简易计算器的制作(函数指针数组的实践)

个人主页(找往期文章包括但不限于本期文章中不懂的知识点): 我要学编程(ಥ_ಥ)-CSDN博客

 前期思路(菜单的制作等):利用C语言的分支循环少量的函数知识写一个猜数字的小游戏-CSDN博客

计算器的制作其实与游戏没有很大的区别。

#include <stdio.h>
void Add(int x, int y)//加法
{printf("%d\n", x + y);
}void Sub(int x, int y)//减法
{printf("%d\n", x - y);
}void Mul(int x, int y)//乘法
{printf("%d\n", x * y);
}void Div(int x, int y)//除法
{printf("%d\n", 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;do{menu();printf("请输入您要进行的运算:");scanf("%d", &input);switch (input){case 1:printf("请输入要运算的数:");scanf("%d%d", &x, &y);Add(x,y);break;case 2:printf("请输入要运算的数:");scanf("%d%d", &x, &y);Sub(x, y);break;case 3:printf("请输入要运算的数:");scanf("%d%d", &x, &y);Mul(x, y);break;case 4:printf("请输入要运算的数:");scanf("%d%d", &x, &y);Div(x, y);break;case 0: printf("退出计算器\n");break;default: printf("输入错误,请重新输入:\n");break;}} while (input);return 0;
}

注意上述计算都是整数运算。

上面这个代码虽然能够达到我们想要的目的,但是我们会发现这个比较冗杂,特别是那个switch……case语句。那么我们有没有什么办法,使这个代码看上去简洁一点呢?这个就得用到函数指针数组的知识点(不知道的小伙伴可以去我的主页自取,指针第3篇),通过一个数组存放一些函数的地址,再间接来调用这些函数。

#include <stdio.h>
void Add(int x, int y)
{printf("%d\n", x + y);
}void Sub(int x, int y)
{printf("%d\n", x - y);
}void Mul(int x, int y)
{printf("%d\n", x * y);
}void Div(int x, int y)
{printf("%d\n", 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;void (*p[5])(int, int) = { 0, Add, Sub, Mul, Div };//数组初始化,对应的运算do{menu();printf("请输入您要进行的运算:");scanf("%d", &input);printf("请输入要运算的数:");scanf("%d%d", &x, &y);switch (input){case 1:p[1](x, y);break;case 2:p[2](x, y);break;case 3:p[3](x, y);break;case 4:p[4](x, y);break;case 0: printf("退出计算器\n");break;default: printf("输入错误,请重新输入:\n");break;}} while (input);return 0;
}

这个代码去计算,确实是没问题。但是如果我们输入错误或者是想退出计算器,就显得有点别扭。 

输入错误了或者不想用了,还要我们输入运算数。 

怎么解决呢?其实只要我们限制输入的数就行了。

#include <stdio.h>
void Add(int x, int y)
{printf("%d\n", x + y);
}void Sub(int x, int y)
{printf("%d\n", x - y);
}void Mul(int x, int y)
{printf("%d\n", x * y);
}void Div(int x, int y)
{printf("%d\n", 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;void (*p[5])(int, int) = { 0, Add, Sub, Mul, Div };do{menu();printf("请输入您要进行的运算:");scanf("%d", &input);if ((input >= 1) && (input <= 4))//switch语句在此处用不了{printf("请输入要运算的数:");scanf("%d%d", &x, &y);p[input](x,y);}else if (input == 0){printf("退出计算器\n");}else{printf("输入错误,请重新输入:\n");}} while (input);return 0;
}

如果把if语句写进switch语句中会导致if语句不执行。因为先执行的switch语句,就直接跳到case语句去了,不会理会if语句。 

当然这个也可以用函数调用的方法来写。

#include <stdio.h>
void Add(int x, int y)
{printf("%d\n", x + y);
}void Sub(int x, int y)
{printf("%d\n", x - y);
}void Mul(int x, int y)
{printf("%d\n", x * y);
}void Div(int x, int y)
{printf("%d\n", 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(void(*p)(int, int))
{printf("请输入要运算的数:");int x = 0;int y = 0;scanf("%d%d", &x, &y);p(x, y);}int main()
{int input = 0;int x = 0;int y = 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);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/253590.html

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

相关文章

使用ChatGpt和文心一言辅助文章创作

近期在写数字水浒系列文章&#xff0c;使用了ChatGpt和文心一言进行辅助创作&#xff0c;整体感受不错&#xff0c;提高了工作效率。 在使用过程中&#xff0c;感觉文心的中文能力更强一些&#xff0c;主要体现在&#xff1a; 1 语料库更大&#xff0c;比如对水浒传了解的更多…

Postman(接口测试工具),什么是Postman接口

目录 一.基本介绍 Postman 是什么Postman 快速入门快速入门需求说明 二.Postman 完成 Controller 层测试 需要的代码&#xff1a; Java类request.jspsuccess.jsp1. 完成请求2. 完成请求3. 完成请求4. 完成请求5. 完成请求 三.发送join 目录 一.基本介绍 Postman 是什么 …

微信小程序解决华为手机保存图片到相册失败

1.新增隐私设置 2.优化代码 新增uni.authorize判断 _saveCode() {let that this;console.log(点击了保存图片)console.log(this.result)uni.authorize({scope: scope.writePhotosAlbum,success(e) {console.log(e)if (this.result ! "") {uni.saveImageToPhotosAlb…

一步步建立一个C#项目(连续读取S7-1200PLC数据)

这篇博客作为C#的基础系列,和大家分享如何一步步建立一个C#项目完成对S7-1200PLC数据的连续读取。首先创建一个窗体应用。 1、窗体应用 2、配置存储位置 3、选择框架 拖拽一个Button,可以选择视图菜单---工具箱 4、工具箱 拖拽Lable控件和TextBook控件 5、拖拽控件 接下来…

C# 实现微信自定义分享

目录 需求与调整 代码实现 获取令牌 生成合法票据 获取有效签名 客户端准备 客户端实现 小结 需求与调整 在微信中打开网页应用后&#xff0c;可以选择将地址发送给朋友进行分享&#xff0c;如下图&#xff1a; 在实际的应用中&#xff0c;我们可能不是简单的将该网页…

进程控制(Linux)

进程控制 一、进程创建1. 再识fork2. 写时拷贝 二、进程终止前言——查看进程退出码1. 退出情况正常运行&#xff0c;结果不正确异常退出 2. 退出码strerror和errno系统中设置的错误码信息perror异常信息 3. 退出方法exit和_exit 三、进程等待1. 解决等待的三个问题2. 系统调用…

Unity_ShaderGraph节点问题

Unity_ShaderGraph节点问题 Unity版本&#xff1a;Unity2023.1.19 为什么在Unity2023.1.19的Shader Graph中找不见PBR Master节点&#xff1f; 以下这个PBR Maste从何而来&#xff1f;

项目02《游戏-09-开发》Unity3D

基于 项目02《游戏-08-开发》Unity3D &#xff0c; 本次任务是做抽卡界面&#xff0c;获取的卡片增添在背包中&#xff0c;并在背包中可以删除卡片&#xff0c; 首先在Canvas下创建一个空物体&#xff0c;命名为LotteryPanel&#xff0c;作为抽卡界面&#xff0c; …

Redis的数据类型Hash使用场景实战

Redis的数据类型Hash使用场景 常见面试题&#xff1a;redis在你们项目中是怎么用的&#xff0c;除了String数据类型还使用什么数据类型&#xff1f; 怎么保证缓存和数据一致性等问题… Hash模型使用场景 知识回顾&#xff1a; redisTemplate.opsForHash() 方法是 Redis 的 …

【Nginx】nginx入门

文章目录 一、Web服务器二、Nginx三、Nginx的作用Web服务器正向代理反向代理 四、CentOS上安装Nginx(以CentOS 7.9为例) 一、Web服务器 Web 服务器&#xff0c;一般是指“网站服务器”&#xff0c;是指驻留于互联网上某种类型计算机的程序。Web 服务器可以向 Web 浏览器等客户…

Centos 7.5 安装 NVM 详细步骤

NVM&#xff08;Node Version Manager&#xff09;是一个用于管理Node.js版本的工具&#xff0c;它可以让你轻松地在多个版本之间切换。NVM 通过下载和管理 Node.js 的多个版本&#xff0c;为用户提供了一种灵活的方式来使用不同版本的 Node.js。如果你需要更多关于NVM的信息&a…

C语言操作符详解

操作符的分类 • 算数操作符 &#xff1a; 、 - 、 * 、 / 、 % • 移位操作符 &#xff1a; << 、 >> • 位操作符 &#xff1a; & 、 | 、 ^ • 赋值操作符 &#xff1a; 、 、 - 、 * 、 / 、 % 、 << 、 >> 、 & 、 |…

阅读《极客时间 | Kafka核心技术与实战》(一)【Kafka入门】

阅读《极客时间 | Kafka核心技术与实战》 为什么要学习Kafka消息引擎系统ABC一篇文章带你快速搞定Kafka术语我应该选择哪种Kafka&#xff1f;聊聊Kafka的版本号 为什么要学习Kafka 如果你是一名软件开发工程师的话&#xff0c;掌握 Kafka 的第一步就是要根据你掌握的编程语言去…

移动光猫gs3101超级密码及改桥接模式教程

文章目录 超级管理员账号改桥接模式路由器连接光猫&#xff0c;PPPOE拨号即可&#xff01;附录&#xff1a;如果需要改桥接的话不知道拨号密码咋办打开光猫Telnet功能Telnet 登录 参考文章 移动光猫吉比特GS3101超级账号获取更改桥接 移动光猫gs3101超级密码及改桥接模式教程 …

单片机——FLASH(2)

文章目录 flash &#xff08;stm32f40x 41x的内存映射中区域详解&#xff09;flash写数据时 flash &#xff08;stm32f40x 41x的内存映射中区域详解&#xff09; Main memory 主存储区 放置代码和常数 System memory 系统存储区 方式bootloader代码 OTP区 一次性可编程区 选项…

AR人脸106240点位检测解决方案

美摄科技针对企业需求推出了AR人脸106/240点位检测解决方案&#xff0c;为企业提供高效、精准的人脸识别服务&#xff0c;采用先进的人脸识别算法和机器学习技术&#xff0c;通过高精度、高速度的检测设备&#xff0c;对人脸进行快速、准确地定位和识别。该方案适用于各种应用场…

spring boot和spring cloud项目中配置文件application和bootstrap加载顺序

在前面的文章基础上 https://blog.csdn.net/zlpzlpzyd/article/details/136060312 日志配置 logback-spring.xml <?xml version"1.0" encoding"UTF-8"?> <configuration scan"true" scanPeriod"10000000 seconds" debug…

Flink流式数据倾斜

1. 流式数据倾斜 流式处理的数据倾斜和 Spark 的离线或者微批处理都是某一个 SubTask 数据过多这种数据不均匀导致的&#xff0c;但是因为流式处理的特性其中又有些许不同 2. 如何解决 2.1 窗口有界流倾斜 窗口操作类似Spark的微批处理&#xff0c;直接两阶段聚合的方式来解决…

【开源】SpringBoot框架开发超市账单管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统设计3.1 总体设计3.2 前端设计3.3 后端设计在这里插入图片描述 四、系统展示五、核心代码5.1 查询供应商5.2 查询商品5.3 新增超市账单5.4 编辑超市账单5.5 查询超市账单 六、免责说明 一、摘要 1.1 项目介绍 基于…

Adobe Camera Raw for Mac v16.1.0中文激活版

Adobe Camera Raw for Mac是一款强大的RAW格式图像编辑工具&#xff0c;它能够处理和编辑来自各种数码相机的原始图像。以下是关于Adobe Camera Raw for Mac的一些主要特点和功能&#xff1a; 软件下载&#xff1a;Adobe Camera Raw for Mac v16.1.0中文激活版 RAW格式支持&…