C和C++運算子

所有的C语言运算符都被C++语言支持。C语言不支持运算符重载。

在不重载时，运算符&&、||、,（逗号运算符），在第一个操作数求值之后有一个顺序点。 

大部分C与C++运算符也可用于其它程序设计语言如C#、Java、Perl、PHP等，具有相同的优先级、结合性与语义。

 運算子優先級 
以下是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))
這是一個有效的表達式。

位元邏輯運算子的優先級一直受到批評。在觀念裡，&和|是類似於+和*的數值運算子。但是，表達式
    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-溢位,包裹,截裁?:無=|=截裁<無<=> +=<<溢位,包裹,截裁>無

 參閱 

 C
 C++

 參考資料 

 外部連結 
 Experimental results showing that developers have poor knowledge of binary operator precedence.
 Basic types & Operators

Category:C語言
Category:C++
Category:运算符_(编程)