在深入理解指针(3)中,我详细讲解了函数指针数组的理论知识,对于函数指针数组的应用,想必大家还比较陌生,没关系!小博在这篇文章中将通过例题带大家深入理解函数指针数组的应用。本文主要通过编写C语言"计算器"代码,带大家理解函数指针数组在转移表和回调函数中的应用。
话不多说,直接上例题,大家可以先自己尝试一下,如果让你用C语言编写一个简易"计算器"(只含加、减、乘、除功能即可),你会怎么做。
1.青铜级别:
cs
#include <stdio.h>
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;
}
int main()
{
int x, y;
int intput = 0;
int ret = 0;
do
{
printf("*****************************\n");
printf("**1:add 2:sub**\n");
printf("**3:mul 4:div**\n");
printf("*****************************\n");
printf("请选择:");
scanf("%d", &intput);
switch (intput)
{
case 1:
printf("输入操作数:");
scanf("%d%d", &x, &y);
ret = add(x, y);
printf("ret=%d\n", ret);
break;
case 2:
printf("输入操作数:");
scanf("%d%d", &x, &y);
ret = sub(x, y);
printf("ret=%d\n", ret);
break;
case 3:
printf("输入操作数:");
scanf("%d%d", &x, &y);
ret = mul(x, y);
printf("ret=%d\n", ret);
break;
case 4:
printf("输入操作数:");
scanf("%d%d", &x, &y);
ret = div(x, y);
printf("ret=%d\n", ret);
break;
case 0:
printf("推出程序\n");
break;
}
} while (intput);
return 0;
}
当我学了函数指针数组之后,再仔细审视该代码,我们会发现被调用的 add()、sub()、mul()、div()这些函数的返回类型和参数类型都一样,因此,我们考虑是否可以将这些函数像存变量一样存入到一个数组中,用到哪个直接调用即可:
2.铂金级别(转移表):
cs
#include <stdio.h>
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;
}
int main()
{
int x, y;
int intput = 0;
int ret = 0;
//函数指针数组
int (*pfArr[5])(int x, int y) = {0,add,sub,mul,div}; //转移表
do
{
printf("*****************************\n");
printf("**1:add 2:sub**\n");
printf("**3:mul 4:div**\n");
printf("*****************************\n");
printf("请选择:");
scanf("%d", &intput);
if (intput >= 1 && intput <= 4)
{
printf("输入操作数:");
scanf("%d%d", &x, &y);
ret = pfArr[intput](x,y);
printf("ret=%d\n", ret);
}
else if (intput == 0)
{
printf("推出计算器\n");
}
else
{
printf("输入有误\n");
}
} while (intput);
return 0;
}
经过使用加星卡,我们一路飞升,该代码将函数指针变量应用的淋漓尽致,其好处当然也不言而论,大大缩短了代码的长度,在后续拓展计算器的功能时,直接加一个数组变量,非常的方便 。所以当我们遇到函数参数和返回类型相同的多个函数时,我们就可以往函数指针数组上面想 。其实说白了,函数指针数组的用途 就叫做:转移表。
3.王者级别(回调函数):
当我学了回调函数之后,再次回过头来审视青铜级别时的我,我发现自己现在强的可怕。才发现青铜时的我是多么的纯真呐🥹🥹!!
1.回调思考
我发现,这些 switch() 下执行的代码如此的神似,我能否将他们给简化掉,直接给出一个函数代替。

于是我就陷入了沉思:
- 把重复代码抽象成函数
- 但是这个函数又能执行不同的任务
2.代码实现:
cs
#include <stdio.h>
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, y;
int ret = 0;
printf("请输入两个操作数:");
scanf("%d%d", &x, &y);
ret = pf(x, y);
printf("%d\n", ret);
}
int main()
{
int intput = 0;
do
{
printf("*****************************\n");
printf("**1:add 2:sub**\n");
printf("**3:mul 4:div**\n");
printf("*****************************\n");
printf("请选择:");
scanf("%d", &intput);
switch (intput)
{
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;
}
} while (intput);
return 0;
}
经过改造,我们通过回调函数将那些比较冗余的代码给简化了。
3.代码理解

4.回调函数定义
回调函数就是通过函数指针调用的函数。
由上面的示例,我们发现可以用多种方法去解决一个问题,当我们的知识学的越多,积累的越多,那些想不到的解决方法自然而然就自动显现出来了。所以,不要着急,想不到没关系,积累下来,不要焦虑,加油!!
这里小博送上自己喜欢的一句话"人世间令我徒叹无奈的事情多如牛毛,使尽吃奶的力气也无法战胜的对手亦不计其数。与之相比,我对败绩早已习以为常"。