c语言:转移表的实现

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://www.mzph.cn/news/718463.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Foxmail快捷键设置问题

当快捷键设置错误时不会生效&#xff0c;原来的快捷键仍有效&#xff0c;即使禁用快捷键功能&#xff0c;原先快捷键仍有效。正确的快捷键&#xff1a; 1. 不能是空&#xff08;NULL&#xff09; 2. 应该设置按键值只有一个的键盘按钮。

力扣字符串篇

以下解题思路来自代码随想录以及官方题解。 文章目录 344.反转字符串541.反转字符串||151.反转字符串中的单词28.找出字符串中第一个匹配项的下标459.重复的字符串 344.反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给…

怎样查询到pycharm终端中执行过的命令?

pycharm终端中记录了曾经运行过的命令&#xff0c;怎样才能查询到全部曾经运行过的命令呢&#xff1f; 怎样查询到pycharm终端中执行过的命令&#xff1f;

【动态规划专栏】

动态规划基础知识 概念 动态规划&#xff08;Dynamic Programming&#xff0c;DP&#xff09;&#xff1a;用来解决最优化问题的算法思想。 动态规划是分治思想的延伸&#xff0c;通俗一点来说就是大事化小&#xff0c;小事化无的艺术。 一般来说&#xff0c;…

【CSS】初学轻松学会使用Flex布局

目录 什么是Flex布局如何开始使用Flex布局Flex容器的属性Flex项目的属性举个例子 什么是Flex布局 Flex布局是一种基于盒子模型的布局方式&#xff0c;它让我们可以轻松地控制容器内的元素在主轴和交叉轴上的排列方式。通过设置不同的Flex属性&#xff0c;我们可以实现各种不同…

探索Hadoop的三种运行模式:单机模式、伪分布式模式和完全分布式模式

目录 前言一、 单机模式二、 伪分布式模式三、 完全分布式模式&#xff08;重点&#xff09;3.1 准备工作3.2 配置集群3.2.1 配置core-site.xml 文件3.2.2 配置hdfs-site.xml 文件3.2.3 配置yarn-site.xml 文件3.2.4 配置mapred-site.xml 文件 3.3 启动集群3.3.1 配置workers3.…

【百度】商业AIGC组_AIGC Java研发工程师(J70353)

北京市技术4人2024-02-28 工作职责&#xff1a; 负责商业AIGC平台方向的工程架构设计及研发&#xff0c;致力于为广告业务提供内容生成、内容知识化、内容多模态等中台化服务&#xff0c;并将内容能力打通广告检索系统&#xff0c;于广告的触发、创意、模型和机制等联动&#…

RK3568 android11 调试陀螺仪模块 MPU6500

一&#xff0c;MPU6500功能介绍 1.简介 MPU6500是一款由TDK生产的运动/惯性传感器&#xff0c;属于惯性测量设备&#xff08;IMU&#xff09;的一种。MPU6500集成了3轴加速度计、3轴陀螺仪和一个板载数字运动处理器&#xff08;DMP&#xff09;&#xff0c;能够提供6轴的运动…

Matlab|基于Logistic函数负荷需求响应

目录 1 基于Logistic函数的负荷转移率模型 2 程序示例 3 效果图 4 下载链接 负荷需求响应模型种类较多&#xff0c;有电价型和激励型等类型&#xff0c;本次和大家分享一个基于Logistic函数的负荷转移率模型&#xff0c;该模型属于电价型&#xff0c;由于该方法使用的较少&a…

mysql 性能调优参数配置文件

########################################################################### ## my.cnf for MySQL 8.0.x # ## 本配置参考 https://imysql.com/my-cnf-wizard.html # ## 注意&#xff1a; …

python爬虫之app爬取-charles的使用

