1. 程式人生 > >C語言複習筆記(2)——運算子優先順序

C語言複習筆記(2)——運算子優先順序

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 , 逗號 從左到右
  1. sizeof 的運算數不能是型別轉型:表示式 sizeof (int) * p 無歧義地轉譯成 (sizeof(int)) * p ,而非 sizeof((int)*p)
  2. 虛構優先順序,見下面注意
  3. 條件運算子中部( ?: 之間)的表示式分析為如同加括號:忽略其相對於 ?: 的優先順序。

分析表示式時,列於上面表中某行的運算子,將比列於低於它的行中擁有較低優先順序的任何運算子,更緊密地繫結到其引數(如同用括號)。例如,表示式 *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 ++*pdelete(++(*p)) )而一元后綴運算子始終從左到右結合( a[1][2]++((a[1])[2])++ )。注意結合性對成員訪問運算子有意義,即使在它們與一元后綴運算子組合時: a.b++ 分析為 (a.b)++ 而非 {{c|a.(b++)} 。