本篇文章介绍c语言中的函数指针以及函数指针的应用。
函数指针:指向函数的指针。
函数在编译时分配地址。
&函数名 和 函数名代表的意义相同,都表示函数的地址。
int (* pf)(int,int);
int:表示函数指针指向的函数的返回值类型为int
pf:表示函数指针变量名
(int,int):表示函数指针指向的函数的参数类型
pf的类型:int(*)(int,int)
//写法一
int ret1 = (*pf)(2,3); //通过对函数指针进行解引用
//写法二
int ret2 = pf(2,,3); //函数指针调用函数的简写形式
下面两段代码来自《c陷阱与缺陷》
代码一
(* (void(*)()) 0)();
上面这行代码表示一次函数调用
void(*)() 表示函数指针类型
( void(*)() )0 表示将整型值0强制转换为函数指针类型
(* (void(*)()) 0)() 表示调用地址为0的函数
代码二
void(* signal_func(int, void(*)(int)) )(int);
上面代码表示一次函数声明
函数名 signal_func
参数类型int和void(*)(int)
返回值类型 void(*)(int)
将代码进行简写
typedef void(*SIGNALTYPE)(int); //将void(*)(int)函数指针类型重命名为SIGNALTYPE
SIGNALTYPE signal_func(int, SIGNALTYPE);
函数指针数组:存储函数指针的数组
函数指针数组的定义形式:
ret_type(* parr[array_size])(param_type);
ret_type: 函数指针数组中每个元素返回值类型
parr: 函数指针数组名
array_size: 数组长度
param_type: 函数指针数组中每个元素的参数类型
应用场景:
下面通过一个简单实现计算器功能的例子说明函数指针数组的使用。
//加
int add(int x, int y)
{
return (x + y);
}
//减
int sub(int x, int y)
{
return (x - y);
}
//除
int div(int x, int y)
{
assert(y);
return (x / y);
}
//乘
int mul(int x, int y)
{
return (x * y);
}
void menu(void)
{
printf("********************\n");
printf("** 1 加法 2 减法 **\n");
printf("** 3 乘法 4 除法 **\n");
printf("** 0 退出 **\n");
printf("********************\n");
}
int main()
{
int input = 0;
int x = 0;
int y = 0;
int ret = 0;
//函数指针数组
int(*parr[])(int, int) = {NULL, add, sub, mul, div};
int length = sizeof(parr) / sizeof(parr[1]);
do{
menu();
printf("请选择>");
scanf("%d", &input);
if (0 == input)
{
printf("退出程序!\n");
}
else if (input >= 1 && input <= (length - 1))
{
printf("请输入两个操作数>");
scanf("%d %d", &x, &y);
ret = parr[input](x,y);//通过函数指针调用
printf("结果为:%d\n",ret);
}
else
{
printf("输入不正确!\n");
}
} while (input);
return 0;
}
指向函数指针数组的指针,其实就是数组指针。
定义形式:
ret_type(*(*pparr)[array_size])(param_type);
ret_type: 函数指针数组中每个元素返回值类型
pparr: 指向函数指针数组的指针变量名
array_size: 数组长度
param_type: 函数指针数组中每个元素的参数类型
回调函数指通过函数指针调用的函数
当把一个函数的地址作为参数传递给另一个函数,另一个函数通过这个地址调用函数,这个函数就是回调函数。
回调函数不是由函数的实现方直接调用,即不直接通过使用函数名调用,而是在特定事件或条件时由另外的一方通过函数指针调用,用于对该事件或条件进行响应。
修改上面的例子,利用回调函数实现:
//参数为函数指针
void calculator(int(* pfunc)(int,int))
{
int x = 0;
int y = 0;
int ret = 0;
printf("输入两个操作数>");
scanf("%d %d", &x, &y);
ret = pfunc(x, y);
printf("结果为:%d\n", ret);
}
int main()
{
int input = 0;
do {
menu();
printf("请选择>");
scanf("%d", &input);
switch (input)
{
case 0:
printf("退出程序!\n");
break;
case 1:
calculator(add);//将加法函数的地址传递
break;
case 2:
calculator(sub);//将减法函数的地址传递
break;
case 3:
calculator(mul);//将乘法的地址传递
break;
case 4:
calculator(div);//将除法的地址传递
break;
default:
printf("输入不正确!\n");
break;
}
} while (input);
return 0;
}
本篇文章介绍了函数指针的使用、函数指针数组的使用、指向函数指针数组的指针的定义、以及介绍了回调函数的定义以及使用。