C和C++運算子
運算子優先級
    
以下是C++程式語言中的所有運算子的優先級和結合性列表。
| 优先级 | 運算子 | 敘述 | 示例 | 重载性 | 結合性 | 
|---|---|---|---|---|---|
| 1 | :: | 作用域解析(C++专有) | Class::age = 2; | 否 | 由左至右 | 
| 2 | ++ | 后缀递增 | i++ | ||
| -- | 后缀递减 | i-- | |||
| () | 函数调用或函数调用形式的类型转换 | int x = f(); | |||
| [] | 数组访问 | 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 | <=> | 三路比较(C++20) | auto flags = 33 <=> 1; | ||
| 9 | < | 小于关系 | if (i < 42) … | ||
| <= | 小于等于关系 | if (i <= 42) ... | |||
| > | 大于关系 | if (i > 42) … | |||
| >= | 大于等于关系 | if (i >= 42) ... | |||
| 10 | == | 等于关系 | if (i == 42) ... | ||
| !=not_eq | 不等于关系 !=的备用拼写 | if (i != 42) … | |||
| 11 | &bitand | 位元 AND &的备用拼写 | flag1 = flag2 & 42; | ||
| 12 | ^xor | 位元 XOR(独占or) ^的备用拼写 | flag1 = flag2 ^ 42; | ||
| 13 | |bitor | 位元 OR(包含or) |的备用拼写 | flag1 = flag2 | 42; | ||
| 14 | &&and | 逻辑 AND &&的备用拼写 | if (conditionA && conditionB) … | ||
| 15 | ||or | 逻辑 OR ||的备用拼写 | if (conditionA || conditionB) ... | ||
| 16 | c?t:f | 三元条件运算 | int i = a > b ? a : b; | 否 | 由右至左 | 
| 17 | = | 直接赋值 |  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; | |||
| 18 | throw | 抛出异常 | throw EClass("Message"); | 否 | |
| 19 | , | 逗號運算子 | 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 | 是 | 是 | 
| 三路比较 | 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 < 4.3 | 
註解
    
在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  
}
安全问题
    
下表指出了各个运算符可能导致的安全问题:
| 符號 | 安全性 | 符號 | 安全性 | 符號 | 安全性 | 符號 | 安全性 | 
|---|---|---|---|---|---|---|---|
| + | 溢位,包裹,循環 | -= | 溢位,包裹,循環,截裁 | >> | 無 | >= | 無 | 
| - | 溢位,包裹,循環 | *= | 溢位,包裹,循環,截裁 | & | 無 | == | 無 | 
| * | 溢位,包裹,循環 | /= | 溢位,截裁 | ~ | 無 | != | 無 | 
| % | 溢位 | <<= | 溢位,包裹,循環,截裁 | ! | 無 | && | 無 | 
| ++ | >>= | 截裁 | un+ | 無 | || | 無 | |
| -- | &= | 截裁 | un- | 溢位,包裹,截裁 | ?: | 無 | |
| = | |= | 截裁 | < | 無 | <=> | ||
| += | << | 溢位,包裹,截裁 | > | 無 | 
參考資料
    
- . [2007-03-01]. (原始内容存档于2015-02-03).
外部連結
    
- Experimental results(页面存档备份,存于) showing that developers have poor knowledge of binary operator precedence.
- Basic types & Operators(页面存档备份,存于)
    This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.