用过`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 ", 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] != ' '; 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 ",str.size()); printf("%s ", 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 ", 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] != ' '; 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 ",str.size(&str)); printf("%s ", 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