介紹
運算符是告訴編譯程序執行特定算術或邏輯操作的符號。C語言的運算范圍很寬,把除了控制語句和輸入輸出以外的幾乎所有的基本操作都作為運算符處理。主要分為三大類:算術運算符、 關系運算符與邏輯運算符。除此之外,還有一些用于完成特殊任務的運算符。
運算符的優先級與結合性
優先級:C語言中,運算符的運算優先級共分為15級。1級最高,15級最低。在表達式中,優先級較高的先于優先級較低的進行運算。而在一個運算量兩側的運算符優先級相同時,則按運算符的結合性所規定的結合方向處理。
結合性:C語言中各運算符的結合性分為兩種,即左結合性(自左至右)和右結合性(自右至左)。例如算術運算符的結合性是自左至右,即先左后右。如有表達式x-y+z則y應先與"-"號結合,執行x-y運算,然后再執行+z的運算。這種自左至右的結合方向就稱為"左結合性"。而自右至左的結合方向稱為"右結合性"。最典型的右結合性運算符是賦值運算符。如x=y=z,由于“=”的右結合性,應先執行y=z再執行x=(y=z)運算。C語言運算符中有不少為右結合性,應注意區別,以避免理解錯誤。
優先級 |
結合性 |
運算符 |
備注 |
1 |
左結合 |
()
[]
->
.
|
圓括號
下標運算符
指向結構體成員運算符
結構體成員運算符
|
2 |
右結合 |
!
~
++
--
+
-
(類型)
*
&
sizeof
|
邏輯非運算符
按位取反運算符
前綴增量運算符
前綴減量運算符
正號運算符
負號運算符
類型轉換運算符
指針運算符
地址運算符
長度運算符
|
3 |
左結合 |
*
/
%
|
乘法運算符
除法運算符
取余運算符
|
4 |
左結合 |
+
-
|
加法運算符
減法運算符
|
5 |
左結合 |
<<
>>
|
左移運算符
右移運算符
|
6 |
左結合 |
<
<=
>
>=
|
關系運算符
|
7 |
左結合 |
==
!=
|
等于運算符
不等于運算符
|
8 |
左結合 |
&
|
按位與運算符
|
9 |
左結合 |
^
|
按位異或運算符
|
10 |
結合性 |
|
|
按位或運算符
|
11 |
左結合 |
&&
|
邏輯與運算符
|
12 |
左結合 |
||
|
邏輯或運算符
|
13 |
右結合 |
? :
|
條件運算符
|
14 |
右結合 |
=
+=
-=
*=
/=
%=
&=
^=
|=
<<=
>>=
|
賦值運算符
|
15 |
左結合 |
,
|
逗號運算符
|
備注
優先級口訣:圓方括號、箭頭一句號,自增自減非反負、針強地址長度,乘除,加減,再移位,小等大等、等等不等,八位與,七位異,六位或,五與,四或,三疑,二賦,一真逗。
口訣解釋:“圓方括號、箭頭一句號”指的是第15級的運算符。其中圓方括號很明顯“()、[]”,箭頭指的是指向結構體成員運算符“->”,句號指的是結構體成員運算符“.”。 “自增自減非反負、針強地址長度”指的是第14級的運算符。其中非指的是邏輯運算符“!”,反指的是按位取反運算符“~”,負指的是負號運算符“-”,針指的是指針運算符“*”,強指的是強制類型轉換運算符,地址指的是地址運算符“&”,長度指的是長度運算符“sizeof”。“乘除,加減,再移位”移位指的是左移運算符“<<”和右移運算符“>>”,其中除法還包括了取余運算符“%”。“小等大等、等等不等”指的是第10級到第9級的運算符:<、<=、>和>=,等等指的是等于運算符==,不等指的是不等于運算符!=。 “八位與,七位異,六位或”其中 八位與指的是第8級的按位與運算符“&”,七位異指的是第7級的按位異或運算符“^”,六位或指的是第6級的按位或運算符“|”。 “五與,四或”指的是第5級、第4級的邏輯與運算符“&&”和邏輯或運算符“||”。“三疑,二賦,一真逗”指的是第3級到第1級的運算符。其中,三疑指的是條件運算符“?:”(三有雙重含義:即指優先級別是三,它的運算符類型也是三目,疑也取“?”之意),二賦指的是賦值運算符=、+=、-=、*=、/=、%=、>>=、<<=、&=、^=和|= ,一真逗指的是第1級的“,”運算符,真字只是為了語句需要罷了。
由于C語言的運算符優先級與C++的不完全一樣(主要是增加了幾個運算符),所以這個口訣不能完全實用于C++.但是應該能夠兼容,大家可以比較一下他們的區別應該就能夠很快掌握C++的優先級的!當然,如果真的不想背這些優先級,那么可以在每次使用符號的地方都用上(),這樣就不用在意運算符優先級了,這也是一個很好的編程習慣。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
優先級
|
運算符
|
名稱或含義
|
使用形式
|
結合方向
|
說明
|
1
|
[]
|
數組下標
|
數組名[常量表達式]
|
左到右
|
|
()
|
圓括號
|
(表達式)/函數名(形參表)
|
|
.
|
成員選擇(對象)
|
對象.成員名
|
|
->
|
成員選擇(指針)
|
對象指針->成員名
|
|
2
|
-
|
負號運算符
|
-表達式
|
右到左
|
單目運算符
|
(類型)
|
強制類型轉換
|
(數據類型)表達式
|
|
++
|
自增運算符
|
++變量名/變量名++
|
單目運算符
|
--
|
自減運算符
|
--變量名/變量名--
|
單目運算符
|
*
|
取值運算符
|
*指針變量
|
單目運算符
|
&
|
取地址運算符
|
&變量名
|
單目運算符
|
!
|
邏輯非運算符
|
!表達式
|
單目運算符
|
~
|
按位取反運算符
|
~表達式
|
單目運算符
|
sizeof
|
長度運算符
|
sizeof(表達式)
|
|
3
|
/
|
除
|
表達式/表達式
|
左到右
|
雙目運算符
|
*
|
乘
|
表達式*表達式
|
雙目運算符
|
%
|
余數(取模)
|
整型表達式/整型表達式
|
雙目運算符
|
4
|
+
|
加
|
表達式+表達式
|
左到右
|
雙目運算符
|
-
|
減
|
表達式-表達式
|
雙目運算符
|
5
|
<<
|
左移
|
變量<<表達式
|
左到右
|
雙目運算符
|
>>
|
右移
|
變量>>表達式
|
雙目運算符
|
6
|
>
|
大于
|
表達式>表達式
|
左到右
|
雙目運算符
|
>=
|
大于等于
|
表達式>=表達式
|
雙目運算符
|
<
|
小于
|
表達式<表達式
|
雙目運算符
|
<=
|
小于等于
|
表達式<=表達式
|
雙目運算符
|
7
|
==
|
等于
|
表達式==表達式
|
左到右
|
雙目運算符
|
!=
|
不等于
|
表達式!= 表達式
|
雙目運算符
|
8
|
&
|
按位與
|
表達式&表達式
|
左到右
|
雙目運算符
|
9
|
^
|
按位異或
|
表達式^表達式
|
左到右
|
雙目運算符
|
10
|
|
|
按位或
|
表達式|表達式
|
左到右
|
雙目運算符
|
11
|
&&
|
邏輯與
|
表達式&&表達式
|
左到右
|
雙目運算符
|
12
|
||
|
邏輯或
|
表達式||表達式
|
左到右
|
雙目運算符
|
13
|
?:
|
條件運算符
|
表達式1? 表達式2: 表達式3
|
右到左
|
三目運算符
|
14
|
=
|
賦值運算符
|
變量=表達式
|
右到左
|
|
/=
|
除后賦值
|
變量/=表達式
|
|
*=
|
乘后賦值
|
變量*=表達式
|
|
%=
|
取模后賦值
|
變量%=表達式
|
|
+=
|
加后賦值
|
變量+=表達式
|
|
-=
|
減后賦值
|
變量-=表達式
|
|
<<=
|
左移后賦值
|
變量<<=表達式
|
|
>>=
|
右移后賦值
|
變量>>=表達式
|
|
&=
|
按位與后賦值
|
變量&=表達式
|
|
^=
|
按位異或后賦值
|
變量^=表達式
|
|
|=
|
按位或后賦值
|
變量|=表達式
|
|
15
|
,
|
逗號運算符
|
表達式,表達式,…
|
左到右
|
從左向右順序運算
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Precedence |
Operator |
Description |
Example |
Associativity |
1 |
()
[]
->
.
::
++
-- |
Grouping operator
Array access
Member access from a pointer
Member access from an object
Scoping operator
Post-increment
Post-decrement |
(a + b) / 4;
array[4] = 2;
ptr->age = 34;
obj.age = 34;
Class::age = 2;
for( i = 0; i < 10; i++ ) ...
for( i = 10; i > 0; i-- ) ... |
left to right |
2 |
!
~
++
--
-
+
*
&
(type)
sizeof |
Logical negation
Bitwise complement
Pre-increment
Pre-decrement
Unary minus
Unary plus
Dereference
Address of
Cast to a given type
Return size in bytes |
if( !done ) ...
flags = ~flags;
for( i = 0; i < 10; ++i ) ...
for( i = 10; i > 0; --i ) ...
int i = -1;
int i = +1;
data = *ptr;
address = &obj;
int i = (int) floatNum;
int size = sizeof(floatNum); |
right to left |
3 |
->*
.* |
Member pointer selector
Member pointer selector |
ptr->*var = 24;
obj.*var = 24; |
left to right |
4 |
*
/
% |
Multiplication
Division
Modulus |
int i = 2 * 4;
float f = 10 / 3;
int rem = 4 % 3; |
left to right |
5 |
+
- |
Addition
Subtraction |
int i = 2 + 3;
int i = 5 - 1; |
left to right |
6 |
<<
>> |
Bitwise shift left
Bitwise shift right |
int flags = 33 << 1;
int flags = 33 >> 1; |
left to right |
7 |
<
<=
>
>= |
Comparison less-than
Comparison less-than-or-equal-to
Comparison greater-than
Comparison geater-than-or-equal-to |
if( i < 42 ) ...
if( i <= 42 ) ...
if( i > 42 ) ...
if( i >= 42 ) ... |
left to right |
8 |
==
!= |
Comparison equal-to
Comparison not-equal-to |
if( i == 42 ) ...
if( i != 42 ) ... |
left to right |
9 |
& |
Bitwise AND |
flags = flags & 42; |
left to right |
10 |
^ |
Bitwise exclusive OR |
flags = flags ^ 42; |
left to right |
11 |
| |
Bitwise inclusive (normal) OR |
flags = flags | 42; |
left to right |
12 |
&& |
Logical AND |
if( conditionA && conditionB ) ... |
left to right |
13 |
|| |
Logical OR |
if( conditionA || conditionB ) ... |
left to right |
14 |
? : |
Ternary conditional (if-then-else) |
int i = (a > b) ? a : b; |
right to left |
15 |
=
+=
-=
*=
/=
%=
&=
^=
|=
<<=
>>= |
Assignment operator
Increment and assign
Decrement and assign
Multiply and assign
Divide and assign
Modulo and assign
Bitwise AND and assign
Bitwise exclusive OR and assign
Bitwise inclusive (normal) OR and assign
Bitwise shift left and assign
Bitwise shift right and assign |
int a = b;
a += 3;
b -= 4;
a *= 5;
a /= 2;
a %= 3;
flags &= new_flags;
flags ^= new_flags;
flags |= new_flags;
flags <<= 2;
flags >>= 2; |
right to left |
16 |
, |
Sequential evaluation operator |
for( i = 0, j = 0; i < 10; i++, j++ ) ... |
left to right |
資料來源:
http://clanguage.h.baike.com/?m=article&id=74289
http://www.slyar.com/blog/c-operator-priority.html
http://en.cppreference.com/w/cpp/language/operator_precedence