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

C語言易錯知識點深度解析:stdout緩衝、extern陷阱、switch變量、sizeof副作用、宏註釋、scanf格式

     編輯:關於C語言

1. stdout/stderr 緩衝機制差異

現象:無限迴圈交替 fprintf(stdout, ...) 和 fprintf(stderr, ...),stdout 輸出不顯示直到緩衝區滿/遇換行/調用 fflush,而 stderr 立即顯示。
原因:stdout 預設**全緩衝**(塊設備),stderr 預設**無緩衝**。
解決:setbuf(stdout, NULL) 或每次輸出後 fflush(stdout),或輸出帶 \n(行緩衝模式下)。

2. extern 數組聲明類型不匹配

代碼:file1.c: int arr[80];,file2.c: extern int *arr;
後果:編譯通過,運行時崩潰。int * 與 int [80] 類型不同:前者是指針(需儲存地址),後者是數組(地址常量)。extern int *arr 會讀取數組前幾個元素作為指針值。
正確:extern int arr[]; 或 extern int arr[80];。

3. switch 語句跳過變量初始化

代碼:switch(a) { int b=20; case 1: printf("%d",b); }
結果:輸出隨機棧值。
原因:case 標籤是跳轉目標,聲明帶初始化的變量在作用域內但初始化被跳過。C 標準規定可聲明但不可初始化(或用塊包裹 { int b=20; ... })。

4. sizeof 不計算副作用

代碼:int i=10; sizeof(i++); printf("%d", i); 輸出 10。
原因:sizeof 是**編譯時運算符**,僅求表達式類型大小,不求值。i++ 不會執行。
注意:VLA(變長數組)中 sizeof 會在運行時求值,但仍不計算副作用。

5. 宏參數意外觸發註釋

代碼:y = y/*p; /* dividing y by *p */
結果:/* 被識別為註釋開始,後面代碼全被註釋掉,語句實為 y = y。
教訓:宏參數中避免 / * 組合;除法寫 y / (*p) 加空格括號。

6. scanf 掃描集 %[^r] 行為

代碼:scanf("%[^r]", dummy); 輸入 Hello, World。
結果:讀取直到遇到字符 'r'(不含),即 Hello, Wo。%[^r] 非 %[^\n](讀整行)。
正確讀行:scanf("%[^\n]", s) 或 fgets(s, sizeof(s), stdin)。

總結:避坑清單

  1. 輸出調試信息優先用 stderr 或手動 fflush。
  2. 跨文件共享數組用 extern int arr[];。
  3. switch 中聲明變量用 { } 包裹。
  4. 不要在 sizeof 中寫有副作用的表達式。
  5. 宏定義與除法運算加括號空格防註釋誤觸發。
  6. scanf 格式字串仔細閱讀手冊,測試邊界輸入。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved