所有的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 a
typeof(expr) |
否 |
是 |
GCC
|
最小/最大值 |
a <? b
a >? 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-
|
溢位,包裹,截裁
|
?:
|
無
|
=
|
|
|=
|
截裁
|
<
|
無
|
<=>
|
|
+=
|
|
<<
|
溢位,包裹,截裁
|
>
|
無
|
|
|
參閱
參考資料
外部連結