软件工程综合实践专题 第二次作业 四则运算
这次的结对编程是我和府斐妍同学一起完成的,我们先后对程序进行了两次改动,编程内容、过程、问题解决方案、心得体会、思考如下:
一、编程内容
- 小学老师要每周给同学出300道四则运算练习题。
- 这个程序有很多种实现方式:
- c/c++
- c#/VB.net/Java
- Excel
- Unix Shell
- Emacs/Powershell
- Perl
- Python
- 两个运算符,100以内的数字,不需要写答案。
- 需要写答案,并且保证答案在0-100之间
- 这个老师发现你的程序很好用,其他老师都想要一份,有些新的要求:
- 题目避免重复
- 可扩展性
- 可定制(数量/打印方式)
- 具体定制:是否有乘除法,是否有括号,数值范围,条件发有无负数,除法有无余数,是否支持分数,打印中每行的间隔可调整。
二、编程过程
1. 第一次
1.1 前期计划
查找了随机函数的使用方法,两个人确定了两个运算符不包含‘’等号‘’,一人编代码,一人写博客。
1.2 编程思想
使用两个随机函数,一个功能为随机0~100中的数,另一个为随机‘+,-,*,/’中随机一个运算符号,在main函数中使用循环将其打印出来。
1.3 程序代码
#include <iostream>
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
using namespace std;
char yunsuanfu ()
{
char a[]={'+','-','*','/'};
int n=4;
int i;
i=rand()%n;
return a[i];
}
int shuzi()
{
int i;
i=rand()%100+1;
return i;
}
int main()
{
srand(time(NULL));
for(int j=0;j<300;j++)
{
int a,c,e;
char b,d;
a=shuzi();
b=yunsuanfu();
c=shuzi();
d=yunsuanfu();
e=shuzi();
cout<<a<<b<<c<<d<<e<<'='<<endl;
}
return 0;
}
1.4 程序结果
1.5 总结
我们最开始敲出来的代码能够按照要求给出300道题目,数字在100以内,不写出答案。而在此基础上能够进行的优化只有题目的数量,可扩展性较弱,并且没有办法给出算式的答案。
这段代码所给出的式子有一些也会出现逻辑上的错误,比如除数可能为零等。综上我们放弃了四则混合运算,否定了之前不把‘=’看做一个运算符的决定,虽然降低算式的难度,但是可以保证算是没有逻辑错误,并且可以给使用者更多的选择。
2. 第二次
2.1 前期计划:
发现了程序的不足我们决定加减乘除分开进行出题目,计划在第一次编程的基础上加入了定制题目数量及限制答案在0-100之间。
2.2 编程思想:
在加法和乘法打印前加入if判断,如果得出的数大于100则跳转出本次循环。
在程序的一开始定义题目数量的变量number,由用户输入,放入for循环的条件内。
2.3 程序代码
2.3.1 加法函数:
void addtion()
{
int a,b,i,number;
srand ( (unsigned) time (NULL) );
system("cls");
printf("\t请输入题目数!\n\t\t");
scanf("%d",&number);
getchar();
printf("\t程序将会随机出题!\n\t\t");
for(i=0;i<number;i++)
{
a=rand()%100;
b=rand()%100;
if(a+b>=100)
{
i--;
continue;
}
printf("\n\t%d + %d=",a,b);
}
printf("\t请按任意键返回菜单\n");
getch();
}
2.3.2 减法函数
void subtraction()
{
int a,b,i,number;
srand ( (unsigned) time (NULL) );
system("cls");
printf("\t请输入题目数!\n\t\t");
scanf("%d",&number);
getchar();
printf("\t程序将会随机出题!\n\t\t");
for(i=0;i<number;i++)
{
a=rand()%100;
b=rand()%100;
printf("\n\t%d - %d=",a,b);
}
printf("\t请按任意键返回菜单\n");
getch();
}
2.3.3 乘法函数
void multiply()
{
int a,b,i,number;
srand ( (unsigned) time (NULL) );
system("cls");
printf("\t请输入题目数!\n\t\t");
scanf("%d",&number);
getchar();
printf("\t程序将会随机出题!\n\t\t");
for(i=0;i<number;i++)
{
a=rand()%100;
b=rand()%100;
if(a*b>=100)
{
i--;
continue;
}
printf("\n\t%d * %d=",a,b);
}
printf("\t请按任意键返回菜单\n");
getch();
}
2.3.4 除法函数
void division()
{
int a,b,i,number;
srand ( (unsigned) time (NULL) );
system("cls");
printf("\t请输入题目数!\n\t\t");
scanf("%d",&number);
getchar();
printf("\t程序将会随机出题!\n\t\t");
for(i=0;i<number;i++)
{
a=rand()%100;
b=rand()%100;
printf("\n\t%d / %d=",a,b);
}
printf("\t请按任意键返回菜单\n");
getch();
}
2.4 程序结果
2.5 总结
经过一次修改,程序可以按照用户需求定制题目数量并且限制了答案在0-100之间。完成了要求,但随着修改出现越来越多的可以优化的地方,比如判断用户是否答对并给出答案,做减法时减数大于被减数,做除法时是否整除等,于是我们进行了第二次修改。
3. 第三次
3.1 前期计划
找出程序可以优化的地方,判断用户是否答对并给出答案,做减法时减数大于被减数,做除法时是否整除。
3.2 编程思想
在减法函数中加入if判断是否减数小于被减数,若小于则跳转本次循环,在除法函数中加入if判断是否除数小于被除数,限制被除数不为0,并且加入是否为整除的判断,为整除时,两数取余不为0则跳转本次循环,不为整除时,两数取余为0则跳转本次循环。
3.3 程序代码
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include<math.h>
void menu();
int main()
{
system("cls");
menu();
eturn 0;
}
void addtion()
{
int a,b,i,d,number;
srand ( (unsigned) time (NULL) );
system("cls");
printf("\t请输入题目数!\n\t\t");
scanf("%d",&number);
getchar();
printf("\t程序将会随机出题,请输入正确答案!\n\t\t");
for(i=0;i<number;i++)
{
a=rand()%100;
b=rand()%100;
if(a+b>=100)
{
i--;
continue;
}
printf("\n\t%d + %d=",a,b);
scanf("%d",&d);
if(d==a+b)
{
printf("\t恭喜答对了\n");
}
else printf("\t很可惜,错了哦!答案是%d\n",a+b);
}
printf("\t你已经做完测试,请按任意键返回菜单\n");
getch();
}
void subtraction()
{
int a,b,i,d,number;
srand ( (unsigned) time (NULL) );
system("cls");
printf("\t请输入题目数!\n\t\t");
scanf("%d",&number);
getchar();
printf("\t程序将会随机出题,请输入正确答案!\n\t\t");
for(i=0;i<number;i++)
{
a=rand()%100;
b=rand()%100;
if(a-b<=0)
{
i--;
continue;
}
printf("\n\t%d - %d=",a,b);
scanf("%d",&d);
if(d==a-b)
{
printf("\t恭喜答对了\n");
}
else printf("\t很可惜,错了哦!答案是%d\n",a-b);
}
printf("\t你已经做完测试,请按任意键返回菜单\n");
getch();
}
void multiply()
{
int a,b,i,d,number;
srand ( (unsigned) time (NULL) );
system("cls");
printf("\t请输入题目数!\n\t\t");
scanf("%d",&number);
getchar();
printf("\t程序将会随机出题,请输入正确答案!\n\t\t");
for(i=0;i<number;i++)
{
a=rand()%100;
b=rand()%100;
if(a*b>=100)
{
i--;
continue;
}
printf("\n\t%d * %d=",a,b);
scanf("%d",&d);
if(d==a*b)
{
printf("\t恭喜答对了\n");
}
else printf("\t很可惜,错了哦!答案是%d\n",a*b);
}
printf("\t你已经做完测试,请按任意键返回菜单\n");
getch();
}
void division()
{
int i,a,b,number,c,f,g;
double d,e;
srand ( (unsigned) time (NULL) );
system("cls");
printf("\t请输入题目数!\n\t\t");
scanf("%d",&number);
getchar();
printf("\t是否整除?(是1/否0)\n\t\t");
scanf("%d",&c);
getchar();
printf("\t程序将会随机出题,请输入正确答案!\n\t\t");
if(c==0)
{
for(i=0;i<number;i++)
{
a=rand()%100;
b=rand()%100;
if((a<b)||b==0||a%b==0)
{
i--;
continue;
}
printf("\n\t%d / %d=",a,b);
e=(a*1.0)/b;
scanf("%lf",&d);
if(fabs(e-d)<0.001)
{
printf("\t恭喜答对了\n");
}
else
printf("\t很可惜,错了哦!答案是%.2lf\n",e);
}
printf("\t你已经做完测试,请按任意键返回菜单\n");
getch();
}
else
{
for(i=0;i<number;i++)
{
a=rand()%100;
b=rand()%100;
if(a<b||b==0||a%b!=0)
{
i--;
continue;
}
printf("\n\t%d / %d=",a,b);
g=a/b;
scanf("%d",&f);
if(g==f)
{
printf("\t恭喜答对了\n");
}
else printf("\t很可惜,错了哦!答案是%d\n",a/b);
}
printf("\t你已经做完测试,请按任意键返回菜单\n");
getch();
}
}
void menu()
{
int i;
printf("\n\n\t******************************\n");
printf("\t* 欢迎使用四则运算练习软件 *\n");
printf("\t* 1- 加法 *\n");
printf("\t* 2- 减法 *\n");
printf("\t* 3- 乘法 *\n");
printf("\t* 4- 除法 *\n");
printf("\t* 0- 退出 *\n");
printf("\t******************************");
i=getch();
switch(i)
{
case '1':addtion();break;
case '2':subtraction();break;
case '3':multiply();break;
case '4':division();break;
case '0':exit(0);break;
default:system("cls");printf("\n\t\t请输入1~4!\n\n\n");getch();break;
}
main();
}
3.4 程序结果
3.5 总结
经过两次次修改,我们已经实现了大部分功能,程序接近完善,能判断用户是否答对并给出答案,做减法时减数一定大于被减数,做除法时可选择是否整除,可定制题目的数量。
三、问题及解决方案
1) 在第一次编程过程中,将随机函数的时间节点放入了运算符和数字函数当中,导致了每一次循环过程中出现的随机数都是一样的。只需要将其删除就可以了。
2) 非整除的if判断存在问题,用户输入的double类型的d与实际的e的值有小数点位数的差异,比如用户输入1.62正确答案,而e的实际值为1.62000。将其修改为fabs(e-d)<0.001 就能正常运行了。
3) 在非整除的算法里定义e为float类型,但是ab都为int型,除出来总是整数。将其修改为e=a*1.0/b就可以了。
四、心得体会
总体来说这个程序不是很难实现,我们的优化也是循序渐进的,一开始写出了雏形,然后慢慢修改,有了思路按照想的写下来,修改一下错误就完成了,意外地花了比我们预期少的时间,也没有按照之前决定的一人编代码,一人写博客,因为写博客的人没有编代码,很难写出代码的进程以及遇到的问题和解决方案。这次的作业让我们再一起体验了结对编程,上一次还是在小学期里,在编程的过程中遇到的问题大家可以一起解决,在编程前可以和同伴商讨算法怎么实现、如何构建函数等等,一个人编程遇到困难很难进行下去,而两个人可以互相讨论,如破竹之势就解决了很多问题,总体感觉比个人编程的感受要好一些,这次编程不能使我的技巧提高多少,但是却让我感受到了合作的力量,以后工作了一定是一个团队一起的,所以在大学提前感悟到此我认为是十分有必要的。
五、思考
我们的程序还有很多需要改进的地方,比如没有窗口界面,时间有限,我们没有编写窗口的界面,程序功能也没有做全,是否有括号以及打印间隔无法调整。这个四则运算的软件我觉得很实用,老师和家长不用给小学生们编题目,程序还能给他们判断对错,解放了双手,如果增加窗口界面并且增加功能应该投入使用。