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

C 語言鏈表學生管理系統:修改節點邏輯錯誤修正與代碼規範化

     編輯:程式設計綜合問答

原代碼核心缺陷

int ModifyList(LinkList &L, int Chinese, int Math, int English) {
    LinkList p = L->next;
    char changename[3]; // 緩衝區極小,姓名超 2 字符溢出
    scanf("%s", changename);
    for (; (strcmp(changename, p->name) == 0); p = p->next) { // 條件反了!相等時進入,不相等直接退出
        p->s[0].score = Chinese;
        p->s[1].score = Math;
        p->s[2].score = English;
    }
    return OK;
}

致命錯誤:`for` 循環條件 `(strcmp(...) == 0)` 表示**當名字相等時繼續循環**,實際需**遍歷所有節點,找到匹配名字者修改**。

修正版 ModifyList

#define NAME_LEN 20
#define MAX_COURSES 3

int ModifyList(LinkList L, int Chinese, int Math, int English) {
    char changename[NAME_LEN];
    printf("請輸入要修改的學生姓名: ");
    if (scanf("%19s", changename) != 1) return ERROR; // 限制寬度防溢出

    LinkList p = L->next;
    while (p != NULL) {
        if (strcmp(changename, p->name) == 0) { // 找到匹配
            p->s[0].score = Chinese;
            p->s[1].score = Math;
            p->s[2].score = English;
            printf("修改成功: %s\n", changename);
            return OK;
        }
        p = p->next;
    }
    printf("未找到學生: %s\n", changename);
    return ERROR;
}

全局代碼規範化建議 (節選關鍵點)

問題原代碼建議修正
姓名緩衝區過小 `char name[3];` `#define NAME_LEN 32` / `char name[NAME_LEN];`
`scanf("%s")` 無寬度限制 `scanf("%s", p->name);` `scanf("%31s", p->name);` (留 1 字節給 `\0`)
成績輸入格式強制逗號 `scanf("%d,%d,%d", ...)` `scanf("%d %d %d", ...)` 支持空格/換行/逗號混合,或解析整行 `fgets`+`sscanf`
無內存分配失敗檢查 `malloc` 直接用 `if (!p) { perror("malloc"); exit(1); }`
主函數非標準 `void main()` `void main()` `int main(void)` 返回 `0`
鏈表操作無邊界檢查 `ListInsert(L, 2)` 位置合法性 檢查 `i >= 1 && i <= Length(L)+1`
C++ 引用語法 `LinkList &L` 用在 C 文件 `LinkList &L` 改 `LinkList *L` (指針的指針) 或重命名為 `.cpp` 用 C++ 編譯

完整可編譯版 (C99 標準)

// 完整代碼見附件,核心修正點:
// 1. 所有字符串緩衝區擴大至 32 字節
// 2. scanf 限制寬度 %31s
// 3. ModifyList 正確遍歷查找邏輯
// 4. 主函數 int main(void)
// 5. 刪除節點時免檢查 p->next 為空
// 6. 統一錯誤碼 OK/ERROR
// 7. 釋放內存後指針置 NULL (良好習慣)

調試技巧

  • 編譯加 `-Wall -Wextra -fsanitize=address -g` (GCC/Clang) 開啟地址消毒器檢測越界/釋放後使用。
  • 用 `valgrind --leak-check=full ./a.out` 檢測內存洩漏。
  • 在關鍵節點打印指針地址 `printf("p=%p\n", (void*)p);` 觀察鏈表結構。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved