| 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 |
C++中運算子優先順序的學習註解
提起運算子的優先順序,很多瞭解C++的過來人都會想:這有什麼難的?不就是誰的優先順序高就算誰麼。確實如此,運算子的優先順序不是一個大問題,但對於一個初學者來說,卻經常容易在上面迷糊與犯錯。而對於一個瞭解C++的人來說,我相信也會偶爾在上面摔倒,不信就繼續往下讀。
“優先順序高的先運算”帶來的困惑
C++中運算子的優先順序有一張表,表裡把運算子進行了分類,這張表是不需要死記硬背的,只要有個大致的輪廓就OK了。例如應該記住最低優先順序是逗號運算子,其次是賦值運算子,再其次是三目運算子。而關係運算子的優先順序高於邏輯運算子(不包括邏輯非運算),算術運算子的優先順序高於關係運算子,象++和﹣﹣的優先順序比前面幾個都高,但最高的要屬()了。知道這些後,你的腦海裡一定有一條準則了:優先順序高的先運算。那麼下面看一個例子:
int x=1,y=0;
!x&&x+y&&++y;
上面的語句中出現了!、&& 、+、++這四個運算子,那麼問題來了,到底先算誰呢?
有一個姓蔡的同學站起來說,++運算子在這裡面優先順序最高,理所應當最先算++,既先計算++y,再算!x,再算x+y,最後把它們&&起來。按照蔡同學的思路,第二步的結果是0&&x+y&&1,由於&&是嚴格運算,有一個為0結果既為0,所以不需要計算x+y了,整個語句的結果是:假。按照上面蔡同學的說法,執行完後y的值應該是1了,這對不對呢?
一位姓高的同學站起來反駁道,我覺得應該先計算!x,如果值為假,則不需要計算下去,最後結果為假。如果值為真,再計算x+y,同理如果其值為真,再去計算++y,否則最後結果也為假。
蔡同學不服起來說,高同學你覺得++和!誰的優先順序高呢?高同學答道,那當然是++高。蔡同學接著問,那為什麼還要先計算!呢?高同學答不出來了。
是呀,為什麼要先算!呢?
加括弧確定優先順序的方法
高同學說的是正確的,為什麼呢?下面我給大家解釋一下。當多個優先順序不同的運算子在一起時,為了不混淆,可以先加上括弧,這樣就分出層次了,相同層次的考慮結合性問題,當確定下來先算那塊時,再往這塊裡面深入。例如上面的例子,我們可以這樣加上括弧:從左向右看,由於!比&&優先順序高,所以有(!x),又由於&&比+優先順序低,所以有(x+y),而++優先順序高於&&,所以(++y)。這樣整個式子就變成了:(!x)&&(x+y)&&(++y),最外層的是兩個&&運算,由於&&的結合性是從左至右,所以上式可看成:A&&B&&C,先計算A,再計算B,最後算C。由於x=1,則!x就為假,後面的就不需要再算了,整個語句的值為假。執行完後,y的值沒變,還是0。
所以碰到不清楚先算誰後算誰時,先加個括弧看看,就明白了先後次序。下面做一個加括弧的練習:給語句c=a>b?a:b;加括弧。此語句有三個運算子:=、>、? :,應該怎樣加括弧呢?
第一種方案:c=((a>b)?a:b);
第二種方案:c=(a>(b?a:b));
第三種方案:(c=a)>(b?a:b);
應該是那一種呢?按照運算子優先順序的高低順序,>優先順序高於=,所以不可能把(c=a)括起來。而>優先順序高於? :運算子。所以也不可能把(b?a:b)括起來。因此,第一種答案正確。
下面再看一個類似的例子:
int i=8,j=4,k;
k=i<j?++i:++j;
猛然一看,有些人上來可能就要計算++i和++j了。這裡不妨先加括弧看看。從左至右看,<的優先順序高於=而且又高於? :,所以有k=(i<j)?++i:++j,再繼續向右看,由於++高於? :,所以k=(i<j)?(++i):(++j),這樣相當於k=A?B:C,先算A的值,若為真,則值為B,既算一下++i,若為假,則值為C,既算一下++j。整個語句執行完後,k的值為5,i的值為8,j的值為5。
所以運算子的優先順序千萬要小心,既不是想象的那麼難,也不是想象的那麼容易。