示例一
int main
{
(*(void(*)())0)();
return 0;
}
void(*p)()p是函数指针,而void(*)()是函数指针类型。
(void(*)())0 是把0强制类型转换为无参数,返回类型是void的函数的地址。
(*(void(*)())0 )()最后把0作为一个函数的地址解引用。
此示例本质上是一次函数调用
示例二
void(*signal(int,void(*)()))(int);
signal是函数名,int和void(*)()是它的两个参数。
signal函数的返回类型是void(*)(int)。
其中void(*)()和void(*)(int)都是函数指针类型。
综上,示例二是一个函数声明。声明的signal函数的第一个参数类型是int。signal函数的第二个参数类型是函数指针,该函数指针指向的函数的参数是int返回类型是void。signal函数的返回类型也是一个函数指针,该函数指针指向的函数参数是int返回类型是void。
注意:typedef void(*pf_t)(int)是指把void(*)(int)类型重命名为pf_t
则示例二可以写为 pf_t signal(int,pf_t);
函数指针使用示例
//写一个计算器
//加法、减法、乘法、除法
void menu()
{
printf("*****************************\n");
printf("**** 1. add 2. sub *****\n");
printf("**** 3. mul 4. div *****\n");
printf("**** 0. exit *****\n");
printf("*****************************\n");
}
int Add(int x, int y)
{
return x + y;
}
int Sub(int x, int y)
{
return x - y;
}
int Mul(int x, int y)
{
return x * y;
}
int Div(int x, int y)
{
return x / y;
}
void calc(int (*pf)(int , int))
{
int x = 0;
int y = 0;
int ret = 0;
printf("请输入2个操作数:>");
scanf("%d %d", &x, &y);
ret = pf(x, y);
printf("%d\n", ret);
}
int main()
{
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
calc(Add);
break;
case 2:
calc(Sub);
break;
case 3:
calc(Mul);
break;
case 4:
calc(Div);
break;
case 0:
printf("退出计算器\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
使用 void calc(int(*pf)(int,int))减少了代码的重复。
函数指针数组
另外,存放函数指针的数组就是函数指针数组。
//计算器
int main()
{
int (*pfArr[4])(int,int)= {Add,Sub,Mul,Div};
int i = 0;
for (i = 0;i < 4;i++)
{
int ret = pfArr[i]( 8,4 );
}
return 0;
}
pfArr就是函数指针数组。
另外,指向arr的指针就是函数指针数组指针,如下。
int(*(*ppfArr)[5])(int,int);