經典 C 語言面試題:c = fgetc(fp) != EOF 這行代碼的執行順序是什麼?
| 優先級 | 運算符 | 結合性 |
|---|---|---|
| 高 | () [] -> . | 左→右 |
| ⋮ | ⋮ | ⋮ |
| 中 | != == | 左→右 |
| 低 | = += -= ... | 右→左 |
c = fgetc(fp) != EOF
// 步驟 1:函數調用最高優先級
// fgetc(fp) → 返回 int (字符值或 EOF)
//
// 步驟 2:!= 比賦值 = 優先級高
// fgetc(fp) != EOF → 邏輯判斷:真(1) 或 偽(0)
//
// 步驟 3:賦值 = 最低優先級
// c = (上一步結果) → c 被賦值為 1 或 0
fgetc 返回字符碼 (如 65 'A'),65 != EOF 為真 (1),c = 1fgetc 返回 EOF (通常 -1),-1 != -1 為假 (0),c = 0// 加括號強制先賦值再比較
while ((c = fgetc(fp)) != EOF) {
// c 是字符值,正常處理
putchar(c);
}
| 代碼 | c 的值 | 循環條件 | 用途 |
|---|---|---|---|
c = fgetc(fp) != EOF | 0 或 1 | 無循環,單次判斷 | 錯誤用法 |
(c = fgetc(fp)) != EOF | 字符碼 (0-255) 或 EOF | 讀到 EOF 為假結束 | 標準讀取循環 |
c = fgetc(fp); c != EOF | 字符碼 | 分兩句寫,同效果 | 教學演示 |
「賦值最低級,比較在中間,函數調用最高,括號保平安。」
// 1. 位運算 & | 優先級低於 == !=
if (a & b == 0) // 實際解析:a & (b == 0) ❌
if ((a & b) == 0) // 正確
// 2. 移位優先級低於加減
x = y << 2 + 1 // 實際:y << (2+1) = y << 3 ❌
x = (y << 2) + 1 // 正確
// 3. 三目運算符優先級極低
return a > 0 ? 1 : -1 == 0 // 實際:(a>0?1:-1) == 0 ❌
return a > 0 ? 1 : (-1 == 0) // 正確
寫 C 代碼時,不確定優先級就加括號,現代編譯器優化會消除冗餘括號,可讀性與正確性永遠優先。