C语言博客作业03--函数

0.展示PTA总分

1.本章学习总结

1.1 学习内容总结

函数的作用

简化主函数,让代码更具有可读性,更简洁。因为一个函数可以实现某个功能而不被主函数限制,所以函数可以在其他程序上使用,具有高度的灵活性。

函数的结构

函数由首部和函数体构成。首部用来声明函数类型、定义实参。函数体用来实现函数功能。

函数的形参与实参

形参与实参类型必须一致。实参只会将数值传给形参,自身不会变化。

局部变量、全局变量、静态变量

局部变量只在定义它的函数内有效,但是在函数返回后失效。
全局变量在整个程序内有效。
静态变量未对其赋初值时,系统自动赋值0;每次静态变量被改变后,它的新值保存下来。

1.2 本章学习体会

函数的使用让原本繁琐、冗杂、重复的工作得以简化,同时也让我知道了结构化程序设计思想,让我对一个程序的设计有了更深入的认识。

代码量统计:1034行(每个程序减去两行大括号)

2. 综合作业—小学生口算表达式自动生成系统

本次作业的函数关系图

3.函数功能及全局变量介绍

3.1.全局变量

static int a[5];//a[4]用于存放答案
	int flag = 0;//用于返回上一级的中转变量
	int i;//循环用的变量
	int n;//题目数
	int j=0;//已做题目数
	int answer;//用户答案
	int ture = 0;//正确题目数
	double accuracy;//正确率
	int g;//年级
	int c;//答题结束后,用户的选择
	srand(time(0));//随机数函数

3.2.ListMenu()函数

//说明
	printf("欢迎使用小学生口算表达式自动生成系统,本系统适用于一至三年级学生。\n");
	printf("本程序保证所有答案均不为负数,所以输入-1可以返回上一级,但是在本级所做任何操作清零。\n");
	printf("年级选择规则如下:\n");
	printf("1.选择1、2、3年级为覆盖型出题,即二年级包含一年级题目,三年级包含一、二年级题目。\n");
	printf("2.选择4、5为独立性出题,即只出二、三年级对应难度的题目。\n\n");

3.3. 其它函数

