C語言複習筆記(2)——運算子優先順序
阿新 • • 發佈:2018-12-29
C 運算子優先順序
下表列出 C 運算子的優先順序和結合性。運算子從頂到底以降序列出。
優先順序 | 運算子 | 描述 | 結合性 |
---|---|---|---|
1 | ++ -- |
字尾自增與自減 | 從左到右 |
() |
函式呼叫 | ||
[] |
陣列下標 | ||
. |
結構體與聯合體成員訪問 | ||
-> |
結構體與聯合體成員通過指標訪問 | ||
(type){list} |
複合字面量(C99) | ||
2 | ++ -- |
字首自增與自減 | 從右到左 |
+ - |
一元加與減 | ||
! ~ |
邏輯非與逐位非 | ||
(type) |
型別轉型 | ||
* |
間接(解引用) | ||
& |
取址 | ||
sizeof |
取大小 | ||
_Alignof |
對齊要求(C11) | ||
3 | * / % |
乘法、除法及餘數 | 從左到右 |
4 | + - |
加法及減法 | |
5 | << >> |
逐位左移及右移 | |
6 | < <= |
分別為 < 與 ≤ 的關係運算符 | |
> >= |
分別為 > 與 ≥ 的關係運算符 | ||
7 | == != |
分別為 = 與 ≠ 關係 | |
8 | & |
逐位與 | |
9 | ^ |
逐位異或(排除或) | |
10 | | |
逐位或(包含或) | |
11 | && |
邏輯與 | |
12 | || |
邏輯或 | |
13[注 2] | ?: |
三元條件 | 從右到左 |
14 | = |
簡單賦值 | |
+= -= |
以和及差賦值 | ||
*= /= %= |
以積、商及餘數賦值 | ||
<<= >>= |
以逐位左移及右移賦值 | ||
&= ^= |= |
以逐位與、異或及或賦值 | ||
15 | , |
逗號 | 從左到右 |
- ↑
sizeof
的運算數不能是型別轉型:表示式sizeof (int) * p
無歧義地轉譯成(sizeof(int)) * p
,而非sizeof((int)*p)
。 - ↑ 虛構優先順序,見下面注意
- ↑ 條件運算子中部(
?
與:
之間)的表示式分析為如同加括號:忽略其相對於?:
的優先順序。
分析表示式時,列於上面表中某行的運算子,將比列於低於它的行中擁有較低優先順序的任何運算子,更緊密地繫結到其引數(如同用括號)。例如,表示式 *p++ 被分析為 *(p++) ,而非 (*p)++ 。
擁有相同優先順序的運算子以其結合性的方向繫結到其引數。例如表示式 a = b = c 被分析為 a = (b = c) 而非 (a = b) = c ,因為從右到左結合性。
注意
優先順序和結合性與求值順序獨立。
C 語言標準不指定運算子優先順序。它指定語言文法,而優先順序表格從它匯出,以簡化理解。文法有一部分無法以優先順序表格表示:不允許賦值表示式作為條件運算子的右側運算數,故 e = a < d ? a++ : a = d 是不能分析的表示式,從而條件與賦值運算子的相對優先順序無法簡單描述。
然而,許多 C 編譯器使用非標準表示式文法,其中指定 ?:
擁有高於 =
的優先順序,這將該表示式分析為 e = ( ((a < d) ? (a++) : a) = d ) ,它因語義制約而編譯失敗: ?:
決不是左值而 =
要求可修改左值在左側。此即此頁面所呈現的表格。
注意 C++ 中這有別,其中條件運算子與賦值擁有相同優先順序。
結合性規定對於一元運算子是冗餘的,且只為完備而顯示:一元字首運算子始終從右到左結合( delete ++*p 為 delete(++(*p)) )而一元后綴運算子始終從左到右結合( a[1][2]++ 為 ((a[1])[2])++ )。注意結合性對成員訪問運算子有意義,即使在它們與一元后綴運算子組合時: a.b++ 分析為 (a.b)++ 而非 {{c|a.(b++)} 。