某初學者在杭電 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 核心問題
- 指針數組未分配內存:
int *stu[max]僅分配指針,未malloc每個元素- 輸入循環無終止條件:導致緩衝區溢出
- 變量未初始化:
rank, jack_id, flag[]含隨機值- 邏輯與輸入耦合:排名計算混雜在輸入循環中
- 語法不規範:隱式
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; i num, &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 初學者的建議
- 先寫
struct設計數據模型,再寫算法- 每次
malloc配對free,Valgrind 檢查內存洩漏- 邊界條件 (n=0, n=1, 重複分數) 必須測試
- 善用
assert斷言關鍵假設- 代碼風格統一:縮進、命名、註釋