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

ACM 題目代碼審查:杭電 OJ 常見錯誤模式與重構建議

     編輯:關於C語言

背景

某初學者在杭電 OJ 提交代碼屢次 WA,代碼存在嚴重語法錯誤、邏輯混亂、變量未初始化等問題。本文通過對比錯誤代碼與重構版,總結 ACM 入門常見陷阱。

典型錯誤代碼分析

// 原始錯誤版 (節選)
#include 
#define max 1000
main(argc, argv) {
    int *stu[max], *stur[max], rank, jack_id, flag[max];
    while (scanf("%d", &jack) != EOF) {
        for (i=0; i

核心問題

  1. 指針數組未分配內存:int *stu[max] 僅分配指針,未 malloc 每個元素
  2. 輸入循環無終止條件:導致緩衝區溢出
  3. 變量未初始化:rank, jack_id, flag[] 含隨機值
  4. 邏輯與輸入耦合:排名計算混雜在輸入循環中
  5. 語法不規範:隱式 int 返回類型、參數未聲明類型

重構版代碼 (C99 風格)

#include 
#include 

typedef struct { int num; int mark; } Student;

int read_students(Student *stu, int n, int *jack_mark) {
    Student *p = stu;
    for (int i=0; inum, &p->mark) != 2) return 0;
        if (p->num == *jack_mark) *jack_mark = p->mark; // 假設 jack_mark 為目標學號
    }
    return 1;
}

int rank_student(Student *stu, int n, int jack_mark) {
    int rank = 1;
    for (int i=0; i jack_mark) rank++;
    return rank;
}

int main() {
    int n, jack_num;
    while (scanf("%d", &n) == 1 && n) {
        scanf("%d", &jack_num);
        Student *stu = malloc(n * sizeof(Student));
        int jack_mark = 0;
        if (!read_students(stu, n, &jack_mark)) break;
        // 找到 Jack 的分數 (假設學號唯一)
        for (int i=0; i

改進要點

  • 使用結構體封裝學生數據,替代平行數組
  • 動態分配內存 (malloc/free) 適應變長輸入
  • 分離輸入、計算、輸出邏輯,單一職責
  • 嚴格檢查 scanf 返回值,防止輸入異常
  • 變量定義時初始化,消除未定義行為

給 ACM 初學者的建議

  1. 先寫 struct 設計數據模型,再寫算法
  2. 每次 malloc 配對 free,Valgrind 檢查內存洩漏
  3. 邊界條件 (n=0, n=1, 重複分數) 必須測試
  4. 善用 assert 斷言關鍵假設
  5. 代碼風格統一:縮進、命名、註釋
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved