=========================================================================

相关代码gitee自取:C语言学习日记: 加油努力 (gitee.com)

=========================================================================

接上期

学C的第二十五天【指针的进阶(一)】_高高的胖子的博客-CSDN博客

=========================================================================

6 .函数指针数组

(1). 含义:

函数指针数组 一个数组,是用于存放 函数指针数组

例如:

(2). 实例 — 计算器(转移表的使用):

计算器加法减法乘法除法 各自定义为一个函数

因为返回int类型数据参数都是 两个整数

所以可以使用 函数指针数组 存储并调用这四个函数

(2.1). 未使用函数指针数组的效果:

自定义函数部分:

主函数部分:

对应代码:

//计算器:#include //加法: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 menu(){printf("***************************\n");printf("*****1.add 2.sub*****\n");printf("*****3.mul 4.div*****\n");printf("******* 0.exit ********\n");printf("***************************\n");}int main(){int input = 0; //菜单选择的数int x = 0; //计算的第一个数int y = 0; //计算的第二个数int ret = 0; //接收函数返回值do{menu();//从键盘输入:printf("请选择:>");scanf("%d", &input);//根据输入的数进行相应操作:switch (input){ case 1://输入加法函数的两个参数:printf("请输入两个操作数:");scanf("%d %d", &x, &y);//调用加法函数:ret = Add(x, y);printf("计算结果为:%d\n", ret);break;case 2://输入减法函数的两个参数:printf("请输入两个操作数:");scanf("%d %d", &x, &y);//调用减法函数:ret = Sub(x, y);printf("计算结果为:%d\n", ret);break;case 3://输入乘法函数的两个参数:printf("请输入两个操作数:");scanf("%d %d", &x, &y);//调用乘法函数:ret = Mul(x, y);printf("计算结果为:%d\n", ret);break;case 4://输入除法函数的两个参数:printf("请输入两个操作数:");scanf("%d %d", &x, &y);//调用除法函数:ret = Div(x, y);printf("计算结果为:%d\n", ret);break;case 0:printf("退出计算器\n");break;default:printf("选择错误,重新选择\n");break;}} while (input);//如果input为0则退出停止循环return 0;}

(2.2). 使用函数指针数组的效果 — 转移表

转移表:通过函数指针数组的下标找到函数地址调用函数实现“跳转”的效果

自定义函数部分:

主函数部分:

减少代码冗余,之后添加算法只需要将添加添加函数加入 函数指针数组 再调整些参数即可

对应代码:

//计算器:#include //加法: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 menu(){printf("***************************\n");printf("*****1.add 2.sub*****\n");printf("*****3.mul 4.div*****\n");printf("******* 0.exit ********\n");printf("***************************\n");}int main(){int input = 0; //菜单选择的数int x = 0; //计算的第一个数int y = 0; //计算的第二个数int ret = 0; //接收函数返回值//使用函数指针数组:int (*pfArr[5])(int, int) = {NULL, Add, Sub, Mul, Div};//“挤一位” 下标: 0 1234do{menu();//从键盘输入:printf("请选择:>");scanf("%d", &input);if (input >= 1 && input <= 4)//输入有效,调用函数进行计算{//输入函数的两个参数:printf("请输入两个操作数:");scanf("%d %d", &x, &y);//通过 函数指针数组 来调用函数:ret = pfArr[input](x, y);// pfArr[数组下标](函数参数1,函数参数2)//打印计算结果:printf("计算结果为:%d\n", ret);}else if(input == 0) //退出{printf("退出计算器\n");}else //输入错误{printf("选择错误,重新选择\n");}} while (input);//如果input为0则退出停止循环return 0;}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

7 . 指向函数指针数组的指针(了解)

(1). 含义:

本质上还是一个数组指针,只不过这里的数组函数指针数组

例如:

int (*pf) (int, int); — 函数指针

int (*pfArr [4]) (int, int); — 函数指针数组

int (* (*p) [4]) (int, int) =&pfArr; — 函数指针数组的指针

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

8 . 回调函数

(1). 含义:

回调函数就是一个通过函数指针调用的函数

如果你把函数的指针(地址)作为参数传递给另一个函数

当这个指针被用来调用其所指向的函数时,我们就说这是回调函数

回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时另外的一方调用,用于对该事件或条件进行响应

(2). 实例 — 计算器(回调函数的使用):

编写计算器函数Calc()包含之前写的加减乘除四个函数

假如Calc() 函数通过函数指针调用了加法函数,这时加法函数就是 回调函数 了。

使用回调函数的效果:

自定义函数部分:

主函数部分:

对应代码:

//计算器:#include //加法: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 menu(){printf("***************************\n");printf("*****1.add 2.sub*****\n");printf("*****3.mul 4.div*****\n");printf("******* 0.exit ********\n");printf("***************************\n");}void Calc(int (*pf)(int x, int y)) //使用函数指针作为形参{//在该函数中调用相应函数继续计算int x = 0;int y = 0;int ret = 0;printf("请输入两个操作数:");scanf("%d %d", &x, &y);//通过形参的函数指针来调用函数 -- Calc()函数就是回调函数ret = pf(x, y);printf("ret = %d\n", ret);}int main(){int input = 0; //菜单选择的数int x = 0; //计算的第一个数int y = 0; //计算的第二个数int ret = 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);//如果input为0则退出停止循环return 0;}