void problem(int a[],int g)//出题
{
	int x;//题目类型
	int c1;
	int c2;

	switch (g)
	{
	case 1:x = rand() % 6 + 1;break;
	case 2:x = rand() % 16 + 1; break;
	case 3:x = rand() % 23 + 1;break;
	case 4:x = 7 + rand() % 10; break;
	case 5:x = 17 + rand() % 7; break;
	}
	c1 = rand() % 2;
	c2 = rand() % 2;
	switch (x)
	{
		//一年级题目
	case 1://20以内加减
		a[1] = rand() % 20 + 1;
		a[2] = rand() % 20 + 1;
		swap(a);
		type1(a, c1);
		break;
	case 2://20以内填括号
		a[1] = rand() % 20 + 1;
		a[2] = rand() % 20 + 1;
		swap(a);
		if (c1 == 0)
		{
			printf("%d+?=%d,?=", a[2], a[1]);
			a[4] = a[1] - a[2];
		}
		else
		{
			printf("%d-?=%d,?=", a[1], a[2]);
			a[4] = a[1] - a[2];
		}
		break;
	case 3://整十加减一位数or两位数加减一位数
		a[1] = (rand() % 9 + 1) * 10 + rand() % 10;
		a[2] = rand() % 9 + 1;
		type1(a, c1);
		break;
	case 4://整十加减整十
		a[1] = (rand() % 9 + 1) * 10;
		a[2] = (rand() % 9 + 1) * 10;
		swap(a);
		type1(a, c1);
		break;
	case 5://两位数加减整十
		a[1] = (rand() % 9 + 1) * 10 + rand() % 10;
		a[2] = rand() % (a[1] / 10) * 10;
		type1(a, c1);
		break;
	case 6://100以内三位数连续加减
		while (1)
		{
			a[1] = (rand() % 9 + 1) * 10 + rand() % 10;
			a[2] = (rand() % 9 + 1) * 10 + rand() % 10;
			a[3] = (rand() % 9 + 1) * 10 + rand() % 10;
			if (c1 == 0 && c2 == 0)//a+b+c
			{
				printf("%d+%d+%d=", a[1], a[2], a[3]);
				a[4] = a[1] + a[2] + a[3];
				break;
			}
			if (c1 == 0 && c2 == 1)//a+b-c
			{
				a[4] = a[1] + a[2] - a[3];
				if (a[4] < 0)					continue;
				printf("%d+%d-%d=", a[1], a[2], a[3]);
				break;
			}
			if (c1 == 1 && c2 == 0)//a-b+c
			{
				a[4] = a[1] - a[2] + a[3];
				if (a[4] < 0)					continue;
				printf("%d-%d+%d=", a[1], a[2], a[3]);
				break;
			}
			if (c1 == 1 && c2 == 1)//a-b-c
			{
				a[4] = a[1] - a[2] - a[3];
				if (a[4] < 0)					continue;
				printf("%d-%d-%d=", a[1], a[2], a[3]);
				break;
			}
		}
		break;
		//二年级题目
	case 7://两位数加减两位数or整十数减两位数
		a[1] = (rand() % 9 + 1) * 10 + rand() % 10;
		a[2] = (rand() % 9 + 1) * 10 + rand() % 10;
		swap(a);
		type1(a, c1);
		break;
	case 8://九九乘法or除法
		a[1] = rand() % 9 + 1;
		a[2] = rand() % 8 + 2;
		a[3] = a[1] * a[2];
		if (c1 == 0)
		{
			type4(a);
		}
		else
		{
			printf("%d/%d=", a[3], a[1]);
			a[4] = a[2];
		}
		break;
	case 9://整千加减法(和在一万内)
		if (c1 == 0)
		{
			a[1] = (rand() % 5 + 1) * 1000;
			a[2] = (rand() % 4 + 1) * 1000;
			printf("%d+%d=", a[1], a[2]);
			a[4] = a[1] + a[2];
		}
		else
		{
			a[1] = (rand() % 9 + 1) * 1000;
			a[2] = (rand() % 8 + 1) * 1000;
			printf("%d-%d=", a[1], a[2]);
			a[4] = a[1] - a[2];
		}
		break;
	case 10://整十加整十(进位)or整十减整十(退位)
		type2(a, c1, 1);
		break;
	case 11://整百加整百(进位)or整百减整百(退位)
		type2(a, c1, 10);
		break;
	case 12://尾数为0三位数加法(和在1000内)or尾数为0的减法
		switch (c1)
		{
		case 0:
			while (1)
			{
				a[1] = (rand() % 99 + 1) * 10;
				a[2] = (rand() % 99 + 1) * 10;
				if (a[1] + a[2] < 1000)
				{
					printf("%d+%d=", a[1], a[2]);
					a[4] = a[1] + a[2];
					break;
				}
				else { continue; }
			}
			break;
		case 1:
			while (1)
			{
				a[1] = (rand() % 99 + 1) * 10;
				a[2] = (rand() % 99 + 1) * 10;
				swap(a);
				printf("%d-%d=", a[1], a[2]);
				a[4] = a[1] - a[2];
				break;
			}
			break;
		}
		break;
	case 13://十以内整数连乘
		a[1] = (rand() % 8 + 2);
		a[2] = (rand() % 8 + 2);
		a[3] = (rand() % 8 + 2);
		printf("%d*%d*%d=", a[1], a[2], a[3]);
		a[4] = a[1] * a[2] * a[3];
		break;
	case 14://十以内整数连除
		a[1] = (rand() % 8 + 2);
		a[2] = (rand() % 8 + 2);
		a[3] = a[1] * a[2] * (rand() % 9 + 1);
		printf("%d/%d/%d=", a[3], a[1], a[2]);
		a[4] = a[3] / a[1] / a[2];
		break;
	case 15://10以内整数乘除混算
		a[1] = (rand() % 8 + 2);
		a[2] = (rand() % 8 + 2);
		a[3] = a[1] * (rand() % 8 + 2);
		printf("%d/%d*%d=", a[3], a[1], a[2]);
		a[4] = a[3] / a[1] * a[2];
		break;
	case 16://含有小括号的混合运算
		while (1)
		{
			a[1] = (rand() % 99 + 1);
			a[2] = (rand() % 99 + 1);
			a[3] = rand() % 8 + 2;
			swap(a);
			if (c1 == 0)
			{
				printf("(%d-%d)*%d=", a[1], a[2], a[3]);
				a[4] = (a[1] - a[2]) * a[3];
				break;
			}
			else
			{
				if ((a[1] - a[2]) % a[3] == 0)
				{
					printf("(%d-%d)/%d=", a[1], a[2], a[3]);
					a[4] = (a[1] - a[2]) / a[3];
					break;
				}
				else
				{
					continue;
				}
			}
		}
		break;
		//三年级题目
	case 17://三位数加减法
		a[1] = (rand() % 999 + 1);
		a[2] = (rand() % 999 + 1);
		swap(a);
		type1(a, c1);
		break;
	case 18://一位数乘以两位数or两位数乘以两位数
		a[1] = (rand() % 99 + 1);
		a[2] = rand() % 89 + 11;
		type4(a);
		break;
	case 19://三位数乘以三位数or两位数乘以三位数or一位数乘以三位数
		a[1] = (rand() % 999 + 1);
		a[2] = rand() % 899 + 101;
		type4(a);
		break;
	case 20://万以内加减法
		a[1] = rand() % 9999 + 1;
		a[2] = rand() % 9999 + 1;
		swap(a);
		type1(a, c1);
		break;
	case 21://两位数除以一位数
		a[1] = rand() % 8 + 2;
		a[2] = a[1]*(rand() % 9 + 1);
		type3(a, 1);
		break;
	case 22://三位数除以一位数
		a[1] = rand() % 8 + 2;
		a[2] = a[1] * (rand() % 99 + 1);
		type3(a, 10);
		break;
	case 23://百以内三数连减
		a[1] = rand() % 99 + 1;
		a[2] = rand() % 99 + 1;
		a[3] = a[1]+a[2]+(rand() % 9 + 1);
		printf("%d-%d-%d=", a[3], a[1], a[2]);
		a[4] = a[3] - a[1] - a[2];
		break;
	}
}

