6 . 函数指针数组
(1). 含义:
函数指针数组 是一个数组,是用于存放函数指针 的数组。
例如:
(2). 实例 -- 计算器(转移表的使用):
将计算器的 加法、减法、乘法、除法 各自定义为一个函数,
因为都要 返回int类型数据 ,参数都是 两个整数 ,
所以可以使用 函数指针数组 存储并调用这四个函数。
(2.1). 未使用函数指针数组的效果:
自定义函数部分:
主函数部分:
对应代码:
//计算器: #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 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 <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 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 1 2 3 4 do { 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 <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 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; }