指针型函数:函数类型 *函数名(形参定义表)
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);
总结:
没有函数变量,只有函数声明,函数指针和函数定义。
万变不离其宗,函数指针只要搞清楚,返回值问题,函数声明问题,函数指针数组问题,再复杂的问题都是由这几个问题引伸出来的。