開發一個控制台程式,管理兩個班級 (人數可配置) 的單門課程成績,實現以下功能:
使用結構體綁定學號與成績,靜態數組存儲 (上限由宏定義),簡單高效:
#define MAX_CLASS_A 50
#define MAX_CLASS_B 50
typedef struct {
int id;
int score;
} Student;
Student classA[MAX_CLASS_A];
Student classB[MAX_CLASS_B];
int countA = 0, countB = 0;
void input_students(Student *cls, int *count, int max, const char *prompt) {
printf("%s (最多%d人,輸入學號 -1 結束):\n", prompt, max);
while (*count < max) {
int id, score;
printf("第 %d 位 - 學號 成績: ", *count + 1);
if (scanf("%d %d", &id, &score) != 2) {
while(getchar() != '\n'); printf("格式錯誤,重輸。\n"); continue;
}
if (id == -1) break;
if (id <= 0 || score < 0 || score > 100) {
printf("數據非法 (學號>0, 0<=成績<=100),重輸。\n"); continue;
}
cls[*count].id = id;
cls[*count].score = score;
(*count)++;
}
// 清理緩衝區
while(getchar() != '\n');
}
typedef struct {
float avg;
int max_score, max_id;
int min_score, min_id;
int pass_cnt;
float pass_rate;
} Stats;
Stats calc_stats(Student *cls, int count) {
Stats s = {0, -1, -1, 101, -1, 0, 0.0f};
if (count == 0) return s;
int sum = 0;
for (int i = 0; i < count; i++) {
sum += cls[i].score;
if (cls[i].score > s.max_score) { s.max_score = cls[i].score; s.max_id = cls[i].id; }
if (cls[i].score < s.min_score) { s.min_score = cls[i].score; s.min_id = cls[i].id; }
if (cls[i].score >= 60) s.pass_cnt++;
}
s.avg = (float)sum / count;
s.pass_rate = (float)s.pass_cnt / count * 100;
return s;
}
采用結構體整體交換,避免多字段獨立交換出錯:
void sort_desc(Student *cls, int count) {
for (int i = 0; i < count - 1; i++) {
for (int j = 0; j < count - 1 - i; j++) {
if (cls[j].score < cls[j+1].score) {
Student tmp = cls[j];
cls[j] = cls[j+1];
cls[j+1] = tmp;
}
}
}
}
void print_stats(const char *title, Stats s) {
printf("\n=== %s ===\n", title);
printf("平均分: %.2f\n", s.avg);
printf("最高分: %d (學號: %d)\n", s.max_score, s.max_id);
printf("最低分: %d (學號: %d)\n", s.min_score, s.min_id);
printf("及格人數: %d, 及格率: %.2f%%\n", s.pass_cnt, s.pass_rate);
}
void print_ranking(const char *title, Student *cls, int count) {
printf("\n--- %s 排名表 ---\n", title);
printf("%-5s %-10s %s\n", "排名", "學號", "成績");
for (int i = 0; i < count; i++) {
printf("%-5d %-10d %d\n", i+1, cls[i].id, cls[i].score);
}
}
int main() {
input_students(classA, &countA, MAX_CLASS_A, "班級 A");
input_students(classB, &countB, MAX_CLASS_B, "班級 B");
Stats sa = calc_stats(classA, countA);
Stats sb = calc_stats(classB, countB);
print_stats("班級 A 統計", sa);
print_stats("班級 B 統計", sb);
sort_desc(classA, countA);
sort_desc(classB, countB);
print_ranking("班級 A", classA, countA);
print_ranking("班級 B", classB, countB);
return 0;
}
$ gcc grade_mgmt.c -o grade_mgmt -std=c11 -Wall
$ ./grade_mgmt
班級 A (最多50人,輸入學號 -1 結束):
第 1 位 - 學號 成績: 1001 85
第 2 位 - 學號 成績: 1002 58
第 3 位 - 學號 成績: 1003 92
第 4 位 - 學號 成績: -1 0
班級 B (最多50人,輸入學號 -1 結束):
第 1 位 - 學號 成績: 2001 76
第 2 位 - 學號 成績: 2002 60
第 3 位 - 學號 成績: -1 0
=== 班級 A 統計 ===
平均分: 78.33
最高分: 92 (學號: 1003)
最低分: 58 (學號: 1002)
及格人數: 2, 及格率: 66.67%
=== 班級 B 統計 ===
平均分: 68.00
最高分: 76 (學號: 2001)
最低分: 60 (學號: 2002)
及格人數: 2, 及格率: 100.00%
--- 班級 A 排名表 ---
排名 學號 成績
1 1003 92
2 1001 85
3 1002 58
--- 班級 B 排名表 ---
排名 學號 成績
1 2001 76
2 2002 60
malloc/realloc 替換靜態數組,突破人數上限。save_to_csv/load_from_csv,數據掉電不丟失。int scores[SUBJECT_CNT],統計邏輯改為多維。本實現嚴格遵循「高內聚、低耦合」原則,各功能模組職責單一,代碼可讀性強,易於維護擴展。核心難點——**排序時學號與成績綁定交換**——通過結構體整體賦值優雅解決,避免了原始代碼中分開交換導致的數據錯位風險。此代碼可作為 C 語言期末項目、嵌入式數據處理模塊的直接參考。