[C语言]加减乘除训练系统

程序目的

用户进入程序,可根据程序提示选择加减乘除中的一个选项,程序根据用户所选类型自动生成两个数进行测试,用户输入答案。若答案正确,则计次并给予提示正确次数;若答案错误,则提示正确答案。完成后清除刚才题目,用户进行下一轮选择。

大致流程图如下:

此文章只详细讲解较难部分。

程序目的

程序说明

菜单

判断选项

 生成约束

产生数字

符合约束

 答案计算

显示算式

 核实答案及其之后操作

整体代码


程序说明

菜单

菜单就是简单的输出函数即可,为了美观可适当加入\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;	
}
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Traveler·玖安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值