原程式主要問題
- 排序邏輯錯誤:
sort() 使用選擇排序但索引處理錯誤,導致排名錯誤、重複或遺漏。
- 全域變數濫用:
sum, k, maxch... 皆為全域,耦合度高、難除錯。
- 輸入緩衝區殘留:
scanf_s 後 getchar() 處理換行不穩定,建議改用 fgets + sscanf。
- 查詢功能
switch 缺少 break:導致 case 貫穿,輸出混亂。
- 陣列大小硬編碼:
#define maxsize 5,擴充不便。
核心修正:排名排序重寫
void sort(Student* stu, int n) {
// 計算總分
for (int i = 0; i < n; i++) {
stu[i].sum = stu[i].chinese + stu[i].math + stu[i].computer + stu[i].english;
}
// 簡單選擇排序(降序)
for (int i = 0; i < n - 1; i++) {
int maxIdx = i;
for (int j = i + 1; j < n; j++) {
if (stu[j].sum > stu[maxIdx].sum) maxIdx = j;
}
if (maxIdx != i) {
Student tmp = stu[i];
stu[i] = stu[maxIdx];
stu[maxIdx] = tmp;
}
}
// 指派排名(同分同名次)
stu[0].rank = 1;
for (int i = 1; i < n; i++) {
if (stu[i].sum == stu[i-1].sum) stu[i].rank = stu[i-1].rank;
else stu[i].rank = i + 1;
}
}
重構建議
- 將學生資料封裝為結構體,功能模組化(輸入、統計、排序、查詢、輸出各自函式)。
- 使用動態陣列
realloc 或鏈表支援不定人數。
- 輸入驗證:分數 0-100、學號唯一、姓名非空。
- 選單迴圈改用
do-while,結構更清晰。
- 編譯器升級:VS 建議用
scanf + _CRT_SECURE_NO_WARNINGS,跨平台用標準 scanf。
原答案提供的修正片段
for(i=0;i=maxsum) { maxsum=sum[j]; k=j; }
}
stu[k].rank=x++; // 此邏輯仍有缺陷,建議採用上方完整重寫版
}