用過`C++/Java/python/matlab/JS`等語言后,發現都能很輕松的使用string類型,而C只能這樣:
char str[] = "hello world"; or const char* str = "hello world";
如果只是一個string的類型的話,可以簡單的自定義一個:
typedef const char* string;
但這樣的寫法並不便利,且這種用法不能修改變量中的數據,於是想寫一個類似C++中的string類,但寫了一會兒,發現用C實現有點難...
代碼:
#ifndef STRING_H_INCLUDED
#define STRING_H_INCLUDED
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef const char* const_string;
typedef char* not_const_string;
typedef struct {
const_string str;
unsigned int size(){return (unsigned int)strlen(str);};
void show(){printf("%s\n", str);};
not_const_string sort() {
not_const_string not_con_str = (not_const_string)malloc(strlen(str));
strcpy(not_con_str, str);
for(int i = 1; not_con_str[i] != '\0'; i++) {
char s = not_con_str[i];
int j = i - 1;
while(not_con_str[j] != NULL && not_con_str[j] > s) {
not_con_str[j + 1] = not_con_str[j];
j--;
}
not_con_str[j + 1] = s;
}
return not_con_str;
}
}string;
#endif // STRING_H_INCLUDED
test:
// 測試頭文件 String.h
#include "String.h"
int main()
{
string str = {"baced"}; // 必須加{}
str.show();
printf("%d\n",str.size());
printf("%s\n", str.sort());
return 0;
}
運行結果:
baced 5 abcde
正常來說,用老版的編譯器,比如用VC6.0,或用gcc編譯會出現語法錯誤。我在codeblocks中雖然運行成功了,但這樣寫法是不能稱為C語言的,不過是IDE用C++兼容了這樣的寫法,所以才這樣寫。
我看了一些資料后嘗試用回調函數來實現,即在結構體中保存函數指針。
結果效果並不是很好,語法很麻煩:
#ifndef STRING_H_INCLUDED
#define STRING_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef const char* const_string;
typedef char* not_const_string;
typedef struct string string;
struct string {
const_string str;
void (*init) (string* );
void (*show) (string* );
unsigned int (*size) (string* );
not_const_string (*sort) (const_string );
};
/* 定義函數 */
void init(string*self);
unsigned int size(string*self);
void show(string*self);
not_const_string sort(const_string str);
void init(string*self) {
self->init = init;
self->show = show;
self->size = size;
self->sort = sort;
}
unsigned int size(string*self) {
return (unsigned int)strlen(self->str);
}
void show(string*self) {
printf("%s\n", self->str);
}
not_const_string sort(const_string str) {
not_const_string not_con_str = (not_const_string)malloc(strlen(str));
strcpy(not_con_str, str);
for(int i = 1; not_con_str[i] != '\0'; i++) {
char s = not_con_str[i];
int j = i - 1;
while(not_con_str[j] != NULL && not_con_str[j] > s) {
not_con_str[j + 1] = not_con_str[j];
j--;
}
not_con_str[j + 1] = s;
}
return not_con_str;
}
#endif // STRING_H_INCLUDED
測試:
#include "String.h"
int main()
{
string str = {"baced"}; // 必須加{} --這里是C++中的結構體初始化寫法 C語言好像不能這樣寫 但無妨 可以const_string str2 = "baced";然后再傳給init函數
init(&str);
str.show(&str);
printf("%d\n",str.size(&str));
printf("%s\n", str.sort(str.str));
return 0;
}
運行結果:
baced 5 abcde
可以看到用着挺麻煩的...不如其他語言的簡單和直觀,經常拿來用的話是不太可能的。
# 2018-02-05
實際上,回調函數在許多語言中都可看見(比如python/java/C++等),C語言的一些工程源碼中也隨處可見,比如windows API 中的WNDCLASS結構體的lpfnWndProc成員就是一個函數指針,還有CreateThread 創建線程函數的第三個參數也是函數指針(創建線程的幾個函數中的參數都有函數指針)。
CreateThread函數的函數指針的定義是這樣的:
typedef (DWORD)(*PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
其中DWORD是函數類型,其定義為:
typedef unsigned long DWORD;
*PTHREAD_START_ROUTINE 即是函數指針,LPVOID lpThreadParameter 則是傳參。
在processthreadsapi.h中可看見其函數原型:
WINBASEAPI HANDLE WINAPI CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
參考資料:
https://stackoverflow.com/questions/17052443/c-function-inside-struct http://bbs.csdn.net/topics/390124447 https://www.zhihu.com/question/31519846?sort=created
