一、作业信息
问题 | 结果 |
---|---|
这个作业属于哪个课程 | 软件工程 |
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 能对需求进行分析并实现;编码格式规范;学习博客撰写 |
学号 | 3180701313 |
二、作业要求
写一个能自动生成小学四则运算题目的程序,然后在此基础上扩展:
1)除了整数以外,还要支持真分数的四则运算,例如:1/6+1/8=7/24
2)程序要求能处理用户的输入,判断对错,累积分数
3)程序支持可以由用户自行选择加、减、乘、除运算
4)使用-n参数控制生成题目的个数,例如Myapp.exe -n 10,将生成10个题目
三、代码与解释
准备阶段
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
# define Ture 1
# define Flase 0;
/*
1、整数 加 减 乘 除
2、分数 加 减 乘 除
3、 答案比对,判断正误
4、分数化简
5、计入分值,答对一题一分,答错不得分
*/
3.1 整数运算部分
3.1.1 整数运算函数
int int_count(int flag,int score,int n_int){
int i,flag1; //循环i,题目类型flag ,正确标志flag1
int a,b,answer,answer1; //操作数a和b,answer正确答案,answer1用户输入
float answer2,answer3;
printf("
");
switch(flag){
case 1:{ //整数加法
for(i=0;i<n_int;i++){
a=randomly(0);
b=randomly(0); //随机生成题目
answer=add_int(a,b); //计算机计算答案
printf("第%d题: %d + %d = ?
",i+1,a,b);
printf("请用户输入答案:");
scanf("%d",&answer1); //用户答案
flag1=judge(answer,answer1); //答案比对
if(flag1==Ture){
score=score+1;
printf("第%d题:正确 加一分 当前总分%d
",i+1,score);
}else{
printf("第%d题:错误 不得分 当前总分%d
",i+1,score);
}
}
break;
}
case 2:{ //整数减法
for(i=0;i<n_int;i++){
a=randomly(0);
b=randomly(0); //随机生成题目
answer=sub_int(a,b); //计算机计算答案
printf("第%d题: %d - %d = ?
",i+1,a,b);
printf("请用户输入答案:");
scanf("%d",&answer1); //用户答案
flag1=judge(answer,answer1); //答案比对
if(flag1==Ture){
score=score+1;
printf("第%d题:正确 加一分 当前总分%d
",i+1,score);
}else{
printf("第%d题:错误 不得分 当前总分%d
",i+1,score);
}
}
break;
}
case 3:{ //整数乘法
for(i=0;i<n_int;i++){
a=randomly(0);
b=randomly(0); //随机生成题目
answer=mul_int(a,b); //计算机计算答案
printf("第%d题: %d * %d = ?
",i+1,a,b);
printf("请用户输入答案:");
scanf("%d",&answer1); //用户答案
flag1=judge(answer,answer1); //答案比对
if(flag1==Ture){
score=score+1;
printf("第%d题:正确 加一分 当前总分%d
",i+1,score);
}else{
printf("第%d题:错误 不得分 当前总分%d
",i+1,score);
}
}
break;
}
case 4:{ //整数除法
for(i=0;i<n_int;i++){
//printf("
1
");
a=randomly(0);
b=randomly(1); //随机生成题目
answer2=(float)b/a; //这个步骤代替了除法的调用函数
printf("第%d题: %d / %d = ?
",i+1,b,a);
printf("请用户输入答案:");
scanf("%f",&answer3);
if(fabs(answer2-answer3)<0.01){ //判断不出来
score=score+1;
printf("第%d题:正确 加一分 当前总分%d
",i+1,score);
}else{
printf("第%d题:错误 不得分 当前总分%d
",i+1,score);
}
}
break;
}
default :printf("题目类型选择错误,结束系统!!!!");exit(0);break;
}
return score;
}
3.1.2 整数加法
int add_int(int a,int b){
int answer;
answer=a+b;
return answer;
}
3.1.3 整数减法
int sub_int(int a,int b){
int answer;
answer=a-b;
return answer;
}
3.1.4 整数乘法
int mul_int(int a,int b){
int answer;
answer=a*b;
return answer;
}
3.1.5整数除法
answer2=(float)b/a; //这个步骤代替了除法的调用函数,在整数运算部分的case 4 :部分直接求得,不在封装函数
3.2 真分数运算部分
3.2.1 真分数运算函数
int eig_count(int flag,int score,int n_eig,int n_int){
int a,c;
int b,d; //分母a,c;分子b,d b/a d/c
int flag_answer1,flag_answer; //得分标志
int temp,temp1,i; //临时变量 temp 分母 temp1 分子
int answer,answer1; //用户输入answer分母,answer1分子
char cha; //分数符号
switch(flag){
case 1:{ //分数加法
for(i=0;i<n_eig;i++){
a=randomly(1);
b=randomly(0);
c=randomly(1);
d=randomly(0); //随机生成题目
add_eig(a,b,c,d,&temp,&temp1); //计算机计算
simplify(&temp,&temp1); //分数化简
printf("第%d题: %d/%d + %d/%d = ?
",i+1+n_int,b,a,d,c);
printf("请用户输入答案(若答案为0,请按照0/1格式书写):");
scanf("%d%c%d",&answer1,&cha,&answer);
if(answer==0){
printf("
分数分母不能为0,计算错误!!!
");
flag_answer=Flase;
flag_answer1=Flase;
}else{
flag_answer1=judge(temp1,answer1); //对分子进行检查
flag_answer=judge(temp,answer); //对分母进行检查
}
if(flag_answer1==Ture&&flag_answer==Ture&&cha=='/'){
score=score+1;
printf("第%d题:正确 加一分 当前总分%d
",i+1+n_int,score);
} else{
printf("第%d题:错误 不得分 当前总分%d
",i+1+n_int,score);
}
}
break;
}
case 2:{//分数减法
for(i=0;i<n_eig;i++){
a=randomly(1);
b=randomly(0);
c=randomly(1);
d=randomly(0); //随机生成题目
sub_eig(a,b,c,d,&temp,&temp1); //计算机计算
simplify(&temp,&temp1); //分数化简
printf("第%d题: %d/%d - %d/%d = ?
",i+1+n_int,b,a,d,c);
printf("请用户输入答案(若答案为0,请按照0/1格式书写):");
scanf("%d%c%d",&answer1,&cha,&answer);
if(answer==0){
printf("
分数分母不能为0,计算错误!!!
");
flag_answer=Flase;
flag_answer1=Flase;
}else{
flag_answer1=judge(temp1,answer1); //对分子进行检查
flag_answer=judge(temp,answer); //对分母进行检查
}
if(flag_answer1==Ture&&flag_answer==Ture&&cha=='/'){
score=score+1;
printf("第%d题:正确 加一分 当前总分%d
",i+1+n_int,score);
} else{
printf("第%d题:错误 不得分 当前总分%d
",i+1+n_int,score);
}
}
break;
}
case 3:{//分数乘法
for(i=0;i<n_eig;i++){
a=randomly(1);
b=randomly(0);
c=randomly(1);
d=randomly(0); //随机生成题目
mul_eig(a,b,c,d,&temp,&temp1); //计算机计算
simplify(&temp,&temp1); //分数化简
printf("第%d题: %d/%d * %d/%d = ?
",i+1+n_int,b,a,d,c);
printf("请用户输入答案(若答案为0,请按照0/1格式书写):");
scanf("%d%c%d",&answer1,&cha,&answer);
if(answer==0){
printf("
分数分母不能为0,计算错误!!!
");
flag_answer=Flase;
flag_answer1=Flase;
}else{
flag_answer1=judge(temp1,answer1); //对分子进行检查
flag_answer=judge(temp,answer); //对分母进行检查
}
if(flag_answer1==Ture&&flag_answer==Ture&&cha=='/'){
score=score+1;
printf("第%d题:正确 加一分 当前总分%d
",i+1+n_int,score);
} else{
printf("第%d题:错误 不得分 当前总分%d
",i+1+n_int,score);
}
}
break;
}
case 4:{//分数除法
for(i=0;i<n_eig;i++){
a=randomly(1);
b=randomly(0);
c=randomly(1);
d=randomly(1); //随机生成题目
div_eig(a,b,c,d,&temp,&temp1); //计算机计算
simplify(&temp,&temp1); //分数化简
printf("第%d题: %d/%d / %d/%d = ?
",i+1+n_int,b,a,d,c);
printf("请用户输入答案(若答案为0,请按照0/1格式书写):");
scanf("%d%c%d",&answer1,&cha,&answer);
if(answer==0){
printf("
分数分母不能为0,计算错误!!!
");
flag_answer=Flase;
flag_answer1=Flase;
}else{
flag_answer1=judge(temp1,answer1); //对分子进行检查
flag_answer=judge(temp,answer); //对分母进行检查
}
if(flag_answer1==Ture&&flag_answer==Ture&&cha=='/'){
score=score+1;
printf("第%d题:正确 加一分 当前总分%d
",i+1+n_int,score);
} else{
printf("第%d题:错误 不得分 当前总分%d
",i+1+n_int,score);
}
}
break;
}
default :printf("题目类型选择错误,结束系统!!!!");exit(0);break;
}
return score;
}
3.2.2 真分数加法
void add_eig(int a,int b,int c,int d,int *temp,int *temp1){ //*temp 分母 *temp1 分子
*temp=mul_int(a,c); //分母通分
*temp1=mul_int(b,c)+mul_int(d,a); //分子相加
}
3.2.3 真分数减法
void sub_eig(int a,int b,int c,int d,int *temp,int *temp1){ //*temp 分母 *temp1 分子
*temp=mul_int(a,c); //分母通分
*temp1=mul_int(b,c)-mul_int(d,a); //分子相减
}
3.2.4 真分数乘法
void mul_eig(int a,int b,int c,int d,int *temp,int *temp1){ //*temp 分母 *temp1 分子
*temp=mul_int(a,c);
*temp1=mul_int(b,d);
}
3.2.5 真分数除法
void div_eig(int a ,int b,int c, int d,int *temp,int *temp1){ //*temp 分母 *temp1 分子
*temp=mul_int(a,d);
*temp1=mul_int(d,c);
}
3.3其他函数
3.3.1 随机生成数
int randomly(int j){
int i;
i=rand()%100+j;
return i;
}
3.3.2 答案对比
int judge(int answer,int answer1){
if(answer-answer1==0){ //可以得分
return Ture;
}else{ //得分失败
return Flase;
}
}
3.3.3 真分数约分
void simplify(int *temp,int *temp1){ //*temp 分母 *temp1 分子
int m;
for(m=*temp;m>=1;m--){
if((*temp%m==0)&&(*temp1%m==0))
{
*temp=*temp/m;
*temp1=*temp1/m;
}
}
if(*temp1==0){
*temp=1;
}
}
3.3.4 主函数
void main(void){
int n,n_int,n_eig; //n题目数量,n_int整数题,n_eig分数题,整数和分数题目个数对半分
int score=0; //用户得分
int flag;
int c=1;
while(c){
score=0;
printf(" 1、整数和分数的 加法
2、整数和分数的 减法
3、整数和分数的 乘法
4、整数和分数的 除法
");
printf("请输入题目的数量:");
scanf("%d",&n);
printf("
请选择题目类型:");
scanf("%d",&flag);
if(n%2==0){//题目个数
n_int=n/2;
n_eig=n/2;
}else if(n%2==1){
n_int=(n+1)/2;
n_eig=(n-1)/2;
}
score=int_count(flag,score,n_int); //整数计算操作
score=eig_count(flag,score,n_eig,n_int); //分数计算操作
printf("/*****答题结束*****/");
printf("
您的最终得分为:%d",score);
printf("
继续回答问题请按1,结束请按0:");
scanf("%d",&c);
system("cls");
}
}
四、运行截图
在之后的运行演示中输入题目总数5题,系统生成3题整数题,2题真分数题,输出最后的用户得分。
4.1加法
4.2减法
4.3乘法
4.4除法
五、个人小结
5.1 小结
在四则运算代码的编写过程中,总体来说还算是顺利的。老师要求的任务全部完成,所有的功能都能够正常的运行没有报错的出现。
这里的简单说一下代码的几点不足:
1)在细节方面处理不够。
2)对于用户界面的提示不够全面。
3)对于结构输出和输入的考虑不是特别全面,但是基本功能可以实现。
4)对于markdown编写博客的使用不够熟练。
5.2 psp表格
psp2.1 | 任务内容 | 计划完成需要的时间(min) | 实际完成需要的时间(min) |
---|---|---|---|
Planning | 计划 | 20 | 15 |
Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 10 | 8 |
Development | 开发 | 180 | 150 |
Analysis | 需求分析(包括学习新技术) | 25 | 20 |
Design Spec | 生成设计文档 | 30 | 25 |
Design Review | 设计复审 | 15 | 10 |
Coding Standard | 代码规范 | 10 | 5 |
Design | 具体设计 | 20 | 15 |
Coding | 具体编码 | 40 | 50 |
Code Review | 代码复审 | 15 | 13 |
Test | 测试(自我测试,修改代码,提交修改) | 20 | 15 |
Reporting | 报告 | 25 | 30 |
Test Report | 测试报告 | 5 | 5 |
Size Measurement | 计算工作量 | 10 | 10 |
Postmortem & Process Improvement Plan | 事后总结,并提出过程改进计划 | 10 | 10 |