序言:在学习了C语言函数调用、函数指针数组、回调函数后,我们可以用三种方法实现简易计算器的功能。
#include 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; } int main() { int input = 0; int x, y; int z = 0; do { menu(); printf("请选择:"); scanf("%d", &input); switch (input) { case 1: printf("请输入两个操作数:"); scanf("%d %d", &x, &y); z = Add(x, y); printf("%d\n",z); break; case 2: printf("请输入两个操作数:"); scanf("%d %d", &x, &y); z = Sub(x, y); printf("%d\n", z); break; case 3: printf("请输入两个操作数:"); scanf("%d %d", &x, &y); z = Mul(x, y); printf("%d\n", z); break; case 4: printf("请输入两个操作数:"); scanf("%d %d", &x, &y); z = Div(x, y); printf("%d\n", z); break; case 0: printf("推出计算器\n"); break; default: printf("选择错误,请重新选择\n"); break; } } while (input); return 0; }
上面的代码完成了两个整数的加减乘除四个基本的运算,若我们想增加其他运算功能(>>、<<、&、|、^、&&、|| 等等),我们只需修改菜单、增加函数运算,以及补充case语句即可完成。
随着运算功能的增加,case语句会越来越长,写起来也会很麻烦,于是我们可以用转移表的方式来简化代码。
其本质就是创建一个函数指针数组,把以上函数地址存储起来。为了让数组下标与菜单相匹配,我们需要在数组中添加一个0。
int (*pfarr[5])(int, int) = { 0, Add,Sub,Mul,Div };
这样就可以通过访问数组中函数的地址来实现函数的调用。
z = pfarr[input](x, y);
#include 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; } int main() { int input = 0; int x, y; int z = 0; //创建一个函数指针的数组 ------- 转移表 int (*pfarr[5])(int, int) = { 0, Add,Sub,Mul,Div }; do { menu(); printf("请选择:"); scanf("%d", &input); if (input >= 1 && input <= 4) { printf("请输入两个操作数:"); scanf("%d %d", &x, &y); z = pfarr[input](x, y); printf("%d\n", z); } else if (input == 0) { printf("退出计算器"); } else { printf("输入正确的操作数\n"); } } while (input); return 0; }
同样,若想添加两个整数的运算功能,只需添加函数和函数指针的数组、修改菜单就行。
我们观察第一种方式,会发现case语句中有太多类似的代码,造成代码冗余。所以现在的问题就在于:想把重复的代码实现成函数,同时这个函数又能完成不同的任务。
在case语句中的代码,只有调用函数的逻辑是有差异的,我们可以把调用的函数的地址以参数的形式传递过去,使用函数指针接收,函数指针指向什么函数就调用什么函数,这其实就是回调函数的功能。
void cal(int(*pf)(int, int)) { int x, y; int z = 0; printf("请输入两个操作数:"); scanf("%d %d", &x, &y); z = pf(x, y); printf("%d\n", z); }
#include void menu() { printf("******************************\n"); printf("******* 1.add 2.sub *******\n"); printf("******* 3.mul 4.div *******\n"); printf("******* 0.exit *******\n"); printf("******************************\n"); } void cal(int(*pf)(int, int)) { int x, y; int z = 0; printf("请输入两个操作数:"); scanf("%d %d", &x, &y); z = pf(x, y); printf("%d\n", z); } 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 input = 0; do { menu(); printf("请选择:"); scanf("%d", &input); switch (input) { case 1: cal(Add); break; case 2: cal(Sub); break; case 3: cal(Mul); break; case 4: cal(Div); break; case 0: printf("退出计算器\n"); break; default: printf("选择错误,请重新选择\n"); break; } } while (input); return 0; }