本周做的是一个自己单独完成的小程序,用来随机生成小学四则运算的题目。
看到这个题目时,头脑有大概的一个编写代码的思路,但都言万事开头难,到真正开始的时候却不知从何下手。于是采取老师的建议参考别人的代码,然后再自己做修改。我在百度上搜索了实现该题目的代码,最终我采用的是百度知道的知道行家ahulxh老师的代码,该代码是在Windows系统上运行,开发环境为visaul c++ 6.0。首次运行老师的代码时出现了一个bug,显示的原因是缺少头文件#include<stdio.h>,修改以后再次运行了代码,详细了解了代码所具有的功能,代码原本的功能是通过生成0-9之内的随机数来随机产生10道四组运算的题目,可以判断对错及计分,每道题10分,答题完成以后显示得分。这就是代码原本的功能,结合作业的要求以及我所发现的代码的不足之处,我做了相应功能上的修改并增加了以下功能:
1、用户可选择答题的方式,线下和线上两种方式,线下为将产生的题目写入到文本文档;
2、用户可自定义随机数产生的范围和题目数量;
3、用户线上答题,输入答案以后判断对错,若错误则需要显示正确答案;
4、改变计分方式,实行百分制,每道题的分数为100.0/题目数量,保留一位小数;
5、计时功能,从用户线上答题开始计时,答题完成以后显示所用时间;
6、支持真分数的四则运算;
7、减法运算避免有负数答案的产生,除法运算避免分母为零。
功能虽然很简单,实现的过程中却也遇到了很多的问题。线下答题方式的实现,将题目写入到文本文档中,找出了大一的《语言程序设计》,重学了这本书中关于文件的操作方法才使这个功能得以顺利的实现。功能2,3,4的实现较为简单,将之前的常量设置为变量由用户自己输入即可完成相应的功能,遇到的问题是由于忽略了两个整数(100和题目数量)相处,运行的结果依然会是整数这个问题,导致计分达不到想要的效果,之后检查将100修改为100.0后解决此问题。计时功能是我之前所没有接触过的,所以借助了万能的百度,查看了实现该功能的一些函数和代码,最终我才用的是添加time.h头文件,使用time()函数来实现该功能。实现能支持真分数的运算是比较难的一块,之前的思路是通过产生四个随机数来组成两个分数,然后跟整数一起随机产生运算,但遇到的问题是,要如何实现整数和分数的和谐共处呢?我自己采用了很多办法都没有成功,最后借助网络上一些网友提供的办法,将是否产生真分数的运算有产生的随机数决定,mode的四个值0-4分别代表加减乘除和真分数的运算,若产生4则单独进行真分数的四则运算,重新产生一个随机数来决定运算符。然后除法和减法运算的注意之处都是一些细节的东西,实现较为容易,具体实现见后附的源代码。
总结:虽然整个程序的实现是在参考他人代码的基础上实现的,但在自己修改和增加一些功能的过程中,自己也获益良多,解决的每一个bug对我来说都是一次提升。这个程序中还存在很多的不足之处:如除法运算有小数,真分数的运算有小数的情况下,用户只能取整才会是正确的答案;此外,教材要求的支持多个运算符,括号,多语言的功能也还未实现,还需不断完善。
源代码上传到GitHub网页地址为:https://github.com/fancy-dawning/hello-world.git
源代码如下:
/*添加功能 1、选择答题方式:线上 线下(文本文档)
2、计分
3、计时
4、支持分数计算*/
#include<stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <conio.h>
#include <time.h>
#include <windows.h>
int a; //第一个数
int b; //第二个数
int d; //中间变量
int f,g; //用于分数
int mode;//0:加 1:减 2:乘 3:除 4:真分数
int c; //输入答案
int result; //正确答案
int x; //答题方式
float p,q;
double score = 0; //成绩
int m;//题数目
int e;//随机数生成的范围
int main() {
void menu();
void online();
void offline();
menu();
return 0;
}
void offline() //增加功能
{
int i=0;
char t,t1;
char s[100];
FILE *f;
printf("请输入需要的题目数目:");
scanf("%d",&m);
printf("请输入生成随机数的范围:");
scanf("%d",&e);
f=fopen("d:\\tencent\\jisuan.txt","w");
if(f==NULL)
{
printf("文件打开出错!");
}
else
{
for(i=0;i<m;i++)
{
s[i]=rand() % e;
s[i+1]=rand() % e;
mode = rand() % 5; //生成一个0~3之间的随机数,代表运算符
switch(mode)
{
case 0:
t=‘+‘;
fprintf(f,"%d",s[i]);
fputc(t,f);
fprintf(f,"%d",s[i+1]);
fputs("=\n",f);
break;
case 1:
if(s[i]<s[i+1])
{
d=s[i];
s[i]=s[i+1];
s[i+1]=d;
}
t=‘-‘;
fprintf(f,"%d",s[i]);
fputc(t,f);
fprintf(f,"%d",s[i+1]);
fputs("=\n",f);
break;
case 2:
t=‘*‘;
fprintf(f,"%d",s[i]);
fputc(t,f);
fprintf(f,"%d",s[i+1]);
fputs("=\n",f);
break;
case 3:
while(s[i+1]==0) //除法保证除数不为零
{
s[i+1]=rand()%e;
}
t=‘/‘;
fprintf(f,"%d",s[i]);
fputc(t,f);
fprintf(f,"%d",s[i+1]);
fputs("=\n",f);
break;
case 4:
t1=‘/‘;
s[i+2] = rand() % e;
s[i+3] = rand() % e;
mode = rand() % 4 ;
while (s[i+1] == 0) // 分母不为零
{
s[i+1] = rand() % e;
}
while (s[i+3] == 0) //分母不为零
{
s[i+3] = rand() % e;
}
if(s[i]>s[i+1]) //保证分子小于分母
{
d=s[i];
s[i]=s[i+1];
s[i+1]=d;
}
if(s[i+2]>s[i+3])
{
d=s[i+2];
s[i+2]=s[i+3];
s[i+3]=d;
}
switch (mode)
{
case 0:
t=‘+‘;
break;
case 1:
p = (float)s[i] / (float)s[i+1];
q = (float)s[i+1] / (float)s[i+3];
if (p < q)
{
d = s[i];
s[i] = s[i+2];
s[i+2] = d;
d = s[i+1];
s[i+1] = s[i+3];
s[i+3] = d;
}
t=‘-‘;
break;
case 2:
t=‘*‘;
break;
case 3:
while (s[i+2]== 0)
{
s[i+2] = rand() % 100;
}
t=‘/‘;
break;
default:
printf("未知错误!\n");
break;
}
fprintf(f,"%d",s[i]);
fputc(t1,f);
fprintf(f,"%d",s[i+1]);
fputs(" ",f);
fputc(t,f);
fputs(" ",f);
fprintf(f,"%d",s[i+2]);
fputc(t1,f);
fprintf(f,"%d",s[i+3]);
fputs("=\n",f);
}
}
}
printf("题目已成功保存到d:\\tencent\\jisuan.txt!\n");
fclose(f);
}
void online(){
time_t t1,t2;
printf("请输入需要的题目数目:");
scanf("%d",&m);
printf("请输入生成随机数的范围:");
scanf("%d",&e);
srand((unsigned)time( NULL ) ); //初始化随机数发生器,使得每次运行生成的随机数不同
printf("\n\n\n\t\t\t\t答题即将开始,建议答题时间为%0.1f分钟(结果为非整数时取整数)!\n",m*0.5);
system("pause");
system("cls");
time(&t1); //计时开始(增加)
for(int i=0;i<m;i++)
{
a = rand() % e; //生成一个随机数
b = rand() % e; //生成另一个随机数
mode = rand() % 5; //生成一个0~4之间的随机数,代表运算符
switch(mode) //确定运算符
{
case 0:
printf("%d + %d = ",a,b);
result= a + b; //选择了+运算的正确答案
break;
case 1:
if(a<b)
{
d=a;
a=b;
b=d;
} //减法保证结果不为负数
printf("%d + %d = ", a,b);
result= a - b; //选择了-运算的正确答案
break;
case 2:
printf("%d * %d = ", a,b);
result= a * b; //选择了*运算的正确答案
break;
case 3:
while(b==0) //除法保证除数不为零
{
b=rand()%e;
}
printf("%d / %d = ", a,b);
result= a / b; //选择了/运算的正确答案
break;
case 4: //增加真分数运算
f = rand() % e;
g = rand() % e;
mode = rand() % 4 ;
while (b == 0) // 分母不为零
{
b = rand() % e;
}
while (g == 0) //分母不为零
{
g = rand() % e;
}
if (a > b)
{
d = a;
a = b;
b = d;
}
if (f > g)
{
d = f;
f = g;
g = d;
}
switch (mode)
{
case 0:
printf("%d/%d + %d/%d =", a, b, f, g);
result = a/b + f/g;
break;
case 1:
p = (float)a / (float)b;
q = (float)f / (float)g;
if (p < q)
{
d = a;
a = f;
f = d;
d = b;
b = g;
g = d;
}
printf("%d/%d - %d/%d =", a,b,f,g);
result = a/b - f/g;
break;
case 2:printf("%d/%d * %d/%d =", a, b, f, g);
result = (a/b) * (f/g);
break;
case 3:
while (f == 0)
{
f = rand() % 100;
}
printf("%d/%d / %d/%d =", a, b, f, g);
result = (a/b) / (f/g);
break;
default:
printf("未知错误!\n");
break;
}
}
scanf("%d", &c); //输入答案
if(c == result) //与正确答案一致
{
score+= 100.0/m; //加分 (修改)
printf("正确!\n\n");
}
else
{
printf("错误!正确答案为%d\n\n",result); //错
}
}
printf("你的得分是: %0.1f\n\n\n", score);//显示得分
time(&t2);
Sleep(1000);
printf("答题所用时间为:%d:%d分钟\n",(t2-t1)/60,(t2-t1)%60);
}
void menu()
{
int x;
printf("请选择答题方式:1、线下答题 2、线上答题\n"); //增加选择页面
scanf("%d",&x);
switch(x)
{
case 1:
offline();
break;
case 2:
online();
break;
default:
printf("输入错误!");
break;
}
}