一、题目描述
编写一个C语言程序,实现班级学生成绩的简易统计功能,具体需求如下:
第一步:输入班级总人数,人数范围限制在1~50(超出范围需提示重新输入);
第二步:依次输入每个学生的单科成绩,成绩范围限制在0~100(超出范围需提示重新输入);
第三步:程序自动计算并输出3个核心统计结果:全班平均分、最高分、最低分;
第四步:额外统计并输出:成绩大于等于80分的优秀学生人数。
二、题目要求
为了贴合初学者的学习重点,这道题设置了4个明确要求,避免大家写“野代码”,培养良好的编程习惯:
必须使用循环输入成绩,使用数组存储所有学生的成绩(禁止直接用变量逐个存储,锻炼数组的基础用法);
所有计算逻辑必须独立封装成函数(比如求平均分、求最高分、求最低分、统计优秀人数,各写一个函数),禁止把所有代码写在main函数里;
输入数据需做简单合法性校验,无论是班级人数还是学生成绩,超出规定范围时,提示用户“输入非法,请重新输入”,直到输入正确为止;
输出结果中,平均分需保留1位小数,其他结果(最高分、最低分、优秀人数)输出整数即可。
三、输入输出示例
为了让大家更直观地理解需求,这里给出两个输入输出示例,包括正常输入和非法输入的校验场景,大家可以对照示例检验自己的代码是否正确。
示例1:正常输入(无非法数据)
输入:
3 85 92 76
输出:
全班平均分:84.3 最高分:92 最低分:76 80分及以上优秀人数:2
示例2:非法数据校验(输入错误后重新输入)
输入:
0 # 非法人数(小于1),提示重新输入 5 105 # 非法成绩(大于100),提示重新输入 88 79 95 66 82
输出:
全班平均分:82.0 最高分:95 最低分:66 80分及以上优秀人数:3
四、解题思路引导(初学者必看)
如果刚开始拿到题目不知道从哪里下手,可以按照这个步骤逐步拆解,降低难度:
第一步:先完成输入功能——先输入班级人数,做合法性校验(循环判断,直到输入1~50之间的数);再输入每个学生的成绩,存入数组,同样做合法性校验。
第二步:封装函数——根据需求,至少封装4个函数:
求平均分:接收数组和数组长度,计算所有元素的平均值,返回double类型;
求最高分:接收数组和数组长度,遍历数组找到最大值,返回int类型;
求最低分:接收数组和数组长度,遍历数组找到最小值,返回int类型;
统计优秀人数:接收数组和数组长度,遍历数组,统计大于等于80的元素个数,返回int类型。
第三步:调用函数,输出结果——在main函数中调用上述4个函数,获取统计结果,按照要求的格式输出(平均分保留1位小数,用printf("%.1f", 平均分)实现)。
五、完整参考代码
这里给出完整的参考代码,大家可以先自己尝试编写,遇到问题再对照参考,不要直接复制粘贴哦~ 代码中加入了详细注释,方便大家理解每一步的作用。
#include <stdio.h> // 函数声明(封装4个核心功能) // 求平均分 double getAverage(int score[], int n) { int sum = 0; for (int i = 0; i < n; i++) { sum += score[i]; } return (double)sum / n; // 强制转换为double,避免整数除法 } // 求最高分 int getMax(int score[], int n) { int max = score[0]; for (int i = 1; i < n; i++) { if (score[i] > max) { max = score[i]; } } return max; } // 求最低分 int getMin(int score[], int n) { int min = score[0]; for (int i = 1; i < n; i++) { if (score[i] < min) { min = score[i]; } } return min; } // 统计80分及以上优秀人数 int getExcellentCount(int score[], int n) { int count = 0; for (int i = 0; i < n; i++) { if (score[i] >= 80) { count++; } } return count; } int main() { int n; // 班级人数 int score[50]; // 存储成绩的数组,最大容量50 // 输入班级人数并校验 printf("请输入班级总人数(1~50):"); while (1) { scanf("%d", &n); if (n >= 1 && n <= 50) { break; // 输入合法,退出循环 } else { printf("输入非法,请重新输入班级总人数(1~50):"); } } // 输入学生成绩并校验 printf("请输入%d个学生的成绩(0~100):\n", n); for (int i = 0; i < n; i++) { printf("请输入第%d个学生的成绩:", i+1); while (1) { scanf("%d", &score[i]); if (score[i] >= 0 && score[i] <= 100) { break; // 成绩合法,退出循环 } else { printf("输入非法,请重新输入第%d个学生的成绩(0~100):", i+1); } } } // 调用函数,获取统计结果 double average = getAverage(score, n); int max = getMax(score, n); int min = getMin(score, n); int excellentCount = getExcellentCount(score, n); // 输出结果,平均分保留1位小数 printf("\n===== 班级成绩统计结果 =====\n"); printf("全班平均分:%.1f\n", average); printf("最高分:%d\n", max); printf("最低分:%d\n", min); printf("80分及以上优秀人数:%d\n", excellentCount); return 0; } }
六、易错点总结(避坑指南)
结合初学者的常见问题,这里总结3个易错点,大家编写代码时一定要注意:
易错点1:整数除法问题——求平均分的时候,sum和n都是int类型,如果直接写sum/n,会得到整数结果(比如85+92+76=253,253/3=84,而不是84.3),所以必须强制转换为double类型,即(double)sum / n。
易错点2:输入校验的循环逻辑——很多小伙伴会忘记“循环校验”,只判断一次输入是否合法,输入错误后程序就结束了。正确的做法是用while(1)循环,直到输入合法才break退出循环。
易错点3:数组下标越界——班级人数最多50人,所以数组定义为int score[50]即可,输入人数时已经限制在1~50,避免数组下标越界(比如n=51,score[50]就会越界)。