随便写一个函数声明:int func(int a, int b);

  该函数是一个返回值为int类型,具有两个int类型变量的函数。如果要定义一个这样的函数指针应该怎么定义呢,一般有下列两种方法:

1. 直接定义

  int (* p_func)(int a, int b); 

   实际上一个函数指针不关心它的输入变量名,只关心输入变量类型,因此输入变量名可以省略掉,如下:

  int (* p_func)(int, int);  

  这样就定义了一个函数指针,去掉变量名和最后的分号就是变量类型,因此p_func这个函数指针的变量类型为int (*)(int, int)

2. 用typedef定义

  可以用typedef定义一个函数指针类型,方法如下:

  typedef int (* func_t)(int, int);  

  这样就可以用func_t去定义该类型的函数指针了,如:func_t p_func;

3. 测试例程

  

 1 #include <stdio.h>
 2 
 3 int add(int a, int b)
 4 {
 5     return a + b;
 6 }
 7 
 8 int sub(int a, int b)
 9 {
10     return a - b;
11 }
12 
13 int(*func(int a)) (int, int)
14 {
15     if (a == 1) {
16         return add;
17     }
18     
19     return sub;
20 }
21 
22 /* 定义函数指针类型 */
23 typedef int (* func_t)(int, int);  
24 
25 int main(int argc, const char *argv[])
26 {
27     int k;
28     func_t p1;
29     int (*p2)(int, int);
30     
31     p1 = func(1);
32     p2 = func(2);
33     k = p1(1, 3);
34     printf("k = %d\n", k);
35     
36     k = p2(1, 3);
37     printf("k = %d\n", k);
38     
39     return 0;
40 }

测试结果:

 

 代码分析:

  代码定义了两个函数,add和sub,add用来计算加法,sub用来计算减法,add和sub函数的类型是一样的。该函数类型为int (*)(int, int),因此可以用int (*p1)(int, int)这种写法定义p1,或者先用typedef int (* func_t)(int, int);定义函数类型,然后就可以用func_t去定义函数指针了。

4、总结

  如果说一个函数的返回值是一个函数指针类型那应该怎么写,可以分为两步,第一步先写出函数的返回值类型:

  int (*)(int, int)

  第2步写一个其他返回值类型的函数,如:

  int func(int a)

  那么接下来就应该将int替换成函数指针类型,乍一看应该写成这样:(int (*)(int, int))func(int a),实际正确写法应该是这样:

  int (*func(int a))(int, int)

  是将func(int a)直接加到函数指针类型的星号后面。

  我之所以想写这篇博客是因为我看到一个函数的声明很奇怪: void (*signal(int sig, void (*func)(int)))(int);

  一眼看上去非常难理解,我们一点点的来拆分,首先将与星号的括号同级别的部分拿出来,变成了两部分:

  void (*)(int)

  signal(int sig, void (*func)(int))

  那void (*)(int)就是返回的函数指针类型,signal就是函数名,它有两个参数,1个整形变量和1个函数指针。