(1)项目来源
从网络下载的 C 语言版 “学生成绩管理” 雏形(代码存在:未做输入校验、内存泄漏、功能单一、代码耦合度高的问题)。
点击查看代码
#include <iostream>
using namespace std;
int main() {
int n;
int score[100]; // 固定数组大小,限制最多100人
cout << "输入学生人数:";
cin >> n; // 无输入校验,输入非数字会导致程序崩溃
for (int i = 0; i < n; i++) {
cout << "输入第" << i+1 << "个学生成绩:";
cin >> score[i]; // 无成绩范围校验,可输入负数或超过100的数
}
int sum = 0;
for (int i = 0; i < n; i++) {
sum += score[i];
}
double avg = sum / n; // 整数除法,结果精度丢失(如sum=175, n=2 → avg=87而非87.5)
cout << "平均分:" << avg << endl;
return 0;
}
(2)运行环境 & 运行结果截图
运行环境:Windows 11 + Visual Studio 2022
原始程序缺陷:


1.输入非数字成绩时,程序崩溃(未处理输入流异常)。
2.仅支持单门课成绩,无法计算平均分。
3.代码无注释,变量命名混乱(如a、b),难以维护。
(3)主要问题列表 & 重构思路
输入非法字符导致程序崩溃:增加cin输入校验,清除错误状态、清空输入缓冲区;
功能单一,仅输出成绩:扩展功能:计算平均分、查询最高分 / 最低分;
代码耦合度高(所有逻辑写在 main):拆分函数:inputScore()、calcAverage()、printResult();
无异常处理:增加边界判断(成绩 0-100 强制校验)。
(4)新代码
点击查看代码
#include <iostream>
#include <vector>
#include <iomanip>
#include <limits>
using namespace std;
// 函数声明:封装功能,降低耦合
void inputScores(vector<int>& scores);
double calculateAverage(const vector<int>& scores);
int getMaxScore(const vector<int>& scores);
int getMinScore(const vector<int>& scores);
void printResult(const vector<int>& scores);
int main() {
vector<int> scores; // 使用vector动态存储,避免固定数组大小限制
cout << "===== 学生成绩管理系统(重构版)=====" << endl;
// 1. 输入成绩(含校验)
inputScores(scores);
// 2. 展示结果
printResult(scores);
system("pause");
return 0;
}
// 输入成绩:增加输入合法性校验
void inputScores(vector<int>& scores) {
int n;
cout << "请输入学生人数:";
while (!(cin >> n) || n <= 0) {
cin.clear(); // 清除错误状态
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 清空缓冲区
cout << "输入无效!请输入正整数:";
}
for (int i = 0; i < n; i++) {
int score;
cout << "请输入第" << i + 1 << "个学生的成绩(0-100):";
while (!(cin >> score) || score < 0 || score > 100) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "成绩非法!请输入0-100的整数:";
}
scores.push_back(score);
}
}
// 计算平均分
double calculateAverage(const vector<int>& scores) {
if (scores.empty()) return 0.0;
int sum = 0;
for (int s : scores) sum += s;
return static_cast<double>(sum) / scores.size();
}
// 获取最高分
int getMaxScore(const vector<int>& scores) {
if (scores.empty()) return 0;
int max = scores[0];
for (int s : scores) {
if (s > max) max = s;
}
return max;
}
// 获取最低分
int getMinScore(const vector<int>& scores) {
if (scores.empty()) return 0;
int min = scores[0];
for (int s : scores) {
if (s < min) min = s;
}
return min;
}
// 打印结果
void printResult(const vector<int>& scores) {
cout << "\n===== 成绩统计结果 =====" << endl;
cout << "学生成绩列表:";
for (int s : scores) {
cout << s << " ";
}
cout << endl;
cout << "最高分:" << getMaxScore(scores) << endl;
cout << "最低分:" << getMinScore(scores) << endl;
cout << "平均分:" << fixed << setprecision(2) << calculateAverage(scores) << endl;
}
(5)重构后的测试截图



(6)总结:难点 & 逆向工程思考
- 核心难点:
◦ C++ 输入流异常处理(cin.clear() + cin.ignore()):解决了原始程序 “输入崩溃” 的致命缺陷。
◦ 代码解耦与函数拆分:将单一的main函数拆分为多个功能函数,提升了代码可读性和可维护性。 - 逆向工程思考:
◦ 逆向分析旧代码时,首先要梳理逻辑链路,识别 “坏味道”(如变量命名不规范、无校验、硬编码)。
◦ 重构的核心是“保持功能不变,优化结构”:保留原有的成绩录入核心逻辑,仅优化代码质量和功能完整性,这也是软件工程中 “迭代优化” 的核心思想。
浙公网安备 33010602011771号