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

C 語言編程 18 類常見錯誤全景圖譜:從語法陷阱到運行時災難

     編輯:關於C語言

前言

C 語言給予程序員極大自由,也帶來極多坑。本文梳理 18 類高發錯誤,附錯誤代碼、原因分析、正確寫法與避坑口訣。

錯誤清單

1. 大小寫敏感:a != A


// 錯
int a = 5; printf("%d", A);  // A 未聲明
// 正
int a = 5; printf("%d", a);

口訣:常量全大寫,變量全小寫,嚴格區分。

2. 類型不匹配運算:浮點不能取模


// 錯
float a, b; printf("%d", a % b);  // % 僅限整型
// 正
int a, b; printf("%d", a % b);
// 或用 fmod(a, b) 處理浮點

3. 字符 vs 字符串混淆


// 錯
char c; c = "a";  // "a" 是字符串(含 \0),占 2 字節
// 正
char c; c = 'a';  // 'a' 是字符,占 1 字節

4. = vs == 經典誤用


// 錯
if (a = 3) ...  // 賦值,值為 3 恆真
// 正
if (a == 3) ... // 比較
// 防禦寫法:if (3 == a) ... 常量在左,誤寫 = 編譯報錯

5. 忘寫分號


a = 1
b = 2  // 編譯器視為一條語句,語法錯誤

復合語句最後一條也必須加分號(Pascal 習慣害人)。

6. 多加分號:空語句陷阱


// 錯
if (a % 3 == 0);  // 分號結束 if,下面語句無條件執行
    i++;

// 錯
for (i = 0; i < 5; i++);  // 循環體為空,僅跑 5 次空操作
    { scanf(...); printf(...); }  // 只執行一次

7. scanf 忘加 & 取地址


// 錯
int a, b; scanf("%d%d", a, b);
// 正
scanf("%d%d", &a, &b);
// 數組名/指針本身即地址,不加 &
char str[20]; scanf("%s", str);  // 正確

8. 輸入格式與格式串不匹配


// 格式串 "%d%d" 輸入需用空格/換行分隔,不能用逗號
// 格式串 "%d,%d" 輸入必須帶逗號 "3,4"
// 格式串 "a=%d,b=%d" 輸入必須 "a=3,b=4"

9. %c 讀取空白字符


scanf("%c%c%c", &c1, &c2, &c3);
// 輸入 "a b c" → c1='a', c2=' ', c3='b'
// 解決:在格式串前加空格 " %c" 跳過空白

10. 輸出格式符與類型不符


int a = 3; float b = 4.5;
printf("%f%d", a, b);  // 運行時輸出亂碼,編譯不報錯
// 必須嚴格對應:%d↔int, %f↔float/double, %p↔指針

11. scanf 限制精度無效


// 錯
scanf("%7.2f", &a);  // 輸入不支持精度限制
// 正
scanf("%f", &a);  // 讀完整數值,輸出時用 %.2f 控制

12. switch 缺 break 貫穿


switch(grade) {
    case 'A': printf("85-100");
    case 'B': printf("70-84");  // 無 break,A 會印出所有後續
}
// 每個 case 末尾加 break

13. while vs do-while 執行次數差異


// while:先判斷後執行,可能 0 次
// do-while:先執行後判斷,至少 1 次
// 輸入 I=11 時,while 不進循環,do-while 執行 1 次

14. 變長數組 (VLA) 非標準 C++ / 栈溢出風險


// 錯
int n; scanf("%d", &n); int a[n];  // C99 支持,C++ 不標準,大 n 炸棧
// 正
int *a = malloc(n * sizeof(int));  // 堆分配,用完 free

15. 數組下標越界:長度 n 下標 0~n-1


int a[10] = {1..10};
printf("%d", a[10]);  // 越界,未定義行為
// 最大下標是 9

16. (原文缺 16,此處補充) 結構體對齊導致 sizeof 非預期


struct { char c; int i; };  // sizeof 可能是 8 而非 5(內存對齊)
// 用 #pragma pack(1) 或排序成員減少填充

17. 字符數組 scanf 加 & 錯誤


// 錯
char str[20]; scanf("%s", &str);
// 正
scanf("%s", str);  // 數組名即首地址

18. 形參與局部變量重名/混淆


// 舊式 K&R 風格錯誤
int max(x, y) int x, y, z; { ... }  // z 是形參?還是局部?
// 現代 ANSI 風格
int max(int x, int y) {
    int z = x > y ? x : y;  // 明確在函數體內定義局部變量
    return z;
}

避錯黃金法則

  1. 開啟高警告級別:gcc -Wall -Wextra -Werror -pedantic
  2. 靜態分析:clang --analyze、cppcheck、Coverity
  3. 單元測試:邊界、異常輸入全覆蓋
  4. Code Review:雙眼審核捕獲 60%+ 邏輯錯誤
  5. 規範命名:語義化變量名,拒絕 i, j, k, a, b, c 流失
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved