運算符優先順序

運算符優先順序

在一個表達式中可能包含多個有不同運算符連接起來的、具有不同數據類型的數據對象;由於表達式有多種運算,不同的結合順序可能得出不同結果甚至出現錯誤運算錯誤,因為當表達式中含多種運算時,必須按一定順序進行結合,才能保證運算的合理性和結果的正確性、唯一性。

優先順序從上到下依次遞減,最上面具有最高的優先順序,逗號操作符具有最低的優先順序。表達式的結合次序取決於表達式中各種運算符的優先順序。優先順序高的運算符先結合,優先順序低的運算符后結合,同一行中的運算符的優先順序相同。

簡介


每種同類型的運算符都有內部的運算符優先順序,不同類型的運算符之間也有相應的優先順序順序。一個表達式中既可以包括相同類型的運算符,也可以包括不同類型的運算符或者函數。當多種運算符出現在同一個表達式中時,應該先按照不同類型運算符間的優先順序進行運算。各種運算符間的優先順序如下:數值運算符、字元串運算符、關係運算符、邏輯運算符。可以用括弧改變優先順序順序,使得括弧內的運算優先於括弧外的運算。對於多重括弧,總是由內到外強製表達式的某些部分優先運行。括弧內的運算總是最優先計算。

優先順序


優先順序與求值順序無關。如a+b && b*c,雖然*優先順序最高,但這個表達式求值順序是從左到右。
優先順序從上到下依次遞減,最上面具有最高的優先順序,逗號操作符具有最低的優先順序。
相同優先順序中,按結合性進行結合。大多數運算符結合性是從左到右,只有三個優先順序是從右至左結合的,它們是單目運算符、條件運算符、賦值運算符。
基本的優先順序需要記住:
指針最優,單目運算優於雙目運算。如正負號。
先算術運算,后移位運算,最後位運算。請特別注意:1 << 3 + 2 & 7等價於 (1 << (3 + 2))&7.
邏輯運算最後結合。

C語言優先順序


優先順序運算符名稱或含義使用形式結合方向說明
1[]數組下標數組名[整型表達式]左到右
()圓括弧(表達式)/函數名(形參表)
.成員選擇(對象)對象。成員名
->成員選擇(指針)對象指針->成員名
2-負號運算符-算術類型表達式右到左單目運算符
(type)強制類型轉換(純量數據類型)純量表達式
++自增運算符++純量類型可修改左值表達式單目運算符
--自減運算符--純量類型可修改左值表達式單目運算符
*取值運算符*指針類型表達式單目運算符
&取地址運算符&表達式單目運算符
!邏輯非運算符!純量類型表達式單目運算符
~按位取反運算符~整型表達式單目運算符
sizeof長度運算符
sizeof 表達式
sizeof(類型)
3/表達式/表達式左到右雙目運算符
*表達式*表達式雙目運算符
%餘數(取模)整型表達式%整型表達式雙目運算符
4+表達式+表達式左到右雙目運算符
-表達式-表達式雙目運算符
5<<左移整型表達式<<整型表達式左到右雙目運算符
>>右移整型表達式>>整型表達式雙目運算符
6>大於表達式>表達式左到右雙目運算符
>=大於等於表達式>=表達式雙目運算符
<小於表達式<表達式雙目運算符
<=小於等於表達式<=表達式雙目運算符
7==等於表達式==表達式左到右雙目運算符
!=不等於表達式!= 表達式雙目運算符
8&按位與整型表達式&整型表達式左到右雙目運算符
9^按位異或整型表達式^整型表達式左到右雙目運算符
10|按位或整型表達式|整型表達式左到右雙目運算符
11&&邏輯與表達式&&表達式左到右雙目運算符
12||邏輯或表達式||表達式左到右雙目運算符
13?:條件運算符表達式1? 表達式2: 表達式3右到左三目運算符
14=賦值運算符可修改左值表達式=表達式右到左
/=除后賦值可修改左值表達式/=表達式
*=乘后賦值可修改左值表達式*=表達式
%=取模后賦值可修改左值表達式%=表達式
+=加后賦值可修改左值表達式+=表達式
-=減后賦值可修改左值表達式-=表達式
<<=左移后賦值可修改左值表達式<<=表達式
>>=右移后賦值可修改左值表達式>>=表達式
&=按位與后賦值可修改左值表達式&=表達式
^=按位異或后賦值可修改左值表達式^=表達式
|=按位或后賦值可修改左值表達式|=表達式
15,逗號運算符表達式,表達式,…左到右從左向右順序結合
說明:
同一優先順序的運算符,結合次序由結合方向所決定。
簡單記就是:! > 算術運算符 > 關係運算符 > && > || > 賦值運算符

C語言


C++