专栏系列:http://t.csdnimg.cn/WfCSx 前言 前面介绍的都是爬取 Web 网页的内容。随着移动互联网的发展,越来越多的企业并没有提供 Web 网页端的服务,而是直接开发了 App,更多更全的信息都是通过 App 来展示的。那么针对 App 我们可以爬取吗?当然可以。 App 的爬取相比 …

FM AM WM DAB是啥

技术描述频率范围优点缺点调频调制&#xff08;FM&#xff09;在FM广播中&#xff0c;音频信号的频率被调制以匹配载波信号的变化&#xff0c;而载波信号的振幅保持不变。FM广播通常具有较高的音质&#xff0c;并且在一定范围内提供清晰的音频。88 MHz 至 108 MHz- 高音质 - 清…

[linux] matplotlib plt画training dynamics指标曲线时,标记每个点的值

plt画折线图时&#xff0c;plt.annotate标记折线图的点的数值。 def plot_ret(*ret_dicts):plt.figure(figsize(10, 5))for ret_dict in ret_dicts:print(ret_dict["iters"])plt.plot([iter*4/1000 for iter in ret_dict["iters"]], ret_dict["ret&q…

亿道信息发布两款升级款全加固笔记本电脑

2022年5月19日&#xff0c;加固手持终端。加固平板电脑、加固笔记本电脑专业设计商和制造商&#xff0c;以及加固型移动计算机软硬件整体定制解决方案提供商亿道信息&#xff0c;宣布对其两款广受欢迎的加固笔记本电脑产品EM-X14U和EM-X15U进行重大升级。新发布的两款升级款全加…

下载element-ui 资源,图标 element-icons.woff,element-icons.ttf 无法解码文件字体

css下载地址&#xff1a;https://unpkg.com/element-ui2.15.14/lib/theme-chalk/index.css js下载地址&#xff1a;https://unpkg.com/element-ui2.15.14/lib/index.js 图标及文字文件下载地址&#xff1a; element-icons.woff:&#xff1a; ​ https://unpkg.com/element-…

《TCP/IP详解 卷一》第10章 UDP 和 IP 分片

目录 10.1 引言 10.2 UDP 头部 10.3 UDP校验和 10.4 例子 10.5 UDP 和 IPv6 10.6 UDP-Lite 10.7 IP分片 10.7.1 例子&#xff1a;IPV4 UDP分片 10.7.2 重组超时 10.8 采用UDP的路径MTU发现 10.9 IP分片和ARP/ND之间的交互 10.10 最大UDP数据报长度 10.11 UDP服务器…

【java、微服务、nacos】nacos学习笔记

Nacos服务分级存储模型 ① 一级是服务&#xff0c;例如userservice ②二级是集群&#xff0c;例如杭州或上海 ③ 三级是实例&#xff0c;例如杭州机房的某台部署了userservice的服务器 配置实例集群属性 改变服务的yml文件 spring:cloud:nacos:discovery:cluster-name: H…

Docker将本地的镜像上传到私有仓库

使用register镜像创建私有仓库 [rootopenEuler-node1 ~]# docker run --restartalways -d -p 5000:5000 -v /opt/data/regostry:/var/lib/registry registry:2[rootopenEuler-node1 ~]# docker images REPOSITORY TAG IMAGE…

Day 60 | 动态规划 647. 回文子串 、 516.最长回文子序列 、动态规划总结篇

647. 回文子串 题目 文章讲解 视频讲解 class Solution {public int countSubstrings(String s) {char[] chars s.toCharArray();int len chars.length;boolean[][] dp new boolean[len][len];int result 0;for (int i len - 1; i > 0; i--) {for (int j i; j < l…

基于React低代码平台开发:构建高效、灵活的应用新范式

文章目录 一、React与低代码平台的结合优势二、基于React的低代码平台开发挑战三、基于React的低代码平台开发实践四、未来展望《低代码平台开发实践&#xff1a;基于React》编辑推荐内容简介作者简介目录前言为什么要写这本书 读者对象如何阅读本书 随着数字化转型的深入&…