C語言運算子優先順序理解記憶,語法「陷阱」

2021-08-06 07:51:14 字數 3069 閱讀 9751

運算子優先順序最重要兩點:

1.任何乙個邏輯運算子的優先順序低於任何乙個關係運算子。

2.移位運算子的優先順序比算術運算子要低,但是比關係運算子要高。

記住這兩條,能避免很多問題了。

貼上運算子優先順序表: 1

陣列下標

陣列名[常量表示式]

左到右--

()圓括號

(表示式)/函式名(形參表)--.

成員選擇(物件)

物件.成員名

--->

成員選擇(指標)

物件指標->成員名--2

-負號運算子

-表示式

右到左單目運算子

~按位取反運算子

~表示式

++自增運算子

++變數名/變數名++

--自減運算子

--變數名/變數名--

*取值運算子

*指標變數

&取位址運算子

&變數名

!邏輯非運算子

!表示式

(型別)

強制型別轉換

(資料型別)表示式

sizeof

長度運算子

sizeof(表示式)3/

除表示式/表示式

左到右算數運算子

(雙目運算子)*乘

表示式*表示式

%餘數(取模)

整型表示式%整型表示式4+

加表示式+表示式

左到右-

減表示式-表示式

5<< 

左移變數《表示式

左到右移位運算子

(雙目運算子)

>> 

右移變數》表示式

6> 

大於表示式》表示式

左到右關係運算子

(雙目運算子)

>=

大於等於

表示式》=表示式

小於表示式《表示式

<=

小於等於

表示式<=表示式7==

等於表示式==表示式

左到右!=

不等於表示式!= 表示式8&

按位與表示式&表示式

左到右邏輯運算子

(雙目運算子)9^

按位異或

表示式^表示式

左到右10

|按位或

表示式|表示式

左到右11

&&邏輯與

表示式&&表示式

左到右12

||邏輯或

表示式||表示式

左到右13

?:條件運算子

表示式1?

表示式2:

表示式3

右到左條件運算子

(三目運算子)14=

賦值運算子

變數=表示式

右到左賦值運算子15,

逗號運算子

表示式,表示式,…

左到右--

下面講一些理解記憶方式:

a:不同型別的運算子優先順序:

1.優先順序最高者,其實不是真正意義的運算子,包括:陣列下標、函式呼叫操作符、各結構成員選擇操作符。

它們都是自左於右結合,因此a.b.c的含義是(a.b).c,而不是a.(b.c)

2.在所有的真正意義上的運算子中,單目運算子的優先順序最高。

因為函式呼叫的優先順序要高於單目運算子的優先順序,所以如果p是乙個函式指標,要呼叫p所指向的函式,必須這樣寫:(*p)()。如果寫成*p(),編譯器會解釋成*(p())。

型別轉換符也是單目運算子,它的優先順序和其他單目運算子的優先順序一樣。單目運算子是自右至左,因此*p++會被編譯器解釋成*(p++),即取指標p所指向的物件,然後將p遞增1;而不是(*p)++,即取指標p所指向的物件,然後將該物件遞增1。

3.所有雙目運算子比單目運算子優先順序低。雙目運算子中優先順序順序:算數運算子 > 移位運算子 > 關係運算子 > 邏輯運算子 > 賦值運算子。

4.三目運算子 ?:的優先順序在所有真正意義的運算子中最低。

三目運算子優先順序最低,所以允許我們在三目條件運算子的條件表示式中包含關係運算子的邏輯組合,例如:

temp_a = temp_b > 4000 && temp_c < 3000 ?  1:0

本例也說明,賦值運算子的優先順序低於條件運算子的優先順序是有意義的。

此外所有的賦值運算子的優先順序是一樣的,而它們的結合方式是從右到左。

b:同一型別的運算子間的優先順序:

1.算數運算子很好理解,乘法、除法和求餘優先順序相同。加法、減法優先順序相同。兩個移位運算子優先順序也相同。

2.六個關係運算子的優先順序不同。==和!=的優先順序要低於其他關係運算子的優先順序。

如果我們要比較a與b的相對大小順序是否和c與d的相對大小順序一樣,就可以這麼寫:a < b == c < d

3.任何兩個邏輯運算子都具有不同的優先順序。所有按位運算子優先順序比順序運算子的優先順序高,每個「與」運算子比相應的「或」運算子優先順序高,而按位異或(^運算子)的優先順序介於按位與運算子和按位或運算子之間。

c:再隨便多說兩句

用新增括號的方法雖然可以完全避免優先順序引發的問題,但是表示式中有了太多的括號反而不容易理解。

涉及到賦值運算子時,經常會引起優先順序的混淆,例如下面這個例子

while(c = getc(in) != eof)

put(c,out);

在while語句表示式中,c似乎是首先被賦予函式getc(in)的返回值,然後與eof比較是否達到檔案結尾以便決定是否終止迴圈。然而,由於賦值運算子的優先順序要低於任何乙個比較運算子,因此c的值實際上是函式getc(in)的返回值與eof比較的結果。此處函式getc(in)的返回值只是乙個臨時變數,在與eof比較後就被「丟棄「了。因此,最後得到的文「副本」中只包括了一組二進位制為1的位元組流。

C 運算子優先順序記憶

為了方便自己記憶,將幾乎所有運算子編成口訣記憶 圓方括號域,箭頭一句號 位反邏非長強制,正負增減值取地 乘除加減再移位,大小等等等不等 八位與九位異或,十一二邏輯與或 條件賦值後逗號 1.圓方括號域,箭頭一句號 1 陣列下標 陣列名 常量表示式 左到右 圓括號 表示式 函式名 形參表 成員選擇 物件...

C 語言運算子優先順序(記憶口訣)

優先順序運算子 名稱或含義 使用形式 結合方向說明1 陣列下標 陣列名 常量表示式 左到右 圓括號 表示式 函式名 形參表 成員選擇 物件 物件.成員名 成員選擇 指標 物件指標 成員名2 負號運算子 表示式 右到左單目運算子 型別 強制型別轉換 資料型別 表示式 自增運算子 變數名 變數名 單目運...

C 語言運算子優先順序(記憶口訣)

優先順序 運算子名稱或含義 使用形式 結合方向說明1 陣列下標 陣列名 常量表示式 左到右 圓括號 表示式 函式名 形參表 成員選擇 物件 物件.成員名 成員選擇 指標 物件指標 成員名2 負號運算子 表示式 右到左單目運算子 型別 強制型別轉換 資料型別 表示式 自增運算子 變數名 變數名 單目運...