運算符描述例子可重載性
第一級別
::作用域解析符Class::age = 2;不可重載
第二級別
()函數調用isdigit('1')可重載
()成員初始化c_tor(int x, int y) : _x(x), _y(y*10){};可重載
[]數組數據獲取array[4] = 2;可重載
->指針型成員調用ptr->age = 34;可重載
.對象型成員調用obj.age = 34;不可重載
++后自增運算符for( int i = 0; i < 10; i++ ) cout << i;可重載
--后自減運算符for( int i = 10; i > 0; i-- ) cout << i;可重載
const_cast特殊屬性轉換const_cast(type_from);不可重載
dynamic_cast特殊屬性轉換dynamic_cast(type_from);不可重載
static_cast特殊屬性轉換static_cast(type_from);不可重載
reinterpret_cast特殊屬性轉換reinterpret_cast(type_from);不可重載
typeid對象類型符
cout « typeid(var).name();
cout « typeid(type).name();
不可重載
第三級別(具有右結合性)
!邏輯取反if( !done ) …可重載
not! 的另一種表達
~按位取反flags = ~flags;可重載
compl~的另一種表達
++預自增運算符for( i = 0; i < 10; ++i ) cout << i;可重載
--預自減運算符for( i = 10; i > 0; --i ) cout << i;可重載
-負號int i = -1;可重載
+正號int i = +1;可重載
*指針取值int data = *intPtr;可重載
&值取指針int *intPtr = &data;可重載
new動態元素內存分配
long *pVar = new long;
MyClass *ptr = new MyClass(args);
可重載
new []動態數組內存分配long *array = new long[n];可重載
delete動態析構元素內存delete pVar;可重載
delete []動態析構數組內存delete [] array;可重載
(type)強制類型轉換int i = (int) floatNum;可重載
sizeof返回類型內存
int size = sizeof floatNum;
int size = sizeof(float);
不可重載
第四級別
->*類指針成員引用ptr->*var = 24;可重載
.*類對象成員引用obj.*var = 24;不可重載
第五級別
*乘法int i = 2 * 4;可重載
/除法float f = 10.0 / 3.0;可重載
%取餘數(模運算)int rem = 4 % 3;可重載
第六級別
+加法int i = 2 + 3;可重載
-減法int i = 5 - 1;可重載
第七級別
<<位左移int flags = 33 << 1;可重載
>>位右移int flags = 33 >> 1;可重載
第八級別
<小於if( i < 42 ) …可重載
<=小於等於if( i <= 42 ) ...可重載
>大於if( i > 42 ) …可重載
>=大於等於if( i >= 42 ) ...可重載
第九級別
==恆等於if( i == 42 ) ...可重載
eq== 的另一種表達
!=不等於if( i != 42 ) …可重載
not_eq!=的另一種表達
第十級別
&位且運算flags = flags & 42;可重載
bitand&的另一種表達
第十一級別
^位異或運算flags = flags ^ 42;可重載
xor^的另一種表達
第十二級別
|位或運算flags = flags | 42;可重載
bitor|的另一種表達
第十三級別
&&邏輯且運算if( conditionA && conditionB ) …可重載
and&&的另一種表達
第十四級別
||邏輯或運算if( conditionA || conditionB ) ...可重載
or||的另一種表達
第十五級別(具有右結合性)
? :條件運算符int i = (a > b) ? a : b;不可重載
第十六級別(具有右結合性)
=賦值int a = b;可重載
+=加賦值運算a += 3;可重載
-=減賦值運算b -= 4;可重載
*=乘賦值運算a *= 5;可重載
/=除賦值運算a /= 2;可重載
%=模賦值運算a %= 3;可重載
&=位且賦值運算flags &= new_flags;可重載
and_eq&= 的另一種表達
^=位異或賦值運算flags ^= new_flags;可重載
xor_eq^=的另一種表達
|=位或賦值運算flags |= new_flags;可重載
or_eq|=的另一種表達
<<=位左移賦值運算flags <<= 2;可重載
>>=位右移賦值運算flags >>= 2;可重載
第十七級別
throw異常拋出throw EClass(“Message”);不可重載
第十八級別
,逗號分隔符for( i = 0, j = 0; i < 10; i++, j++ ) …可重載

Java

運算符結合性
[ ] . ( ) (方法調用)從左向右
! ~ ++ -- +(一元運算) -(一元運算)從右向左
* / %從左向右
+ -從左向右
<< >> >>>從左向右
< <= > >= instanceof從左向右
== !=從左向右
&從左向右
^從左向右
|從左向右
&&從左向右
||從左向右
?:從右向左
=從右向左
一個特殊的例子:
public class stlye
{
public static void main(String[] args)
{
int a=10,b=6;
System.out.println("改變之前的數:a="+a+",b="+b);
a-=b++;
System.out.println("改變之後的數:a="+a+",b="+b);
}
}
運算結果為:
改變之前的數:a=10,b=6
改變之後的數:a=4,b=7
因為b++運算中先執行++,再返回後置++運算表達式(b++)的返回值(6)給-=運算符。
在這個程序中a-=b++等於a=a-b++=10-6,所以a=4。

C#

優先順序類別運算符
1基本(x) x.y f(x) a[x] x++ x-- new typeof sizeof checked unchecked
2單目+ - ! ~ ++x --x (T)x
3乘法與除法* / %
4加法與減法+ -
5移位運算<< >>
6關係運算< > <= >=
7條件等== !=
8位邏輯與&
9位邏輯異或^
10位邏輯或|
11條件與&&
12條件或
13條件?:
14賦值=
一個特殊的例子:
class Program
{
static void Main(string[] args)
{
int a; a = 10; int b = 4;
a += b++;
Console.WriteLine("a={0}",a);
Console.WriteLine("b={0}", b);
Console.ReadLine();
}
}
運算結果為:
a=14
b=5
在這個程序中a+=b等於a=a+b=10+4,因為 b++ 時返回了一個臨時變數后才進行自增。

VisualBasic

優先順序類別運算符
1乘方^
2取負-
3*
3/
4四捨五入除/位移\
5取模Mod
6+
6-
7字元串合併& 或 +
8相等=
8大於>
8大於等於>=
8小於<
8小於等於<=
8不等於<>
8同類對象Is
8Like運算Like
9Not
10And
11Or
12異或Xor
13邏輯等Eqv
14邏輯大於等於(蘊含)Imp