這里是C和C++語言的運算符列表。所有列出的運算符皆含納於C++;第三個欄目里的內容也使用C來描述。應當注意的是C不支持運算符重載。
下列運算符在兩個語言中都是順序點(運算符未重載時): &&、||、?: 和 ,(逗號運算符)。
C++也包含類型轉換運算符const_cast、static_cast、dynamic_cast和reinterpret_cast,不在表中列出以維持簡潔。類型轉換運算符需要在表達式中明確使用括號,因此並不存在優先級的問題。
在C里有的運算符,除了逗號運算符和箭頭記頭的運算符以外,在Java、Perl、C#和PHP同樣也有相同的優先級、結合性和語義。
運算符優先級
| 優先級 | 運算符 | 敘述 | 示例 | 重載性 | 結合性 |
|---|---|---|---|---|---|
1 |
:: |
作用域解析(C++專有) | Class::age = 2; |
否 | 由左至右 |
2 |
++ |
后綴遞增 | i++ | ||
-- |
后綴遞減 | i-- | |||
{} |
組合 | {i++;a*=i;} | |||
() |
函數調用或變量初始化 | c_tor(int x, int y) : _x(x), _y(y * 10) {} | |||
[] |
數組訪問 | array[4] = 2; | |||
. |
以對象方式訪問成員 | obj.age = 34; | 否 | ||
-> |
以指針方式訪問成員 | ptr->age = 34; | |||
dynamic_cast |
運行時檢查類型轉換(C++專有) | Y& y = dynamic_cast<Y&>(x); | 否 | ||
static_cast |
未經檢查的類型轉換(C++專有) | Y& y = static_cast<Y&>(x); | 否 | ||
reinterpret_cast |
重定義類型轉換(C++專有) | int const* p = reinterpret_cast<int const*>(0x1234); | 否 | ||
const_cast |
更改非常量屬性(C++專有) | int* q = const_cast<int*>(p); | 否 | ||
typeid |
獲取類型信息(C++專有) | std::type_info const& t = typeid(x); | 否 | ||
3 |
++ |
前綴遞增 | ++i | 由右至左 | |
-- |
前綴遞減 | --i | |||
+ |
一元正號 | int i = +1; | |||
- |
一元負號 | int i = -1; | |||
!not |
邏輯非!的備用拼寫 |
if (!done) … | |||
~compl |
按位取反~的備用拼寫 |
flag1 = ~flag2; | |||
(type) |
強制類型轉換 | int i = (int)floatNum; | |||
* |
取指針指向的值 | int data = *intPtr; | |||
& |
取變量的地址 | int *intPtr = &data; | |||
sizeof |
某某的大小 | size_t s = sizeof(int); | 否 | ||
new |
動態內存分配(C++專有) | long* pVar = new long; | |||
new[] |
動態數組內存分配(C++專有) | long* array = new long[20]; | |||
delete |
動態內存釋放(C++專有) | delete pVar; | |||
delete[] |
動態數組內存釋放(C++專有) | delete [] array; | |||
4 |
.* |
成員對象選擇(C++專有) | obj.*var = 24; | 否 | 由左至右 |
->* |
成員指針選擇(C++專有) | ptr->*var = 24; | |||
5 |
* |
乘法 | int i = 2 * 4; | ||
/ |
除法 | float f = 10.0 / 3.0; | |||
% |
模數(取余) | int rem = 4 % 3; | |||
6 |
+ |
加法 | int i = 2 + 3; | ||
- |
減法 | int i = 5 - 1; | |||
7 |
<< |
比特左移 | int flags = 33 << 1; | ||
>> |
比特右移 | int flags = 33 >> 1; | |||
8 |
< |
小於關系 | if (i < 42) … | ||
<= |
小於等於關系 | if (i <= 42) ... | |||
> |
大於關系 | if (i > 42) … | |||
>= |
大於等於關系 | if (i >= 42) ... | |||
9 |
==eq |
等於關系==的備用拼寫 |
if (i == 42) ... | ||
!=not_eq |
不等於關系!=的備用拼寫 |
if (i != 42) … | |||
10 |
&bitand |
比特 AND&的備用拼寫 |
flag1 = flag2 & 42; | ||
11 |
^xor |
比特 XOR(獨占or)^的備用拼寫 |
flag1 = flag2 ^ 42; | ||
12 |
|bitor |
比特 OR(包含or)|的備用拼寫 |
flag1 = flag2 | 42; | ||
13 |
&&and |
邏輯 AND&&的備用拼寫 |
if (conditionA && conditionB) … | ||
14 |
||or |
邏輯 OR||的備用拼寫 |
if (conditionA || conditionB) ... | ||
15 |
c?t:f |
三元條件運算 | int i = a > b ? a : b; | 否 | 由右至左 |
16 |
= |
直接賦值 | int a = b; | ||
+= |
以和賦值 | a += 3; | |||
-= |
以差賦值 | b -= 4; | |||
*= |
以乘賦值 | a *= 5; | |||
/= |
以除賦值 | a /= 2; | |||
%= |
以取余數賦值 | a %= 3; | |||
<<= |
以比特左移賦值 | flags <<= 2; | |||
>>= |
以比特右移賦值 | flags >>= 2; | |||
&=and_eq |
以比特AND賦值&=的備用拼寫 |
flags &= new_flags; | |||
^=xor_eq |
以比特XOR賦值^=的備用拼寫 |
flags ^= new_flags; | |||
|=or_eq |
以比特OR賦值|=的備用拼寫 |
flags |= new_flags; | |||
17 |
throw |
拋出異常 | throw EClass(“Message”); | 否 | |
18 |
, |
逗號運算符 | for (i = 0, j = 0; i < 10; i++, j++) … | 由左至右 |
列表
在本表中,a、b和c代表有效值(來自變量或返回值的逐字常數或數值)、對象名稱,或適當的左值。
算術運算符[編輯] |
|||
| 運算符名稱 | 語法 | 可重載 | C里有 |
|---|---|---|---|
| 一元正號 | +a |
是 | 是 |
| 加法(總和) | a + b |
是 | 是 |
| 前綴遞增 | ++a |
是 | 是 |
| 后綴遞增 | a++ |
是 | 是 |
| 以加法賦值 | a += b |
是 | 是 |
| 一元負號(取反) | -a |
是 | 是 |
| 減法(差) | a - b |
是 | 是 |
| 前綴遞減 | --a |
是 | 是 |
| 后綴遞減 | a-- |
是 | 是 |
| 以減法賦值 | a -= b |
是 | 是 |
| 乘法(乘積) | a * b |
是 | 是 |
| 以乘法賦值 | a *= b |
是 | 是 |
| 除法(分之) | a / b |
是 | 是 |
| 以除法賦值 | a /= b |
是 | 是 |
| 模數(余數) | a % b |
是 | 是 |
| 以模數賦值 | a %= b |
是 | 是 |
比較運算符[編輯] |
|||
| 運算符名稱 | 語法 | 可重載 | C里有 |
| 小於 | a < b |
是 | 是 |
| 小於或等於 | a <= b |
是 | 是 |
| 大於 | a > b |
是 | 是 |
| 大於或等於 | a >= b |
是 | 是 |
| 不等於 | a != b |
是 | 是 |
| 等於 | a == b |
是 | 是 |
| 邏輯取反 | !a |
是 | 是 |
| 邏輯 AND | a && b |
是 | 是 |
| 邏輯 OR | a || b |
是 | 是 |
比特運算符[編輯] |
|||
| 運算符名稱 | 語法 | 可重載 | C里有 |
| 比特左移 | a << b |
是 | 是 |
| 以比特左移賦值 | a <<= b |
是 | 是 |
| 比特右移 | a >> b |
是 | 是 |
| 以比特右移賦值 | a >>= b |
是 | 是 |
| 比特一的補數 | ~a |
是 | 是 |
| 比特 AND | a & b |
是 | 是 |
| 以比特 AND 賦值 | a &= b |
是 | 是 |
| 比特 OR | a | b |
是 | 是 |
| 以比特 OR 賦值 | a |= b |
是 | 是 |
| 比特 XOR | a ^ b |
是 | 是 |
| 以比特 XOR 賦值 | a ^= b |
是 | 是 |
其它運算符[編輯] |
|||
| 運算符名稱 | 語法 | 可重載 | C里有 |
| 基本賦值 | a = b |
是 | 是 |
| 函數調用 | a() |
是 | 是 |
| 數組下標 | a[b] |
是 | 是 |
| 間接(向下參考) | *a |
是 | 是 |
| 的地址(參考) | &a |
是 | 是 |
| 成員指針 | a->b |
是 | 是 |
| 成員 | a.b |
否 | 是 |
| 間接成員指針 | a->*b |
是 | 否 |
| 間接成員 | a.*b |
否 | 否 |
| 轉換 | (type) a |
是 | 是 |
| 逗號 | a , b |
是 | 是 |
| 三元條件 | a ? b : c |
否 | 是 |
| 作用域解析 | a::b |
否 | 否 |
| 的大小 | sizeof a |
否 | 是 |
| 類型識別 | typeid type |
否 | 否 |
| 分配存儲區 | new type |
是 | 否 |
| 解除分配存儲區 | delete a |
是 | 否 |
語言擴展[編輯]
| 運算符名稱 | 語法 | 可重載 | C里有 | 提供者 |
|---|---|---|---|---|
| 標簽值 | && label |
否 | 是 | GCC |
| 取得型態 | typeof atypeof(expr) |
否 | 是 | GCC |
| 最小/最大值 | a <? ba >? b |
否 | 否 | GCC |
注解[編輯]
在C和C++中對運算符的約束,是語言的語法規范因素所指定的(在對應的標准中),而不是優先級列表。這造成了一些微妙的沖突。例如,在C中,條件表達式的語法是:
邏輯-OR-表達式 ? 表達式 : 條件-表達式
在C++中則是:
邏輯-or-表達式 ? 表達式 : 賦值-表達式
因此,這個表達式:
e = a ? b : c = d
兩個語言的語法分析結果並不相同。在C中,這個表達式被解析為:
e = ((a ? b : c) = d)
這是一個錯誤的語義,因為條件-表達式的結果並不是一個左值。在C++中,則解析為:
e = (a ? b : (c = d))
這是一個有效的表達式。
比特邏輯運算符的優先級一直受到批評[1]。在觀念里,&和|是類似於+和*的數值運算符。但是,表達式
a & b == 7
意謂
a & (b == 7),
當
a + b == 7
意謂
(a + b) == 7。
這就需要經常使用圓括號,以免有意料之外的結果。
酉加運算符,可用於操作數表達式的類型提升。例如下例:
template <class T> void f(T const& a, T const& b){}; int main() { int a[2]; int b[3]; f(a, b); // won't work! different values for "T"! f(+a, +b); // works! T is "int*" both }
