习题6-7 简单计算器 (超详细!结构化程序设计步骤分析)(20 分)
2021/4/17 14:25:25
本文主要是介绍习题6-7 简单计算器 (超详细!结构化程序设计步骤分析)(20 分),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
习题6-7 简单计算器 (20 分)
模拟简单运算器的工作。假设计算器只能进行加减乘除运算,运算数和结果都是整数,四种运算符的优先级相同,按从左到右的顺序计算。
输入格式:
输入在一行中给出一个四则运算算式,没有空格,且至少有一个操作数。遇等号”=”说明输入结束。
输出格式:
在一行中输出算式的运算结果,或者如果除法分母为0或有非法运算符,则输出错误信息“ERROR”。
输入样例:
1+2*10-10/2=
输出样例:
10
【题意理解与切分任务】
第一步:输出数据的计算过程分析:1+2*10-10/2=10
①先计算1+2=3 ②计算3*10=30 ③ 计算30-10=20 ④ 计算20/10=2 ⑤遇到等号输出结果
第二步:理清逻辑,编辑算法
问题求解的算法转化过程可能会遇到的几个问题:
问题①如何处理这种既有数字又有运算符整个合在一起的输入数据?
问题②如何实现从左往右的依次计算
分析:
针对问题①:显然我们目前所学知识不足以支撑我们一次性输入整个算式再来求解,所以我们应该分批处理输入的数据。
从而又引申出新的问题:问题③如何循环实现分批输入数据,循环的条件是什么,问题④怎样分批,按照什么切分数据。
针对问题③:由于循环控制次数不确定,但我们知道当输入的字符型数据为 ‘=’ 时即可结束循环,故优先选择while循环来实现该问题。while(字符变量 != '=' ) {..... }
针对问题④:由已知条件,
“输入在一行中给出一个四则运算算式,没有空格,且至少有一个操作数。”,
可以确定最开始的输入格式是 scanf("%d%c",&第一个整型变量,&字符型变量);由输入的字符变量,进而得到循环的判断条件。
进入循环以后,接下来要解决的问题是问题②如何实现从左往右的依次计算
我们在最开始的输入过程中已经输入了一个数字和一个操作符,进入循环以后我们还需要调用scanf("%d",&第二个整型变量),获取第二个操作数,然后才能继续计算。接下来就是根据之前输入的运算符确定计算方法。
针对这种有少数 固定判断条件的 选择分支语句 最好使用 swith() 语句:由于用的少,现在补充如下
详见教材:p57-p60
swith() 语句详情
针对问题②,我们可以利用sum = sum+ i 这种计算原理 把计算的结果保存在第一个整型变量里面。 即 第一个整型变量 运算符= 第二个整型变量;
基本逻辑理清楚了大的框架也基本完成,再就是特殊条件处理和边界控制。
在一行中输出算式的运算结果,或者如果除法分母为0或有非法运算符,则输出错误信息“ERROR”。
该条件比较简单,我们直接开始尝试写代码。
编写初步代码合成:
#include <stdio.h> int main() { int x; //运算符前的数据存储在变量x中 int y; //运算符后面的存在y中 char ch; scanf("%d%c", &x, &ch); while(ch!='='){ //运算符合法,继续输入数据 scanf("%d",&y); //开始输入第二个数据 switch(ch){ case '+': x += y; continue; //本想着执行完这条语句后直接跳过后面的语句继续重新下一轮循环的 case '-': x -= y; continue; case '*': x *= y; continue; case '/': if(y!=0) { x /= y; continue; } else if(y == 0) printf("ERROR");break; default :printf("ERROR");break; } scanf("%c",&ch); //循环条件的变更 }//while printf("%d", x); return 0; }
哎呀!编译报错了。
:因为switch语句是选择语句,只能用break+,continue只能用于循环语句中,虽然这里是嵌套在了循环语句内,但由于作用域的原因,所以出错了
main.c:14:35: Error: 'continue' is only allowed inside loop statements.
case '+': x += y; continue;
错误分析与调试
我们的基本逻辑是想着直接跳出switch(),执行之后的语句,进行下一轮循环。
经过初次编译发现一个主要的语法上的细节。
因为switch语句是选择语句,只能用break,continue只能用于循环语句中(长记性!)
将上述代码中continue 全部替换成break语句 后继续进行调试验证:
$ ./main
1+2*10-10/2= //输入样例 成功输出
10 Program exited with status 0尝试除0
$ ./main
125/0=
ERROR125 Program exited with status 0$ ./main
125&5=
ERROR125 Program exited with status 0//输入样例 发现逻辑上有点小问题,出现错误以后不能中断后续所有信息
解决办法 设置一个出错标记的变量flag = 0,设置初值,出错以后标记位被修改比如 flag = 1;
然后再switch()语句后面先设置标记检查,若标记被修改则跳出循环,最后输出的时候还要判断一次标记位的信息,分类打印,实现最终的分类输出。
完整详细的代码如下:
#include <stdio.h> int main() { int x; //运算符前的数据存储在变量x中 int y; //运算符后面的存在y中 int flag = 0; //出错标记位,出错会修改标记变量的值 char ch;//存储输入字符的变量 scanf("%d%c", &x, &ch); while(ch!='='){ //运算符合法,继续输入数据 scanf("%d",&y); //开始输入第二个数据 switch(ch){ //switch语句实现加减乘除的分类运算 case '+': x += y; break; //break实现跳出switch语句 case '-': x -= y; break; case '*': x *= y; break; case '/': if(y!=0) { //条件判断语句实现分母出错的判断 x /= y; break ; } else{ flag = 1 ; //出错修改标记位flag的值 break ; } default :flag = 1 ; break; //非法字符判断 } if(flag==1) break; //出错判断 标记位被修改跳出 break会while循环 scanf("%c",&ch); //****注意:while循环条件的变更,不然就死循环来了******* }//while if(flag==1) //实现分类输出 printf("ERROR"); else printf("%d", x); //正确输出 return 0; }
最后删除简单做一下简单的 优化和删除简单注释:得到
纯净版的代码:
#include <stdio.h> int main() { int x,y,flag=0; char ch; scanf("%d%c", &x, &ch); while(ch!='='){ //运算符合法,继续输入数据 scanf("%d",&y); switch(ch){ //switch语句实现加减乘除的分类运算 case '+': x += y; break; case '-': x -= y; break; case '*': x *= y; break; case '/': if(y!=0) { x /= y; break ; } else{ flag = 1 ; break ; } default :flag = 1 ; break; } if(flag==1) break; //出错判断 scanf("%c",&ch); //:while循环条件的变更 } if(flag==1) printf("ERROR"); else printf("%d", x); return 0; } 从一开始就养成良好的代码书写规范: 一行只写一句话,空行将任务模块分块,调整好缩进 让自己的代码更加直观易懂,便于调试,更加优美!
学习总结与心得:
■break,和continue 的使用场景和限定条件。
■将一整块输入条件拆解、分类处理的算法思维和实现过程。
■switch()语句的格式。
■循环内出错,如何跳出循环,并且与最终输出不产生冲突的处理
这篇关于习题6-7 简单计算器 (超详细!结构化程序设计步骤分析)(20 分)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-25Java创意资料:新手入门的创意学习指南
- 2024-11-25JAVA对接阿里云智能语音服务资料详解:新手入门指南
- 2024-11-25Java对接阿里云智能语音服务资料详解
- 2024-11-25Java对接阿里云智能语音服务资料详解
- 2024-11-25JAVA副业资料:新手入门及初级提升指南
- 2024-11-25Java副业资料:入门到实践的全面指南
- 2024-11-25Springboot应用的多环境打包项目实战
- 2024-11-25SpringBoot应用的生产发布项目实战入门教程
- 2024-11-25Viite多环境配置项目实战:新手入门教程
- 2024-11-25Vite多环境配置项目实战入门教程