指针型函数:函数类型   *函数名(形参定义表)

int   *fun(int x, int y)

函数指针:函数类型  (*函数指针名)(形参表)

int   (*fun) (int x, int y)

函数指针数组:函数类型  (*函数指针名[数组元素个数])(形参表)

int   (*fun [10]) (int x, int y)

上面是定义了一个指针数组,数组元素为函数指针

 

下面有几个问题可以更好的理解

问1:声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,参数是int*

第一步:定义返回值是int,参数是int*的函数指针pf为int (*pf) (int *)

第二步:含有10个元素的数组的指针p为int (*p)[10]

最后:合成为

int *(*p)[10]) (int *)

问2:定义一个函数指针,指向的函数有两个int形参并返回一个函数指针,返回的指针指向一个int形参且返回int的函数

第一步:定义指向的函数有两个int形参并且返回为Type类型的函数指针,为Type (*pf) (int, int)

第二步:返回值为int *,参数为int的函数,为int *f(int)

最后:合成为

int *(*F)(int, int)) (int)

问3:定义一个函数指针,指向的函数的返回值为一个函数指针数组(数组元素为返回值为int,参数为int *的函数指针),参数为int *

第1步:返回值的元素为       int (*s)(int)
第2步:指针数组为              int (*p)[10]
合并为:                              int (* (*p)[10] )(int) 
第3步:指针函数的参数类型为 int (*f)(int)

最后合成:

int (*  (*  (p)(int*)  )[10]  )  (int *);

问4:下面的定义是啥意思

void (*func(void (*p)(void *), void *x)) (void *);

相信读者应该了解了我就不解释了

 

函数指针的一般用法是:

void (* fun)(void);  //定义函数指针
fun = (void (*)(void)) 0x12345678 //将地址强制转换为函数类型地址
(*fun)(); //运行地址上的函数

实例代码:

#include <stdio.h>

void fun1(void *x)
{
printf("%d \n", *((int *)x));
}

void fun2(void *y)
{
printf("%g \n", *((double *)y));
}

void (*func(void (*p)(void *), void *x)) (void *)
{
(*p)(x); //执行P指向的函数,输出2
return fun2; //返回fun2函数地址
}

int main()
{
int x = 2;
double y = 1.25;
void *px = &x;
void *py = &y;
void (*pf) (void *);
pf = func(fun1, px);
(*pf)(py); //执行fun2 ,输出1.25
return 0;
}

运行结果:
2
1.25

关于typedef的函数指针

在实际项目中,一般用typedef来产生新类型,那就和上面的情况有些不同。可能你了解了上面的内容,但是还是不能很好的完成下面的文题。

这里有几个问题:下面的语句是什么意思?如何声明或定义才使它们更易懂?

int (*foo())();
int (*(*foo)())();
int (*foo())[];
int (*foo[])();
(*(void(*)())0)();
void (*signal(int,void(*)(int)))(int);

问题1:int (*foo())();
眨眼一看,你可能以为是一个函数变量,其实它是一个函数声明,等价于:

typedef int (*pf)();
pf foo();

pf foo();这段代码,如果没有上面的提示,可能以为是定义一个变量,但其实是声明。

问题2:int (*(*foo)())();

这个就是定义了一个指针,等价于:

typedef int (*pa)();
int (*(*p)())();

//给指针赋值
pa fun()
{
pa a;
printf("fun\n");
return a;
}
p = fun;
p(); //运行fun

问题3:int (*foo())[];
也是一个函数声明,等价于:

typedef int (*pa)[];
pa foo();

问题4:int (*foo[])();
声明一个数组,等价于:

typedef int (*pf)();
pf foo[];

问题5:(*(void(*)())0)();
这是一个函数调用,等价于:

typedef void (*pf)();
pf pF = 0;
(*pF)();

问题6:void (*signal(int,void(*)(int)))(int);
也是一个函数声明,等价于:

typedef void (*pf)(int);
pf signal(int, pf);

 

注意:

数组元素不能是函数变量,只能是函数指针变量
返回值不能是函数变量,只能是函数指针变量

int ( a[10]) (int);   //错:数组元素不能是函数变量
int (*a[10]) (int);

int ( (*p)[10]) (int);//错:数组元素不能是函数变量
int (*(*p)[10]) (int);

int ( (*p)(int))(int);//错:返回值不能是函数变量
int (*(*p)(int))(int);

总结:

没有函数变量,只有函数声明,函数指针和函数定义。

万变不离其宗,函数指针只要搞清楚,返回值问题,函数声明问题,函数指针数组问题,再复杂的问题都是由这几个问题引伸出来的。