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

C 語言 14 連環謎題:測試你對標準行為的掌握程度

     編輯:關於C語言

C 語言看似簡單,實則暗藏許多「未定義行為」「實作定義行為」與「標準細節」。以下 14 道經典謎題涵蓋 I/O 緩衝、逗號運算子、printf 回傳值、浮點數記憶體佈局、extern 型別不匹配、switch 作用域、緩衝區溢位、sizeof 不求值特性、八進位常數、註解陷阱、短路求值、陣列下標交換、scanf 格式字串、運算子優先級等核心知識點。

謎題與解析精選

1. stdout/stderr 緩衝差異

while(1) {
    fprintf(stdout, "hello-std-out");
    fprintf(stderr, "hello-std-err");
    sleep(1);
}

現象:stderr 立即顯示,stdout 延遲。
原因:stdout 預設全緩衝(遇換行/滿/flush 才輸出),stderr 無緩衝。

2. 逗號運算子 vs 宣告分隔符

int a = 1,2;  // 編譯錯誤
int a = (1,2); // 正確,a=2

宣告中逗號是分隔符,非運算子;需加括號構成逗號運算式。

3. printf 回傳值

printf("%d\n", printf("%d", printf("%d", 43))); // 輸出 4321

內層印 43 回傳 2,中層印 2 回傳 1,外層印 1。

4. 浮點數傳給 %d

float a = 12.5f;
printf("%d\n", a);        // 0  (float 推升為 double,前 4 bytes 為 0)
printf("%d\n", (int)a);   // 12
printf("%d\n", *(int*)&a); // 1095237632 (IEEE 754 位元模式)

5. extern 陣列 vs 指標

// file1.c: int arr[80];
// file2.c: extern int *arr;  // 型別不符,運行時崩潰
// 正確:extern int arr[];

6. switch 跳過初始化

switch(a) {
    int b = 20;  // 被跳過,b 未初始化
    case 1: printf("%d", b);
}

7. scanf 緩衝區溢位

char str[80];
scanf("%s", str);  // 輸入超過 79 字元 → UB

8. sizeof 不求值

int i=10;
sizeof(i++);  // 不執行 i++,i 仍為 10

9. 八進位常數


int pot[] = {0001, 0010, 0100, 1000}; // 1, 8, 64, 1000

10. 註解吞噬除法


y = y/*p;  // /* 開啟註解,p 後內容被忽略

11. 短路求值


int i=6;
if ( ((++i<7) && (i++/6)) || (++i<=9) );
// 逐步推演得 i=8

12. 陣列下標交換


"hello"[2] == 2["hello"]  // 皆為 'l'

因 a[b] ≡ *(a+b) ≡ *(b+a) ≡ b[a]。

13. scanf 掃描集


scanf("%[^r]", buf);  // 讀到 'r' 停止
// 輸入 "Hello, World" → 讀取 "Hello, Wo"

14. 位移優先級低於加法


t = a<<2 + a;  // 實為 a << (2+a)
t = (a<<2) + a; // 正確:乘 5

總結

這些謎題揭示了 C 語言「看似直覺實則陷阱」的特性。建議開發者:

  • 啟用最高警告等級(-Wall -Wextra -pedantic)。
  • 善用靜態分析工具。
  • 養成「不依賴未定義行為」的編碼習慣。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved