习题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()语句的格式。

■循环内出错,如何跳出循环,并且与最终输出不产生冲突的处理

o3提醒点赞小助手大家好,我是本频道的“提醒点赞小助手希望此刻看到消息的人可以给我点赞互相点赞,有赞必回,今天回不了明天回一小时后的我继续提醒大家点赞和我一起成为每天点满赞的人吧!_点赞_提醒_助手_必回_满赞表情给你点赞!_点赞表情

 

 

 

 

 

 



这篇关于习题6-7 简单计算器 (超详细!结构化程序设计步骤分析)(20 分)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程