四则运算(C语言)

1. 作业信息

这个作业属于哪个课程 软件工程
这个作业要求在哪里 作业要求
学号 3180701312

2.题目

写一个能自动生成小学四则运算题目的程序,然后在此基础上扩展:

1)除了整数以外,还要支持真分数的四则运算,例如:1/6+1/8=7/24

2)程序要求能处理用户的输入,判断对错,累积分数

3)程序支持可以由用户自行选择加、减、乘、除运算

4)使用-n参数控制生成题目的个数,例如Myapp.exe -n 10,将生成10个题目

3. 代码提交与运行截图

3.1 源代码

头文件

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

界面

void menu()
{
	system("cls");   //清屏操作 
	printf("**********四则运算题目生成器***********
");
	printf("请选择生成的题目类型:
");
	printf("1.加法运算
");
	printf("2.减法运算
");
	printf("3.乘法运算
");
	printf("4.除法运算
");
	printf("0.退出
");
	printf("提示:真分数运算结果要化简!
");
	printf("请输入选项(0-4):");
}

产生不重复随机数

int *produce(int *eg,int num_a,int num_b) 
{
	int i,m,k,*a,j,t=1,v,b;
	m=num_b-num_a+1;
	v=m/2-1;
	b=0;
	a=(int *)malloc(m/2*sizeof(int));
	srand(time(NULL));
	while(t<=2)
	{
		for(j=0,i=b+1;i<=v+1;i++,j++)
		{
			a[j]=i;
		}
		for(k=0,i=b;i<=v;i++,k++)
    	{
    	    j=(int) ((float) ((m/2-k)*rand())/(RAND_MAX+1.0));
   	     	eg[i]=a[j];
   	     	a[j]=a[m/2-1-k];
   		 }
   		 b=m/2;
   		 v=m-1;
   		 t++;
	}
    free(a);
	return eg;
}

化简分数

int *simplify(int *f)
{
	int i;
	for(i=f[0];i>1;i--)
	{
		if((f[0]%i==0)&&(f[1]%i==0))
		{
			f[0]=f[0]/i;
			f[1]=f[1]/i;
			i=f[0];
		}
	}
	return f;
}

答题结束

void over()
{
   int i;
   printf("答题结束!输入任意数字退出!
");
   printf("请输入数字:");
   scanf("%d",&i);
}

主函数

int main()
{
	int *number_int=NULL;//随机数整数数组
	int *number_f=NULL;//随机数真分数数组 
	int i,m,k,q,w,r;
	int *f1,*f2;//分子和分母 
	float answer;
	float y;
	int score,error;
	int j; //真分数题目数量 
	int n;//生成题目数量 
	while(1)
	{
		menu();
		do
		{
			scanf("%d",&i);
			if(i<0||i>4)
			{
				printf("输入不合法!请重新输入!
");
			}
		}while(i<0||i>4);
		if(i!=0)
		{
			do
			{
				printf("请输入测试题目数量(题目生成数量1-50):");
				scanf("%d",&n);
				if(n<1||n>50)
				{
					printf("输入不合法!请重新输入!
");
				}
			}while(n<1||n>50);
			j=n/3;//真分数数量是总体的1/3 
			m=2*(n-j);
			k=4*j;
			number_int=(int *)malloc(m*sizeof(int));
			number_f=(int *)malloc(k*sizeof(int));
			number_int=produce(number_int,0,m-1);//乘数,减数,除数//被乘数,被减数,被除数,加数 
			number_f=produce(number_f,0,k-1);//分子取值区 //分母取值区 
			f1=(int *)calloc(2,sizeof(int));
			f2=(int *)calloc(2,sizeof(int));
		}
		switch(i)
		{
			//加法 
			case 1:
				score=0;
				for(q=0,w=m/2;q<=m/2-1;q++,w++)//整数 
				{
					answer=number_int[q]+number_int[w];
					printf(" %d + %d = ",number_int[q],number_int[w]);
					scanf("%d",&r);
					if(r==answer)
					{
						score++;//得分 
						printf("正确!得分:%d
",score);
					}
					else
					{
						printf("错误!正确答案:%0.1f
",answer);
					}
				}
				for(q=0,w=k/2;q<k/2-1;q++,w++)//真分数数 
				{
					f1[0]=number_f[q];//分子 
					f1[1]=number_f[w];//分母 
					printf("%d/%d +",f1[0],f1[1]);
					f1=simplify(f1);//化简 
					f2[0]=number_f[q+1];//分子 
					f2[1]=number_f[w+1];//分母 
					printf("%d/%d =
",f2[0],f2[1]);
					f2=simplify(f2);
					f1[0]=f1[0]*f2[1]+f1[1]*f2[0];
					f1[1]=f1[1]*f2[1];
					f1=simplify(f1);//结果 
					//printf("运算到了!!!");
					printf("分子:"); 
					scanf("%d",&f2[0]);
					printf("分母:"); 
					scanf("%d",&f2[1]);
					if(f1[0]==f2[0]&&f1[1]==f2[1])
					{
						score++;//得分 
						printf("正确!得分:%d
",score);
					}
					else
					{
						printf("错误!正确答案:%d/%d
",f1[0],f1[1]);
					}
				}
				printf("总得分%d
",score);
				over();free(number_int);free(number_f);free(f1);free(f2);
				break; 
			//减法 
			case 2:
				score=0;
				for(q=0,w=m/2;q<=m/2-1;q++,w++)//整数 
				{
					answer=number_int[w]-number_int[q];
					printf(" %d - %d = ",number_int[w],number_int[q]);
					scanf("%d",&r);
					if(r==answer)
					{
						score++;//得分 
						printf("正确!得分:%d
",score);
					}
					else
					{
						printf("错误!正确答案:%0.1f
",answer);
					}
				}
				for(q=0,w=k/2;q<k/2-1;q++,w++)//真分数 
				{
					
					f1[0]=number_f[q];//分子 
					f1[1]=number_f[w];//分母 
					f2[0]=number_f[q+1];//分子 
					f2[1]=number_f[w+1];//分母
					if(f1[0]*f2[1]-f1[1]*f2[0]>=0)//防止出现负数 
					{
						printf("%d/%d -",f1[0],f1[1]);
						printf("%d/%d =
",f2[0],f2[1]);
						f1[0]=f1[0]*f2[1]-f1[1]*f2[0];
					}
					else
					{
						printf("%d/%d -",f2[0],f2[1]);
						printf("%d/%d =
",f1[0],f1[1]);
						f1[0]=f1[1]*f2[0]-f1[0]*f2[1];
					}
					f1[1]=f1[1]*f2[1];
					f1=simplify(f1);//结果 
					printf("分子:"); 
					scanf("%d",&f2[0]);
					printf("分母:"); 
					scanf("%d",&f2[1]);
					if(f1[0]==f2[0]&&f1[1]==f2[1])
					{
						score++;//得分 
						printf("正确!得分:%d
",score);
					}
					else
					{
						printf("错误!正确答案:%d/%d
",f1[0],f1[1]);
					}
				}
				printf("总得分%d
",score);
				over();free(number_int);free(number_f);free(f1);free(f2);
				break;
			//乘法 
			case 3:
				score=0;
				for(q=0,w=m/2;q<=m/2-1;q++,w++)//整数 
				{
					answer=number_int[q]*number_int[w];
					printf(" %d * %d = ",number_int[q],number_int[w]);
					scanf("%d",&r);
					if(r==answer)
					{
						score++;//得分 
						printf("正确!得分:%d
",score);
					}
					else
					{
						printf("错误!正确答案:%0.1f
",answer);
					}
				}
				for(q=0,w=k/2;q<k/2-1;q++,w++)//真分数数 
				{
					
					f1[0]=number_f[q];//分子 
					f1[1]=number_f[w];//分母 
					printf("%d/%d *",f1[0],f1[1]);
					f1=simplify(f1);//化简 
					f2[0]=number_f[q+1];//分子 
					f2[1]=number_f[w+1];//分母 
					printf("%d/%d =
",f2[0],f2[1]);
					f2=simplify(f2);
					f1[0]=f1[0]*f2[0];
					f1[1]=f1[1]*f2[1];
					f1=simplify(f1);//结果 
					printf("分子:"); 
					scanf("%d",&f2[0]);
					printf("分母:"); 
					scanf("%d",&f2[1]);
					if(f1[0]==f2[0]&&f1[1]==f2[1])
					{
						score++;//得分 
						printf("正确!得分:%d
",score);
					}
					else
					{
						printf("错误!正确答案:%d/%d
",f1[0],f1[1]);
					}
				}
				printf("总得分%d
",score);
				over();free(number_int);free(number_f);free(f1);free(f2);
				break;
			//除法 
			case 4:
				printf("整数除法保留一位小数
");
				score=0;
				for(q=0,w=m/2;q<=m/2-1;q++,w++)//整数 
				{
					answer=number_int[w]/(number_int[q]*1.0);
					printf(" %d / %d = ",number_int[w],number_int[q]);
					scanf("%f",&y);
					if(y==answer)
					{
						score++;//得分 
						printf("正确!得分:%d
",score);
					}
					else
					{
						printf("错误!正确答案:%0.1f
",answer);
					}
				}
				for(q=0,w=k/2;q<k/2-1;q++,w++)//真分数数 
				{
					
					f1[0]=number_f[q];//分子 
					f1[1]=number_f[w];//分母 
					printf("%d/%d /",f1[0],f1[1]);
					f1=simplify(f1);//化简 
					f2[0]=number_f[q+1];//分子 
					f2[1]=number_f[w+1];//分母 
					printf("%d/%d =
",f2[0],f2[1]);
					f2=simplify(f2);
					f1[0]=f1[0]*f2[1];
					f1[1]=f1[1]*f2[0];
					f1=simplify(f1);//结果 
					printf("分子:"); 
					scanf("%d",&f2[0]);
					printf("分母:"); 
					scanf("%d",&f2[1]);
					if(f1[0]==f2[0]&&f1[1]==f2[1])
					{
						score++;//得分 
						printf("正确!得分:%d
",score);
					}
					else
					{
						printf("错误!正确答案:%d/%d
",f1[0],f1[1]);
					}
				}
				printf("总得分%d
",score);
				over();free(number_int);free(number_f);free(f1);free(f2);
				break;
			default: return 0;		
		}
	}	
}

3.2 运行截图

(1)加法

(2)减法

(3)乘法

(4)除法

4. 个人小结

困难:
1动态分配内存失败!
原因:在前面的程序中出现了内存的越界访问,导致malloc()分配函数所涉及的一些信息被破坏。下次再使用malloc()函数申请内存就会失败,返回空指针NULL(0)。
2.随机数的产生重复
原因:因为此程序产生一个随机数之前,都调用一次srand,而由于计算机运行很快,所以每用time得到的时间都是一样的(time的时间精度较低,只有55ms)。这样相当于使用同一个种子产生随机序列,所以产生的随机数总是相同的。将srand放在循环外。

(psp表格)

psp2.1 任务内容 计划完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划 340 520
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 30 60
Development 开发 20 40
Analysis 需求分析(包括学习新技术) 30 50
Design Spec 生成设计文档 20 20
Design Review 设计复审 10 15
Coding Standard 代码规范 10 10
Design 具体设计 30 60
Coding 具体编码 60 120
Code Review 代码复审 30 60
Test 测试(自我测试,修改代码,提交修改) 40 60
Reporting 报告 10 20
Test Report 测试报告 10 15
Size Measurement 计算工作量 20 20

|Postmortem & Process Improvement Plan| 事后总结,并提出过程改进计划| 20 |30|

原文地址:https://www.cnblogs.com/Jean1225/p/13940855.html