当前位置:首页 » 《随便一记》 » 正文

c语言:转移表的实现

25 人参与  2024年03月05日 19:16  分类 : 《随便一记》  评论

点击全文阅读


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;}

像这种实现方式,你会发现并没有在主函数里直接调用AddSubMulDiv等函数,而是把这些函数的地址传给了clac函数,然后再calc函数内部通过指针变量来调用calc指向的函数,这也是一种回调函数的机制,当然这种机制现在理解不了也没关系,在之后的深入理解指针(4)里面我会详细讲到哟!


创作不易,看完别忘了给博主一键三连哟!谢谢大家呀?


点击全文阅读


本文链接:http://zhangshiyu.com/post/74332.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1