C语言期中成绩计算程序部分函数返回值与预期不符排查
C语言期中成绩计算程序结果异常修复
问题描述
编写的C语言学生期中成绩计算程序,支持录入各考核项成绩,自动计算作业、课堂练习、实验活动、测验、考试的分项平均分,再按权重加权核算最终期中成绩,逻辑基于数组和自定义函数实现。运行后仅作业平均分、长测分、期中统考分输出正确,课堂练习平均分、实验活动平均分、课堂表现分、最终总评分均远高于预期值。
预期输出
STUDENT NUMBER: 1234 STUDENT NAME: HARRY COURSE: BETCPET YEAR: 1 ASSIGNMENT AVERAGE: 9.90 SEATWORK AVERAGE: 13.80 LAB ACTIVITIES AVERAGE: 24.00 QUIZZES AVERAGE: 18.40 LONG QUIZ: 29.40 CLASS STANDING: 57.30 MIDTERM EXAM GRADE: 39.60 MIDTERM GRADE: 96.30
实际错误输出
STUDENT NUMBER: 1234 STUDENT NAME: HARRY COURSE: BETCPET YEAR: 1 ASSIGNMENT AVERAGE: 9.90 SEATWORK AVERAGE: 36.15 LAB ACTIVITIES AVERAGE: 64.17 QUIZZES AVERAGE: 18.50 LONG QUIZ: 29.40 CLASS STANDING: 94.87 MIDTERM EXAM GRADE: 39.60 MIDTERM GRADE: 134.47
根因定位
问题全部出在自定义函数实现细节,和函数调用方式无关,核心问题有3个:
- 局部累加变量未初始化(核心原因)
所有计算分项平均分的函数中,用于存储成绩总和的sum变量是局部自动变量,定义时没有设置初始值0.0f。C语言中这类变量分配在栈上,不手动初始化的话初始值是栈内存中残留的随机垃圾值。第一个运行的assignment函数刚好碰到对应栈位置的残留值为0,所以计算结果正确;后续函数运行时栈已经被之前的逻辑写入了其他数据,sum初始就带有随机非0值,累加后结果自然偏大,这就是逻辑相同但结果不一致的根本原因。 - 输出参数写错
打印学生课程信息时,代码误将studentName作为课程字段的传入参数,会导致课程栏输出学生姓名而非录入的课程值。 - 冗余无效代码
代码声明了classStanding函数但从未实现,所有计算函数的形参完全没有被使用(函数内直接给形参重新赋值后返回,没有读取传入的实参值),属于冗余写法,虽然不影响运行结果但不符合编码规范。另外使用已废弃的不安全函数gets()读取字符串,且传入数组时额外加了取地址符&(数组名本身就是首元素地址,不需要额外取地址),存在内存越界风险。
修复方法
- 所有计算分项平均分的函数中,将
sum变量定义时初始化为0.0f,以seatwork函数为例,修改后代码如下:
float seatwork(float swAverage) { // 给sum设置初始值0,避免读取栈垃圾值 float sum = 0.0f, sw[TOTAL_SEATWORKS]; for (int i = 0; i < TOTAL_SEATWORKS; i++) { printf(" \t SEATWORK #%i SCORE: ", i + 1); scanf("%f", &sw[i]); sum += sw[i]; } swAverage = sum / TOTAL_SEATWORKS; swAverage = swAverage * 0.15; return swAverage; }
assignment、labActivity、quiz三个函数都要做相同的sum初始化修改。
- 修正课程输出的参数错误,将
printf("\n COURSE: %s", studentName);修改为printf("\n COURSE: %s", studentCourse); - 可选优化:删除未实现的
classStanding函数声明,去掉各计算函数无用的形参,将gets替换为更安全的fgets避免缓冲区溢出。
修复后验证
所有分项sum初始化后,累加计算的平均分将和预期一致,后续加权得到的课堂表现分、最终总评分也会匹配预期结果。
内容的提问来源于stack exchange,提问作者Liyanna
相关产品推荐
相关产品推荐

