Hello,宝子们!今天我们来模拟实现一下我们生活中的应用最频繁的工具:计算器,实现计算器有三种方式。
废话不多说,直接上代码,计算器的一般实现:
#include <stdio.h>int add(int a, int b)//加法函数{return a + b;}int sub(int a, int b)//减法函数{return a - b;}int mul(int a, int b)//乘法函数{return a * b;}int div(int a, int b)//除法函数{return a / b;}int main(){int x, y;int input = 1;int ret = 0;do{ //首先一上来就打印菜单,下面进行选择,所以要用到do while 循环结构printf("*************************\n");printf(" 1:Add 2:Sub \n");printf(" 3:Mul 4:Div \n");printf(" 0:Exit \n");printf("*************************\n");printf("请选择:");scanf("%d", &input);switch (input){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;default:printf("选择错误\n");break;}} while (input);return 0;}
像这样的代码看完之后有什么问题?虽然也不影响最后计算的结果,但是这样的代码是不是太冗余了,case
里面重复的代码太多了,这还只有加减乘除四个选项,要是再多扩张几个选项呢,比如:&&
,||
,>>
,<<
等运算呢?所以这样的代码效率太低下,不推荐使用。
那有没有比较高效,不这么冗余的方法呢?当然了,这里就要用到我们前面所讲的函数指针数组了,如果还不知道函数指针数组是什么的话,可以看看我前面讲的这篇文章https://blog.csdn.net/weixin_66058866/article/details/136136008
相信聪明的你看完这篇文章,心里应该已经有答案了吧?
函数指针数组代码实现如下:
#include <stdio.h>int add(int a, int b){return a + b;}int sub(int a, int b){return a - b;}int mul(int a, int b){return a*b;}int div(int a, int b){return a / b;}int main(){int x, y;int input = 1;int ret = 0;int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //为了跟菜单里的选项对应起来,需要在数组元素中的最前面加了一个元素,//这样就不至于出现当我们输入下标为1的元素时,访问的是sub这类问题了。do{printf("*************************\n");printf(" 1:Add 2:Sub \n");printf(" 3:Mul 4:Div \n");printf(" 0:Exit \n");printf("*************************\n");printf( "请选择:" );scanf("%d", &input);if ((input <= 4 && input >= 1))//判断输入的值是否在选项当中{printf( "输⼊操作数:" );scanf( "%d %d", &x, &y);ret = (*p[input])(x, y);printf( "ret = %d\n", ret);}else if(input == 0){printf("退出计算器\n");}else{printf( "输⼊有误\n" );}}while (input);return 0;}
上面我们创建了函数指针数组,并且把加减乘除函数的地址都存放进去,然后想实现什么运算,直接通过下标的方式去调用对应的函数,这种方式就很好的解决了代码冗余的问题,而且如果你还想再扩张选项的时候,也不需要再像第一种方法那样麻烦了。
根据input
下标,找到对应的函数,然后再调用对应的函数,这种方法有没有发现它像一个跳板一样,在做一个转移的动作,所以这种方法也被称为转移表。
那么是否还有其他的方式呢?这时候我们就涉及到一种高级的玩法了。
首先来看代码:
#include <stdio.h>int add(int a, int b)//加法函数{return a + b;}int sub(int a, int b)//减法函数{return a - b;}int mul(int a, int b)//乘法函数{return a * b;}int div(int a, int b)//除法函数{return a / b;}void calc(int(*fp)(int x,int y))//使用函数指针来接收函数的地址{int x=0;int y=0;int ret=0;printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = fp(x, y);printf("ret = %d\n", ret);}int main(){int x, y;int input = 1;int ret = 0;do{ //首先一上来就打印菜单,下面进行选择,所以要用到do while 循环结构printf("*************************\n");printf(" 1:Add 2:Sub \n");printf(" 3:Mul 4:Div \n");printf(" 0:Exit \n");printf("*************************\n");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);return 0;}
像这种实现方式,你会发现并没有在主函数里直接调用Add
,Sub
,Mul
,Div
等函数,而是把这些函数的地址传给了clac函数,然后再calc函数内部通过指针变量来调用calc指向的函数,这也是一种回调函数的机制,当然这种机制现在理解不了也没关系,在之后的深入理解指针(4)里面我会详细讲到哟!
创作不易,看完别忘了给博主一键三连哟!谢谢大家呀?