C和C++运算符
这里是C和C++语言的运算符列表。所有列出的运算符皆含纳于C++;第三个栏目里的内容也使用C来描述。应当注意的是C不支持运算符重载(又称运算符重载)。
下列运算符在两个语言中都是顺序点(运算符未重载时): &&、||、?: 和 ,(逗号运算符)。
C++也包含类型转换运算符const_cast、static_cast、dynamic_cast和reinterpret_cast,不在表中列出以维持简洁。类型转换运算符需要在表达式中明确使用括号,因此并不存在优先级的问题。
在C里有的运算符,除了逗号运算符和箭头记头的运算符以外,在Java、Perl、C#和PHP同样也有相同的优先级、结合性和语义。
目录
- 1 运算符优先级
- 2 列表
- 2.1 算术运算符
- 2.2 比较运算符
- 2.3 位运算符
- 2.4 其它运算符
- 2.5 语言扩展
- 3 注解
|
[编辑] 运算符优先级
以下是C++编程语言中的所有运算符的优先级和结合性列表。
优先级 |
运算符 |
叙述 |
示例 |
重载性 |
结合性 |
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 a
typeof(expr)
|
否 |
是 |
GCC |
最小/最大值 |
a <? b
a >? 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。
这就需要经常使用圆括号,以免有意料之外的结果。