程序目的
用户进入程序,可根据程序提示选择加减乘除中的一个选项,程序根据用户所选类型自动生成两个数进行测试,用户输入答案。若答案正确,则计次并给予提示正确次数;若答案错误,则提示正确答案。完成后清除刚才题目,用户进行下一轮选择。
大致流程图如下:
此文章只详细讲解较难部分。
程序说明
菜单
菜单就是简单的输出函数即可,为了美观可适当加入\t、\n及星号(*)
判断选项
按照要求,选项0代表退出,1、2、3、4分别代表加、减、乘、除法。若用户输入非0,1,2,3,4的数字,则提示让用户重新输入选项并让用户重新输入选项再次进行判断。这里只需要使用while就行了,用个if进行判断,符合条件退出循环即可。此功能代码片段如下:
while(1)
{
Pr(); //此为菜单输出函数,未定义不可直接使用,后有介绍
Sc(); //此为选项输出函数,未定义不可直接使用,后有介绍
scanf("%d",&choice);
if(choice<0||choice>4) //即非0,1,2,3,4
{
printf("请重新输入正确选项!");
sleep(500); //延时0.5s,未定义不可直接使用,后有介绍
system("CLS"); //清屏
}
else
break; //若为0,1,2,3,4跳出循环
}
生成约束
加法和乘法对生成的数字没有任何要求,只有减法和除法有。减法:被减数不能小于减数;除法:除数不能为0。此处需要根据选项来进行判断,故此处使用了一个自定义函数,先让返回参数赋值为0,如果有不符合条件的随机数产生,则令返回值为1。这里返回值为1是有原因的:后面判断产生数字是否合乎约束时,会使用到do-while语句,如果符合条件,那么返回值为0,do-while接收到的条件为0,则不会进行第二次赋值,直接进行计算步骤;反之则进行第二次赋值并进行第二次判断,如此进行下去,直到返回值为0为止。此处功能代码片段如下:
int pb(float a,float b,int choice)
{
int x=0;
if(choice==2)
{
if(a<b) //若是减法,被减数比减数小
x=1; //令返回值为1
}
else if(choice==4)
{
if(b==0) //若是除法,除数为0
x=1; //令返回值为1
}
return x; //返回x至主函数
}
产生数字
数字的产生用的一个简单的随机赋值函数rand,子函数代码如下:
int Fz()
{
int a,b;
static int c=0; //定义静态变量c 静态变量仅第一次使用时会执行赋值
srand((int)time(0)); //初始化
a=rand()%10;
b=rand()%10;
c++;
if(c%2==0)
return a; //这里是如果c为偶数,则返还a,否则返还b
else //因为c为静态变量,所以只要不是重新使用Fz()函数,c都会一直加下去
return b; //这样返还a后下一次必反还b
}
关于静态变量,可查阅相关文章,作者对此了解尚浅,不便做过多解释。
符合约束
上边已产生两个数字,接下来则应该根据方才产生的约束判断两个数字是否符合约束条件,如果不符合,令其重新生成两个新的随机数。此处可用do-while语句解决(此处我的程序不可使用while语句)在程序代码里有相应解释。子函数代码如下:
int pb(float a,float b,int choice)
{ //经过分析,只有在选项为2或4的时候有相应约束
int x=0; //所以只需要在选项为2或4时进行相应判断即可
if(choice==2)
{
if(a<b) //选项为2,代表减法,要求被减数大于除数,程序里,a在运算符前,为被减数
x=1;
}
else if(choice==4)
{
if(b==0) //选项为4,代表除法,要求除数不能为0,程序里b在运算符后,为除数
x=1;
}
return x;
}
产生数字和符合约束的整体代码如下:
do{
a=Fz();b=Fz();
}while(pb(a,b,choice));
/*
因为Fz里面的c为静态变量,c不会因为重新使用Fz而被重新赋值,除非重启所有程序,否则其会按照
0,1,2,3,4……这个顺序一直加下去。do里面有两个Fz,所以它始终可以把产生的第一个数给a,第二
个数给b
*/
/*
这里为什么用do-while而不用while:首先,while里面的a,b隶属于主函数里面的a,b,而while的运
行是先进行判断再执行循环体,这样的话就会导致a,b还没有初始值就被引用来进行判断,程序在运行时
便会出现问题;而do-while是先执行一次循环体再进行判断,执行一次循环体后,a与b都有了相应的值,
此时再拿去进行判断就不会出现问题
*/
答案计算
这一步在流程图里没画出来,但这一步必不可少。我将其安放在符合约束之后,即只要符合约束便直接进行运算,将正确答案存储在主函数的c内。子函数代码如下:
float count(float x,float y,int z)
{
float c;
if(z==0)
exit(0);
if(z==1)
c=pltr(x,y);
if(z==2)
c=sutr(x,y);
if(z==3)
c=mutr(x,y);
if(z==4)
c=ditr(x,y);
return c;
}
float pltr(float x,float y) //加
{
float z;
z=x+y;
return z;
}
float sutr(float x,float y) //减
{
float z;
z=x-y;
return z;
}
float mutr(float x,float y) //乘
{
float z;
z=x*y;
return z;
}
float ditr(float x,float y) //除
{
float z;
z=(int)(((x*1.0)/y+0.005)*100)/100.0; //此步为四舍五入保留两位小数,题中直接给出
return z; //暂不明白其原理
}
显示算式
这个应该不需要多说,子函数代码如下:
void Gs(float x,float y,int z)
{
if(z==1)
printf("%.0f+%.0f=",x,y);
if(z==2)
printf("%.0f-%.0f=",x,y);
if(z==3)
printf("%.0f×%.0f=",x,y);
if(z==4)
printf("%.0f÷%.0f=",x,y);
} //%.0f代表浮点型,保留0位小数,类似用法还有%.2f,表示浮点型保留两位小数
核实答案及其之后操作
这个直接用if语句则能完成。清屏操作涉及的头文件为:<stdlib.h>和延时程序涉及的头文件为:<time.h>。由于作者了解较少,具体使用方法可参考其他文章。
整体代码
#include<stdio.h>
#include<time.h>
#include<conio.h>
#include<stdlib.h>
void Pr();
int sleep(unsigned long x); //休眠(延时)语句
float pltr(float x,float y); //加
float sutr(float x,float y); //减
float mutr(float x,float y); //乘
float ditr(float x,float y); //除
float count(float x,float y,int z); //计算正确答案
int Fz(); //初始赋值
int pb(float a,float b,int choice); //赋值判别,返回1需重新赋值
void Sc(); //输出
void Gs(float x,float y,int z); //公式输出
void Jg(float c,int z); //结果输出
int main()
{
int n=0,choice;
float a,b,c,d=0; //c为正确答案,d为用户输入答案
while(1){
while(1)
{
Pr();
Sc();
scanf("%d",&choice);
if(choice<0||choice>4)
{
printf("请重新输入正确选项!");
sleep(500);
system("CLS");
}
else
break;
}
do{
a=Fz();b=Fz();
}while(pb(a,b,choice));
c=count(a,b,choice);
printf("\t\t\t");
Gs(a,b,choice);
scanf("%f",&d);
if(c==d)
{
n++;
printf("\n\t\t\t恭喜你回答正确!");
printf("\n\t\t\t你已经回答正确%d道。",n);
}
else
{
printf("\n\t\t\t很遗憾你回答错误!");
printf("\n\t\t\t正确答案为:");
Gs(a,b,choice);Jg(c,choice);
}
sleep(1000);
system("CLS");
}
}
void Pr()
{
printf("\t\t\t\t\t\t欢迎进入训练系统\n");
printf("\t\t\t\t*************************");
printf("******************************\n");
printf("\t\t\t\t\t0、退出\t1、加法\t2、减法\t3、乘法\t4、除法");
printf("\n\t\t\t\t");
for(int i=0;i<55;i++)
printf("*");
}
int Fz()
{
int a,b;
static int c=0;
srand((int)time(0));
a=rand()%10;
b=rand()%10;
c++;
if(c%2==0)
return a;
else
return b;
}
int pb(float a,float b,int choice)
{
int x=0;
if(choice==2)
{
if(a<b)
x=1;
}
else if(choice==4)
{
if(b==0)
x=1;
}
return x;
}
void Sc()
{
printf("\n\t\t\t\t\t请输入选项:");
}
float count(float x,float y,int z)
{
float c;
if(z==0)
exit(0);
if(z==1)
c=pltr(x,y);
if(z==2)
c=sutr(x,y);
if(z==3)
c=mutr(x,y);
if(z==4)
c=ditr(x,y);
return c;
}
int sleep(unsigned long x)
{
clock_t start=clock();
clock_t end;
do
{
if ((end=clock())==(clock_t)-1)
{
return 0;
}
} while(1000*(end-start)/CLOCKS_PER_SEC<x);
return 1;
}
void Gs(float x,float y,int z)
{
if(z==1)
printf("%.0f+%.0f=",x,y);
if(z==2)
printf("%.0f-%.0f=",x,y);
if(z==3)
printf("%.0f×%.0f=",x,y);
if(z==4)
printf("%.0f÷%.0f=",x,y);
}
void Jg(float c,int z)
{
if(z==4)
printf("%.2f",c);
else
printf("%.0f",c);
}
float pltr(float x,float y)
{
float z;
z=x+y;
return z;
}
float sutr(float x,float y)
{
float z;
z=x-y;
return z;
}
float mutr(float x,float y)
{
float z;
z=x*y;
return z;
}
float ditr(float x,float y)
{
float z;
z=(int)(((x*1.0)/y+0.005)*100)/100.0;
return z;
}