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

C 語言運算符優先級與結合性完整表:口訣速記、陷阱案例與編譯器差異

     編輯:更多程式設計知識

運算符優先級決定「誰先算誰後算」,結合性決定「同級誰先誰後」。本文提供**標準優先級表(15 級)**、**三大口訣速記法**、**經典陷阱案例**、**C vs C++ 差異**、**編譯器實現細節**,助你徹底征服優先級這座「必考大山」。

標準優先級表(C99/C11,高→低)

級運算符說明結合性目數
1`()` `[]` `->` `.`函數調用、下標、成員訪問左→右1/2
2`++` `--` `+` `-` `!` `~` `*` `&` `(type)` `sizeof`後置/前置自增減、一元正負、邏輯非、按位非、間接/取址、強制轉換、大小右→左1
3`*` `/` `%`乘、除、取模左→右2
4`+` `-`加、減左→右2
5`<<` `>>`左移、右移左→右2
6`<` `<=` `>` `>=`關系比較左→右2
7`==` `!=`等於、不等於左→右2
8`&`按位與左→右2
9`^`按位異或左→右2
10`|`按位或左→右2
11`&&`邏輯與左→右2
12`||`邏輯或左→右2
13`?:`條件運算符右→左3
14`=` `+=` `-=` `*=` `/=` `%=` `<<=` `>>=` `&=` `^=` `|=`賦值及複合賦值右→左2
15`,`逗號運算符(順序求值)左→右2

三大口訣速記法

口訣一:形象編碼法(原文改良版)

圓下箭頭一頓號          // 1級: () [] -> .
非凡增減富強針地長       // 2級: ! ~ ++ -- + - * & (type) sizeof
三乘除,四加減,五移位    // 3/4/5級: * / %  |  + -  |  << >>
千萬別把魚忘記           // % 與 * / 同級 (3級)
小燈大燈燈燈不等         // 6/7級: < <= > >=  |  == !=
爸喂魚,舅疑惑,裸雞也疑惑 // 8/9/10/11/12級: &  |  ^  &&  ||
十三姨,十四父,十五逗   // 13/14/15級: ?:  =+=...  ,

口訣二:分類順序法

括號成員第一
全體單目第二
乘除余三,加減四
移位五,關系六
等於不等排第七
位與異或和位或
邏輯與、邏輯或 八九十
條件高於賦值
逗號運算級最低

口訣三:助記句法

「括下箭點單目先,乘除加減移位遷。關系等於位與異,位或邏輯與或全。三目賦值逗號後,右左結合記心田。」

經典陷阱案例與解析

代碼常見誤解實際解析結果
`a = b = c = 1`語法錯誤`=` 右結合:`a = (b = (c = 1))`a=b=c=1
`*p++``*(p++)` 還是 `(*p)++`?後置 `++` 最高(1級)> `*`(2級) → `*(p++)`取值後指針+1
`&a[3]``&(a[3])` 還是 `(&a)[3]`?`[]` (1級) > `&` (2級) → `&(a[3])`第 3 元素地址
`sizeof int * p``sizeof(int) * p` 還是 `sizeof(int * p)`?`sizeof` (2級) > `*` (3級) → `(sizeof int) * p`類型大小乘 p
`a ? b : c = d``(a?b:c) = d` 還是 `a ? b : (c=d)`?`?:` (13級) > `=` (14級) → `a ? b : (c = d)`三目結果不可作左值
`i = 1; a[i] = i++;`行為未定義 (UB)同一序列點多次修改 `i`,C 標準未定義行為編譯器相關,嚴禁

C vs C++ 關鍵差異

項目CC++
新增運算符無`::` `.*` `->*` `typeid` `dynamic_cast` `static_cast` `reinterpret_cast` `const_cast` `new` `delete` `co_await` `co_yield`
條件運算符結果右值(不可賦值)左值(若兩分支均為左值且類型兼容)
逗號運算符重載不可重載可重載(極少用)
優先級表長度15 級18 級(含類型轉換、成員指針等)

編譯器實現細節

  • 序列點:C 標準規定在序列點(語句結尾、`&&` `||` `?:` `,`、函數調用前後)前所有副作用必須完成。**兩次修改同一對象且無序列點隔離 = UB**。
  • 求值順序:運算符優先級 ≠ 求值順序。`f() + g()` 中 `f` `g` 調用順序**未規定**,不可相互依賴副作用。
  • 整數提升與常見算術轉換:運算前將窄類型提升為 `int`/`unsigned int`,再按符號/寬度轉換為公共類型,影響 `signed/unsigned` 混合比較結果。
  • 常量折疊:編譯期計算常量表達式,`#define N 10; int a = N * 2;` → `int a = 20;`。

實戰防護建議

  1. 不確定時加括號:`(a + b) * c`、`(p->next)->val`、`(flag ? x : y) = z`,**多一對括號少一類 Bug**。
  2. 啟用警告:`-Wparentheses -Wsequence-point -Wlogical-op` 捕獲可疑優先級/序列點問題。
  3. 靜態分析:Cppcheck、Clang-Tidy `bugprone-operator-precedence`、`bugprone-assignment-in-condition`。
  4. 代碼風格強制:公司規範要求「所有二元運算符兩側加空格、嵌套表達式必加括號」。

運算符優先級是 C 語言的「語法交通規則」。**背熟 15 級表、會用三大口訣、遇疑必加括號、警告全開啟**——這就是征服它的全部秘訣。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved