首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C語言學生成績管理系統:雙班數據統計、排序與及格率分析完整實現

     編輯:C 語言問答

需求分析

開發一個控制台程式,管理兩個班級 (人數可配置) 的單門課程成績,實現以下功能:

  1. 輸入學生學號與成績 (動態人數)。
  2. 統計:平均分、最高分/學號、最低分/學號。
  3. 按成績降序排序,**學號隨成績同步調整**。
  4. 輸出排序後排名表。
  5. 計算及格人數 (≥60) 及及格率。

數據結構設計

使用結構體綁定學號與成績,靜態數組存儲 (上限由宏定義),簡單高效:

#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;

核心功能模組化實現

1. 輸入模組 (含合法性校驗)


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');
}

2. 統計模組 (單次遍歷獲取所有指標)


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;
}

3. 排序模組 (學號隨成績同步移動)

采用結構體整體交換,避免多字段獨立交換出錯:


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;
            }
        }
    }
}

4. 輸出模組 (格式化對齊)


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],統計邏輯改為多維。
  • 單元測試:引入 Unity/CMock 框架,對統計、排序函數編寫測試用例。

總結

本實現嚴格遵循「高內聚、低耦合」原則,各功能模組職責單一,代碼可讀性強,易於維護擴展。核心難點——**排序時學號與成績綁定交換**——通過結構體整體賦值優雅解決,避免了原始代碼中分開交換導致的數據錯位風險。此代碼可作為 C 語言期末項目、嵌入式數據處理模塊的直接參考。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved