• 软件工程Ⅱ:小学四则运算


    作业要求来源于 https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2186

    我的GitHub远端库 https://github.com/WAN-Y/gggit

    一、题目要求:

    像《构建之法》的人物阿超那样,写一个能自动生成小学四则运算题目的命令行 “软件”。


    具体要求:任何编程语言都可以,命令行程序接受一个数字输入,然后输出相应数目的四则运算题目和答案。例如输入数字是 30, 那就输出 30 道题目和答案。 运算式子必须至少有两个运算符,运算数字是在 100 之内的正整数,答案不能是负数。 如:

    23 - 3 * 4 = 11

    扩展要求:

    1) 要求能出和真分数 (二分之一, 十二分之五,等)相关的练习题。

    2) 并且要求能处理用户的输入,并判断对错,打分统计。 要求能处理用户输入的真分数, 如 1/2, 5/12 等。

    初步拟定要实现的功能后,估计一下自己需要花多长时间。编程过程中记录自己实际用了多长时间。

    然后和同学们比较一下各自程序的功能、实现方法的异同等等。

    写博客纪录自己实现的过程和思路。

     

    二、个人软件过程耗时估计与统计表

    PSP2.1 Personal Software Process Stages Time Senior Student Time
    Planning 计划 0.5 0.5
    · Estimate 估计这个任务需要多少时间 6  7
    Development 开发 6  
    · Analysis 需求分析 (包括学习新技术) 0.5 0.5
    · Design Spec 生成设计文档 0 0.2
    · Design Review 设计复审 0 0.1
    · Coding Standard 代码规范 0.2  
    · Design 具体设计 2 1
    · Coding 具体编码 2 3
    · Code Review 代码复审 0.5 1
    · Test 测试(自我测试,修改代码,提交修改) 0.5 0.5
    Reporting 报告 0 3
    · 测试报告 0  
    · 计算工作量 0  
    · 并提出过程改进计划 0

     

    三、代码提交

    实现过程和思路

    我选择了c语言来编写这次的程序。

    1.先写出获取题目数量的语句,并用for()循环体输出题目序号。(此后每输出一个序号就随机一个等式。)

     

        printf("请输入题目数量:");
        scanf("%d",&num);
        for(i=1;i<=num;i++)
        {
            printf("%d.
    ",i);
        }

     

    2.随机等式的“部件”。为运算数和运算符建立新变量,并获取循环数。

    (运算符是通过随机获得0~3的数字,再用switch()语句分别对应+-×÷得出的。)

     

        srand((int)time(0));
        a=rand()%100;
        b=rand()%100;
        c=rand()%100;
        m=rand()%4;
        n=rand()%4;
      
      switch(m)
        {
        case 0:
                x='+';
                break;
        case 1:
                x='-';
                break;
        case 2:
                x='*';
                break;
        case 3:
                x='/';
                if(b==0)
                    b=rand()%100; //避免除数为零
                break;
            }

    3.计算等式结果

     

             switch(x) //从左到右算起
             {
             case '*':
                 v=a*b;  //v变量存储第一次运算结果
                 break;
             case '/':
                 v=(float)a/b;
                 break;
             case '+':
                 if(y!='*'&&y!='/') //需要先算后面部分时跳过
                 {v=a+b;}
                 break;
             case '-':
                 if(y!='*'&&y!='/') //需要先算后面部分时跳过
                 {v=a-b;}
                 break;
             }
            switch(y) //计算右半部分
            {
            case '+':
                w=v+c; //w存储最终结果
                break;
            case '-':
                w=v-c;
                break;
            case '*':
                if(x=='+') //1.从右往左算回去
                {w=a+(b*c);}
                else if(x=='-')
                {w=a-(b*c);}
                else
                {w=v*c;}//2.顺序计算
                break;
            case '/':
                if(x=='+')//1.从右往左算回去
                {w=a+((float)b/c);}
                else if(x=='-')
                {w=a-((float)b/c);}
                else
                {w=v/c;}//2.顺序计算
            }

     

      4.若计算结果为负,重新执行循环体。

            if(w<0)
            {
                goto loop;
            }

      5.输出等式及结果。

        for(i=1;i<=num;i++)
        {
            printf("%d.
    ",i);
            printf("%d %c %d %c %d = ",formula[i][0],formula[i][1],formula[i][2],formula[i][3],formula[i][4]);
            printf("%.2f
    ",result[i]);
        }

    6.程序运行结果

     

     

    感想和体会

    1.这次写代码的过程依旧犯了些基础错误,像是输出变量的时候加上了&取地址符,switch()里没有写break语句等等。

     

    2.我发现:程序的主要功能写起来所花的时间是比较少的。在此次编码的过程里,耗时最长的居然是避免结果为负数这一附加要求。

    虽然上面的代码里只有简单的一个go to语句,但实际上我思考所消耗的时间和写其他所有代码的时间是差不多的。

    这是因为我的逻辑思考收到了比较大的考验。

    什么时候结果会为负数?只有减法。

    想把第一次和第二次的运算结果分开检验,那么有减号的情况有多少种呢?

    非顺序的运算要怎么照顾到呢?用什么语句比较好?……

    在思考的过程里大脑甚至当机了好一会儿,辛苦写出来的代码还总是运行失败,最后还是改成go to。

     

    事先想好框架并构思好大致逻辑比闷头写要顺畅得多——也是我在此次作业中的一个小感想。

    寻找可能会出bug的地方并尝试检验实在是很耗心力……

    不难想象功能更复杂的软件要遇到多少更头大的问题,我想这就是软件工程之难的一个小缩影吧。

     

  • 相关阅读:
    ExtJS专题(十):layout布局的使用(3)
    ExtJS专题(十一):lTree的Treepanel使用
    ExtJS专题(四):ExtJS组件的属性
    ExtJS专题(七):ExtJS面板Panel中视图区ViewPort的使用
    ExtJS专题(二):ExtJS类库和组件介绍
    ExtJS专题(十):layout布局的使用(1)
    EXtJS专题(九):ExtJS对话框的使用
    ExtJS专题(五):ExtJS面板Panel的使用
    ExtJS专题(三):ExtJS组件的使用
    ExtJS专题(八):ExtJS窗口Window的使用
  • 原文地址:https://www.cnblogs.com/wan-y/p/9789041.html
Copyright © 2020-2023  润新知