“C语言程序:小学生算术自测”二次开发

(1)程序来源
该程序来源于室友大一下C语言期末大作业

(2)运行环境+运行结果截图
使用VS2022版本编译器完成代码运行

1

2

3

点击查看代码
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
int randomNumber(int w);
char randomSymbol();



int main()
{
	int n, w, num;
	printf("欢迎来到奶龙的口算乐园,我是奶龙!\n");
	int count = 0;
	char continueFlag;
	do
	{
		printf("您想要练习几位数以内的口算?\n");
		scanf("%d", &w);
		printf("您想要练习多少道题?\n");
		scanf("%d", &num);
		printf("开始练习:\n");
		////////////////////////////////////////////////////
		int count = 0;
		for (int i = 1; i <= num; i++)
		{
			char c = randomSymbol();
			int num1 = randomNumber(w);
			int num2 = randomNumber(w);
			printf("%d %c %d = ", num1, c, num2);
			////////////////////////////////////////////////////
			int answer, REanswer;
			if (c == '+')
				REanswer = num1 + num2;
			else REanswer = num1 - num2;
			////////////////////////////////////////////////////
			scanf("%d", &answer);
			if (answer == REanswer)
			{
				printf("		√\n");
				count++;
			}
			else printf("		×\n");
		}
		printf("本轮结束,答对%d题,", count);
		float c = (float)count;
		float numm = (float)num;
		float result = c / numm;
		if (result >= 0.9)
			printf("优秀\n");
		else if (result < 0.9 && result >= 0.7)
			printf("良好\n");
		else if (result < 0.7 && result >= 0.5)
			printf("不错\n");
		else
			printf("菜就多练\n\n\n");
		printf("还要继续练习吗?(y/n):\n");
		scanf(" %c", &continueFlag);
	} while (continueFlag == 'y');
	printf("\n\n结束练习\n");
	return 0;
}


int randomNumber(int w)//生成0=max以内的随机数
{
	int a;
	static int firstCall = 1;
	if (firstCall)
	{
		srand((unsigned int)time(NULL));
		firstCall = 0;
	}
	int digit = pow(10, w);
	a = rand() % (digit + 1);
	return a;
}


char randomSymbol()
{
	srand((unsigned int)time(NULL));
	int a = rand() % (1 - 0 + 1) + 0;
	if (a == 0)
		return '+';
	else return '-';
}

(3)主要问题与改进思路
整体程序较为完整,主要有以下问题。
1.程序主要针对小学生群体,所以在减法中不会出现负数结果,例如“5-8=-3”的结果。
2.随机数范围错误:randomNumber 中 pow(10, w) 返回浮点数,直接用于取模可能有精度问题
3.输入合法性未校验:用户输入非数字时,程序会进入死循环或异常状态。
改进思路:解决上述3个主要问题并对整个程序的细节方面进行优化,如:增加答题准确率功能。

(4)新代码
解决减法负数问题:

点击查看代码
char randomSymbol(int num1, int num2)
{
    int a = rand() % 2; // 0=+, 1=-
    if (a == 0)
    {
        return '+';
    }
    else
    {
        if (num1 < num2)
        {
            int temp = num1;
            num1 = num2;
            num2 = temp;
        }
        return '-';
    }
}

int num1 = randomNumber(w);
int num2 = randomNumber(w);
char c = randomSymbol(num1, num2); 

2.随机数问题

点击查看代码
int randomNumber(int w)
{
    static int firstCall = 1;
    if (firstCall)
    {
        srand((unsigned int)time(NULL));
        firstCall = 0;
    }
    int digit = 1;
    for (int i = 0; i < w; i++)
    {
        digit *= 10;
    }
    a = rand() % (digit + 1);
    return a;
}

3.输入字符校验

点击查看代码
int checkIntInput(int *input)
{
    while (getchar() != '\n'); 
    if (scanf("%d", input) != 1)
    {
        printf("输入错误!请输入数字!\n");
        while (getchar() != '\n');
        return 0;
    }
    return 1;
}
printf("您想要练习几位数以内的口算?\n");
while (!checkIntInput(&w) || w < 1 || w > 4) 
{
    printf("请输入1-4之间的数字!\n");
}
printf("您想要练习多少道题?\n");
while (!checkIntInput(&num) || num < 1 || num > 100)
{
    printf("请输入1-100之间的数字!\n");
}
printf("%d %c %d = ", num1, c, num2);
while (!checkIntInput(&answer))
{
    printf("答案输入错误!请输入数字:");
}

4.添加答题准确率

点击查看代码
float accuracy = result * 100; // 转换为百分比
printf("本轮结束,答对%d题,准确率:%.2f%%\n", count, accuracy); // 显示准确率

5.优化随机数种子

点击查看代码
int main()
{
    srand((unsigned int)time(NULL)); 
    int n, w, num;
}

(5)重构的软件测试截图

4

5

6

(6)总结
核心难点主要有三处:一是随机数相关的修复,原本用 pow 计算位数会有浮点数精度问题,得换成整数循环来算,而且重复初始化随机数种子会导致符号不随机,要调整成只在主函数开头初始化一次;二是减法防负数的处理,得反过来想,不能先随机符号再生成数字,而是先出数字,再根据两个数的大小调整符号,甚至交换数值,确保减法结果非负;三是输入校验,要考虑到用户可能输非数字的情况,花了不少时间。整个优化过程需要结合小学生口算的实际场景倒推,既要保证代码不出错,又要符合口算题的实际使用需求。

posted @ 2026-03-09 19:34  卜渴鲤郁  阅读(22)  评论(0)    收藏  举报