C的函数指针的作用,以及其赋值是弱类型的
C语言中函数指针具有重要的作用。模块之间的调用,可以用函数指针数组或者结构体,配合钩子函数,构造一系列的API接口。
函数指针的赋值比较宽容,这也是一个优点。代码如下:
1 #include<stdio.h> 2 #include<string.h> 3 4 int main() 5 { 6 int a,b; 7 void (*pf1)() = NULL; 8 int (*pf2)(void* argIn,void* argOut) = NULL; 9 10 int func(int*a){ 11 *a = 1; 12 return 1; 13 } 14 int func1(int*a,int*b,int*c){ 15 *a = 1; 16 *b = 2; 17 *c = 3; 18 printf("c:0x%x ,c = %d\n",c,*c); 19 return 1; 20 } 21 //情形1 22 pf1 = func; 23 pf1(&a); 24 //情形2 25 pf2 = func; 26 pf2(&a);//错误 27 pf2(&a,&b); 28 //情形3 29 pf2 = func1; 30 pf2(&a,&b); 31 } 32
test.c:26:2: error: too few arguments to function ‘pf2’
pf2(&a);
上述两个赋值,只有17行是错误的,其他都正确运行。
运行结果:
[david@localhost code]$ ./test c:0xd0fa661c ,c = 3 [david@localhost code]$ ./test c:0x27b4936c ,c = 3 [david@localhost code]$ ./test c:0xef6b1e0c ,c = 3
结论:
不同类型的函数指针,可以转换。根据编译器的不同,可能需要强制转换,或者可以直接转换。
可以看出,对于没有参数的函数指针,可以被有任意参数的函数指针赋值,函数也能正确运行,并且不用考虑返回值。
对于有参数的指针,可以被有任意参数的函数指针赋值,但是函数在运行时,声明的参数和传入的参数需要吻合,同样不用考虑返回值。
但是分两种情况,如情形2和情形3:
当实际的函数如func的参数少于函数指针pf2的参数,调用pf2时,多出来的参数会被func忽略;
当实际的函数如func的参数多于函数指针pf2的参数,调用pf2时,根据运行结果看出,编译器会为func构造参数,存在重大隐患,可能导致内存被修改,应该避免。