首页 > 代码库 > C和C++运算符 (转)

C和C++运算符 (转)

这里是CC++语言的运算符列表。所有列出的运算符皆含纳于C++;第三个栏目里的内容也使用C来描述。应当注意的是C不支持运算符重载

下列运算符在两个语言中都是顺序点(运算符未重载时): &&||?: 和 ,(逗号运算符)。

C++也包含类型转换运算符const_caststatic_castdynamic_castreinterpret_cast,不在表中列出以维持简洁。类型转换运算符需要在表达式中明确使用括号,因此并不存在优先级的问题。

在C里有的运算符,除了逗号运算符和箭头记头的运算符以外,在Java、Perl、C#和PHP同样也有相同的优先级、结合性和语义。

  

运算符优先级

以下是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 = http://www.mamicode.com/*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) ... 
15c?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; 
17throw抛出异常throw EClass(“Message”);
18,逗号运算符for (i = 0, j = 0; i < 10; i++, j++) … 由左至右

列表

在本表中,abc代表有效值(来自变量或返回值的逐字常数或数值)、对象名称,或适当的左值。

算术运算符[编辑]

运算符名称语法可重载C里有
一元正号+a
加法(总和)+ b
前缀递增++a
后缀递增a++
以加法赋值+= b
一元负号(取反)-a
减法(差)- b
前缀递减--a
后缀递减a--
以减法赋值-= b
乘法(乘积)* b
以乘法赋值*= b
除法(分之)/ b
以除法赋值/= b
模数(余数)% b
以模数赋值%= b

比较运算符[编辑]

运算符名称语法可重载C里有
小于< b
小于或等于<= b
大于> b
大于或等于>= b
不等于!= b
等于== b
逻辑取反!a
逻辑 AND&& b
逻辑 OR|| b

比特运算符[编辑]

运算符名称语法可重载C里有
比特左移<< b
以比特左移赋值<<= b
比特右移>> b
以比特右移赋值>>= b
比特一的补数~a
比特 AND& b
以比特 AND 赋值&= b
比特 OR| b
以比特 OR 赋值|= b
比特 XOR^ b
以比特 XOR 赋值^= b

其它运算符[编辑]

运算符名称语法可重载C里有
基本赋值= b
函数调用a()
数组下标a[b]
间接(向下参考)*a
的地址(参考)&a
成员指针a->b
成员a.b
间接成员指针a->*b
间接成员a.*b
转换(type) a
逗号, b
三元条件? b : c
作用域解析a::b
的大小sizeof a
类型识别typeid type
分配存储区new type
解除分配存储区delete a

语言扩展[编辑]

运算符名称语法可重载C里有提供者
标签值&& labelGCC
取得型态typeof a
typeof(expr)
GCC
最小/最大值<? b
>? 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  }