介紹
運算符是告訴編譯程序執(zhí)行特定算術(shù)或邏輯操作的符號。C語言的運算范圍很寬,把除了控制語句和輸入輸出以外的幾乎所有的基本操作都作為運算符處理。主要分為三大類:算術(shù)運算符、 關(guān)系運算符與邏輯運算符。除此之外,還有一些用于完成特殊任務(wù)的運算符。
運算符的優(yōu)先級與結(jié)合性
優(yōu)先級:C語言中,運算符的運算優(yōu)先級共分為15級。1級最高,15級最低。在表達(dá)式中,優(yōu)先級較高的先于優(yōu)先級較低的進(jìn)行運算。而在一個運算量兩側(cè)的運算符優(yōu)先級相同時,則按運算符的結(jié)合性所規(guī)定的結(jié)合方向處理。
結(jié)合性:C語言中各運算符的結(jié)合性分為兩種,即左結(jié)合性(自左至右)和右結(jié)合性(自右至左)。例如算術(shù)運算符的結(jié)合性是自左至右,即先左后右。如有表達(dá)式x-y+z則y應(yīng)先與"-"號結(jié)合,執(zhí)行x-y運算,然后再執(zhí)行+z的運算。這種自左至右的結(jié)合方向就稱為"左結(jié)合性"。而自右至左的結(jié)合方向稱為"右結(jié)合性"。最典型的右結(jié)合性運算符是賦值運算符。如x=y=z,由于“=”的右結(jié)合性,應(yīng)先執(zhí)行y=z再執(zhí)行x=(y=z)運算。C語言運算符中有不少為右結(jié)合性,應(yīng)注意區(qū)別,以避免理解錯誤。
優(yōu)先級 |
結(jié)合性 |
運算符 |
備注 |
1 |
左結(jié)合 |
()
[]
->
.
|
圓括號
下標(biāo)運算符
指向結(jié)構(gòu)體成員運算符
結(jié)構(gòu)體成員運算符
|
2 |
右結(jié)合 |
!
~
++
--
+
-
(類型)
*
&
sizeof
|
邏輯非運算符
按位取反運算符
前綴增量運算符
前綴減量運算符
正號運算符
負(fù)號運算符
類型轉(zhuǎn)換運算符
指針運算符
地址運算符
長度運算符
|
3 |
左結(jié)合 |
*
/
%
|
乘法運算符
除法運算符
取余運算符
|
4 |
左結(jié)合 |
+
-
|
加法運算符
減法運算符
|
5 |
左結(jié)合 |
<<
>>
|
左移運算符
右移運算符
|
6 |
左結(jié)合 |
<
<=
>
>=
|
關(guān)系運算符
|
7 |
左結(jié)合 |
==
!=
|
等于運算符
不等于運算符
|
8 |
左結(jié)合 |
&
|
按位與運算符
|
9 |
左結(jié)合 |
^
|
按位異或運算符
|
10 |
結(jié)合性 |
|
|
按位或運算符
|
11 |
左結(jié)合 |
&&
|
邏輯與運算符
|
12 |
左結(jié)合 |
||
|
邏輯或運算符
|
13 |
右結(jié)合 |
? :
|
條件運算符
|
14 |
右結(jié)合 |
=
+=
-=
*=
/=
%=
&=
^=
|=
<<=
>>=
|
賦值運算符
|
15 |
左結(jié)合 |
,
|
逗號運算符
|
備注
優(yōu)先級口訣:圓方括號、箭頭一句號,自增自減非反負(fù)、針強地址長度,乘除,加減,再移位,小等大等、等等不等,八位與,七位異,六位或,五與,四或,三疑,二賦,一真逗。
口訣解釋:“圓方括號、箭頭一句號”指的是第15級的運算符。其中圓方括號很明顯“()、[]”,箭頭指的是指向結(jié)構(gòu)體成員運算符“->”,句號指的是結(jié)構(gòu)體成員運算符“.”。 “自增自減非反負(fù)、針強地址長度”指的是第14級的運算符。其中非指的是邏輯運算符“!”,反指的是按位取反運算符“~”,負(fù)指的是負(fù)號運算符“-”,針指的是指針運算符“*”,強指的是強制類型轉(zhuǎn)換運算符,地址指的是地址運算符“&”,長度指的是長度運算符“sizeof”。“乘除,加減,再移位”移位指的是左移運算符“<<”和右移運算符“>>”,其中除法還包括了取余運算符“%”。“小等大等、等等不等”指的是第10級到第9級的運算符:<、<=、>和>=,等等指的是等于運算符==,不等指的是不等于運算符!=。 “八位與,七位異,六位或”其中 八位與指的是第8級的按位與運算符“&”,七位異指的是第7級的按位異或運算符“^”,六位或指的是第6級的按位或運算符“|”。 “五與,四或”指的是第5級、第4級的邏輯與運算符“&&”和邏輯或運算符“||”。“三疑,二賦,一真逗”指的是第3級到第1級的運算符。其中,三疑指的是條件運算符“?:”(三有雙重含義:即指優(yōu)先級別是三,它的運算符類型也是三目,疑也取“?”之意),二賦指的是賦值運算符=、+=、-=、*=、/=、%=、>>=、<<=、&=、^=和|= ,一真逗指的是第1級的“,”運算符,真字只是為了語句需要罷了。
由于C語言的運算符優(yōu)先級與C++的不完全一樣(主要是增加了幾個運算符),所以這個口訣不能完全實用于C++.但是應(yīng)該能夠兼容,大家可以比較一下他們的區(qū)別應(yīng)該就能夠很快掌握C++的優(yōu)先級的!當(dāng)然,如果真的不想背這些優(yōu)先級,那么可以在每次使用符號的地方都用上(),這樣就不用在意運算符優(yōu)先級了,這也是一個很好的編程習(xí)慣。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
優(yōu)先級
|
運算符
|
名稱或含義
|
使用形式
|
結(jié)合方向
|
說明
|
1
|
[]
|
數(shù)組下標(biāo)
|
數(shù)組名[常量表達(dá)式]
|
左到右
|
|
()
|
圓括號
|
(表達(dá)式)/函數(shù)名(形參表)
|
|
.
|
成員選擇(對象)
|
對象.成員名
|
|
->
|
成員選擇(指針)
|
對象指針->成員名
|
|
2
|
-
|
負(fù)號運算符
|
-表達(dá)式
|
右到左
|
單目運算符
|
(類型)
|
強制類型轉(zhuǎn)換
|
(數(shù)據(jù)類型)表達(dá)式
|
|
++
|
自增運算符
|
++變量名/變量名++
|
單目運算符
|
--
|
自減運算符
|
--變量名/變量名--
|
單目運算符
|
*
|
取值運算符
|
*指針變量
|
單目運算符
|
&
|
取地址運算符
|
&變量名
|
單目運算符
|
!
|
邏輯非運算符
|
!表達(dá)式
|
單目運算符
|
~
|
按位取反運算符
|
~表達(dá)式
|
單目運算符
|
sizeof
|
長度運算符
|
sizeof(表達(dá)式)
|
|
3
|
/
|
除
|
表達(dá)式/表達(dá)式
|
左到右
|
雙目運算符
|
*
|
乘
|
表達(dá)式*表達(dá)式
|
雙目運算符
|
%
|
余數(shù)(取模)
|
整型表達(dá)式/整型表達(dá)式
|
雙目運算符
|
4
|
+
|
加
|
表達(dá)式+表達(dá)式
|
左到右
|
雙目運算符
|
-
|
減
|
表達(dá)式-表達(dá)式
|
雙目運算符
|
5
|
<<
|
左移
|
變量<<表達(dá)式
|
左到右
|
雙目運算符
|
>>
|
右移
|
變量>>表達(dá)式
|
雙目運算符
|
6
|
>
|
大于
|
表達(dá)式>表達(dá)式
|
左到右
|
雙目運算符
|
>=
|
大于等于
|
表達(dá)式>=表達(dá)式
|
雙目運算符
|
<
|
小于
|
表達(dá)式<表達(dá)式
|
雙目運算符
|
<=
|
小于等于
|
表達(dá)式<=表達(dá)式
|
雙目運算符
|
7
|
==
|
等于
|
表達(dá)式==表達(dá)式
|
左到右
|
雙目運算符
|
!=
|
不等于
|
表達(dá)式!= 表達(dá)式
|
雙目運算符
|
8
|
&
|
按位與
|
表達(dá)式&表達(dá)式
|
左到右
|
雙目運算符
|
9
|
^
|
按位異或
|
表達(dá)式^表達(dá)式
|
左到右
|
雙目運算符
|
10
|
|
|
按位或
|
表達(dá)式|表達(dá)式
|
左到右
|
雙目運算符
|
11
|
&&
|
邏輯與
|
表達(dá)式&&表達(dá)式
|
左到右
|
雙目運算符
|
12
|
||
|
邏輯或
|
表達(dá)式||表達(dá)式
|
左到右
|
雙目運算符
|
13
|
?:
|
條件運算符
|
表達(dá)式1? 表達(dá)式2: 表達(dá)式3
|
右到左
|
三目運算符
|
14
|
=
|
賦值運算符
|
變量=表達(dá)式
|
右到左
|
|
/=
|
除后賦值
|
變量/=表達(dá)式
|
|
*=
|
乘后賦值
|
變量*=表達(dá)式
|
|
%=
|
取模后賦值
|
變量%=表達(dá)式
|
|
+=
|
加后賦值
|
變量+=表達(dá)式
|
|
-=
|
減后賦值
|
變量-=表達(dá)式
|
|
<<=
|
左移后賦值
|
變量<<=表達(dá)式
|
|
>>=
|
右移后賦值
|
變量>>=表達(dá)式
|
|
&=
|
按位與后賦值
|
變量&=表達(dá)式
|
|
^=
|
按位異或后賦值
|
變量^=表達(dá)式
|
|
|=
|
按位或后賦值
|
變量|=表達(dá)式
|
|
15
|
,
|
逗號運算符
|
表達(dá)式,表達(dá)式,…
|
左到右
|
從左向右順序運算
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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