大家都知道指针就是东西的地址.变量有指针,函数也有.而且很巧妙.
看一个简单例子.
#include <stdio.h> int testfunc(int a) { printf("My a = %d", a); } int main() { int (*myfunc)(int) = testfunc; myfunc(5); return 0; } ~
结果就是执行了testfunc,并且传入了5.好像这挺无聊的,看不出什么优势.如果是多个一组函数呢.
#include <stdio.h> int test1(int a) { printf("My a = %d ", a); } int test2(int b) { printf("My b = %d ", b); } int main() { int (*myfunc[2])(int) = {test1, test2}; (myfunc[0])(5); (myfunc[1])(5); return 0; }
我相信你已经看得出声明格式了.
#include <stdio.h> int test1(int a, int b) { printf("My a = %d ", a + b); } int test2(int c, int d) { printf("My b = %d ", c * d); } int main() { int (*myfunc[2])(int, int) = {test1, test2}; (myfunc[0])(5, 4); (myfunc[1])(5, 4); return 0; }
来个复杂的,这个应该知道结果了吧.
My a = 9
My b = 20
好的,那么继续.不知道具体类型怎么办.那就void.void兼容性是一流的.但是,void一定要指针方式传入,否则是incomplete type,另外void是万能类型,需要转化.
#include <stdio.h> int test1(void *a, void *b) { printf("My a = %d ", *(int *)a + * (int *)b); } int test2(void *c, void *d) { printf("My b = %d ", *(int *)c * *(int *)d); } int main() { int val1 = 5; int val2 = 10; int (*myfunc[2])(void *, void *) = {test1, test2}; (myfunc[0])(&val1, &val2); (myfunc[1])(&val1, &val2); return 0; }
我们用int *转换了void类型,使得变量成为int *,然后用*取出真内容,因为我们用&传进去了一个地址.所以要*取出.
如果要加修饰符,怎么办呢.直接加就是了.
#include <stdio.h> int test1(const void *a, const void *b) { printf("My a = %d ", *(int *)a + * (int *)b); } int test2(const void *c, const void *d) { printf("My b = %d ", *(int *)c * *(int *)d); } int main() { int val1 = 5; int val2 = 10; int (*myfunc[2])(const void *, const void *) = {test1, test2}; (myfunc[0])(&val1, &val2); (myfunc[1])(&val1, &val2); return 0; }
既然void是万能的,那么字符串呢?先复习下基本main函数的样子.
#include <stdio.h> int main(int argc,char *argv[]){ }
其中argv是字符串的数组,而数组又是指针,也就是char b[] ≈ char *b(区别只差在是否申请了空间,都是字符串),那么实际上可以写char **argv,就是字符串数组的指针了.(当然,很拗口的读法是字符串指针[数组越≈指针]的指针).如果一个不小心,就会发生Segmentation fault.我到群里随便问了下,有人答案是这样的.
int test1(const void *a, const void *b) { if(strcmp((*(char **)a, *(char **)b)) { printf("a bigger than b "); } else { printf("b bigger than a "); } }
想得太复杂不说,实际上很简单啊.
int test1(const void *a, const void *b) { if(strcmp((char *)a, (char *)b)) { printf("a bigger than b "); } else { printf("b bigger than a "); } }
因为strcmp已经是传入const char *了,所以...
但是,我们现在依然一个一个调用,好像没有体验出优势啊.实际上,函数也可以作为参数,传递进别的函数里面.
函数指针我习惯上用来做动态的驱动加载。我觉得这样,我就可以同时准备多个驱动,然后动态切换了。从整个程序上看,就变成修改硬件的时候,我只需要更改下驱动函数的指针的值。