Console未输出预期结果:C++ 2D数组成绩计算程序故障排查
成绩计算程序修正:解决平均分输出0与高低分识别错误问题
问题核心
你遇到的两个关键问题:
- 平均分计算结果为0,未正确排除高低分并计算剩余3个分数的平均值
- 高低分始终锁定第一个输入的分数,遍历更新逻辑失效
修正后的完整代码
#include <iostream> #include <iomanip> #include <string> // 全局常量符合要求 const int NUM_STUDENTS = 2; // 可按需修改学生数量 const int NUM_TESTS = 5; // 函数声明 void getInput(std::string names[], int scores[][NUM_TESTS]); void findHiandLow(int scores[], int& high, int& low); double calculateAverage(int scores[], int high, int low); char getGrade(double average); void displayTable(std::string names[], int scores[][NUM_TESTS], double averages[], char grades[]); int main() { // 仅变量声明和函数调用,符合要求 std::string studentNames[NUM_STUDENTS]; int studentScores[NUM_STUDENTS][NUM_TESTS]; double studentAverages[NUM_STUDENTS]; char studentGrades[NUM_STUDENTS]; getInput(studentNames, studentScores); // 循环处理每个学生的高低分、平均分和等级 for (int i = 0; i < NUM_STUDENTS; i++) { int high, low; findHiandLow(studentScores[i], high, low); studentAverages[i] = calculateAverage(studentScores[i], high, low); studentGrades[i] = getGrade(studentAverages[i]); } displayTable(studentNames, studentScores, studentAverages, studentGrades); return 0; } // 读取学生姓名和测试分数 void getInput(std::string names[], int scores[][NUM_TESTS]) { for (int i = 0; i < NUM_STUDENTS; i++) { std::cout << "输入第" << i+1 << "个学生的姓名: "; std::cin >> names[i]; std::cout << "输入该学生的5个测试分数: "; for (int j = 0; j < NUM_TESTS; j++) { std::cin >> scores[i][j]; } } } // 找出单个学生的最高分和最低分 void findHiandLow(int scores[], int& high, int& low) { // 初始化高低分为第一个分数,遍历剩余分数更新 high = scores[0]; low = scores[0]; for (int i = 1; i < NUM_TESTS; i++) { if (scores[i] > high) high = scores[i]; if (scores[i] < low) low = scores[i]; } } // 计算去掉高低分后的平均分 double calculateAverage(int scores[], int high, int low) { int total = 0; int skipHigh = 1; int skipLow = 1; for (int i = 0; i < NUM_TESTS; i++) { // 仅跳过一次最高分和一次最低分(处理重复分数场景) if (scores[i] == high && skipHigh > 0) { skipHigh--; continue; } if (scores[i] == low && skipLow > 0) { skipLow--; continue; } total += scores[i]; } // 强制转为浮点数计算,避免整数除法导致的精度丢失或结果为0 return static_cast<double>(total) / 3; } // 根据平均分返回等级 char getGrade(double average) { if (average >= 90) return 'A'; else if (average >= 80) return 'B'; else if (average >= 70) return 'C'; else if (average >= 60) return 'D'; else return 'F'; } // 格式化表格输出 void displayTable(std::string names[], int scores[][NUM_TESTS], double averages[], char grades[]) { std::cout << "\n" << std::setw(15) << std::left << "学生姓名" << std::setw(25) << "测试分数" << std::setw(10) << "平均分" << std::setw(5) << "等级" << "\n"; std::cout << "-------------------------------------------------------------\n"; for (int i = 0; i < NUM_STUDENTS; i++) { std::cout << std::setw(15) << std::left << names[i]; // 输出5个测试分数 for (int j = 0; j < NUM_TESTS; j++) { std::cout << std::setw(5) << scores[i][j]; } std::cout << std::setw(10) << std::fixed << std::setprecision(2) << averages[i]; std::cout << std::setw(5) << grades[i] << "\n"; } }
关键修正点说明
- 高低分识别逻辑:
从第二个分数开始遍历对比,动态更新最高分和最低分,解决了之前只保留第一个输入分数的问题。 - 平均分计算修正:
- 加入计数变量
skipHigh和skipLow,确保仅跳过一次最高分和一次最低分(兼容存在重复高低分的场景) - 使用
static_cast<double>将总和转为浮点数,避免整数除法导致的结果为0或精度丢失
- 加入计数变量
- 表格格式化:
用std::left、std::setw、std::fixed和std::setprecision实现对齐的表格输出,符合格式要求 - 函数职责拆分:
所有数组遍历逻辑都封装在对应函数内,main函数仅做变量声明和调用,完全符合给定框架限制
测试验证
输入你提到的分数12、89、45、100、23时:
- 高低分正确识别为100和12
- 有效分数总和为89+45+23=157,平均分为157/3≈52.33,等级为F,与预期完全一致
内容的提问来源于stack exchange,提问作者SpudsMash3r
相关产品推荐
相关产品推荐