void swap(int a[])//防止答案为负数
{
	int t;
	if (a[1] < a[2])
	{
		t = a[1];
		a[1] = a[2];
		a[2] = t;
	}
}

void type1(int a[],int c1)//a[1]加减a[2]
{
	if (c1 == 0)
	{
		printf("%d+%d=", a[1], a[2]);
		a[4] = a[1] + a[2];
	}
	else
	{
		printf("%d-%d=", a[1], a[2]);
		a[4] = a[1] - a[2];
	}
}

void type2(int a[], int c1, int n)//整十(百)加整十(百) (进位)or整十(百)减整十(百) (退位)
{
	switch (c1)
	{
	case 0:
		while (1)
		{
			a[1] = (rand() % 9 + 1) * 10 * n;
			a[2] = (rand() % 9 + 1) * 10 * n;
			if (a[1] + a[2] >= 100 * n)
			{
				printf("%d+%d=", a[1], a[2]);
				a[4] = a[1] + a[2];
				break;
			}
			else { continue; }
		}
		break;
	case 1:
		while (1)
		{
			a[1] = (rand() % 9 + 1) * 10 * n + 100 * n;
			a[2] = (rand() % 9 + 1) * 10 * n;
			if (a[1] - a[2] < 100 * n)
			{
				printf("%d-%d=", a[1], a[2]);
				a[4] = a[1] - a[2];
				break;
			}
			else { continue; }
		}
	}
}

void type3(int a[], int n)//两(三)位数除以一位数
{
	while (a[2] < 10*n)
	{
		a[2] = a[2] * 2;
	}
	printf("%d/%d=", a[2], a[1]);
	a[4] = a[2] / a[1];
}

void type4(int a[])//a[1]*a[2]
{
	printf("%d*%d=", a[1], a[2]);
	a[4] = a[1] * a[2];
}

4.运行结果截图,测试用例。

一年级

二年级

三年级

5. 调试碰到问题及解决办法

Q1:当用户作答0题退出时,正确率计算异常。
A1:使用if语句让此情况下正确率直接赋值为0。

Q2:答案出现负数。
A2:对数据进行处理使得答案为正数,个别数据难以处理直接令其重新赋值。

6.大作业总结

在编写这个程序的过程中,让我知道了做题目和写程序的不同,一个程序除了本身功能要齐全外,还需要与用户进行沟通。因为这个程序功能较多,所以需要较大的思考量,对于自己的编程能力也有一个很大的提高。在年级选择的基础上,我添加了4、5这两个选项,用来专门出二、三年级的题目。

posted @ 2019-11-03 20:58  极仙  阅读(281)  评论(1编辑  收藏  举报