Expressions
算术运算符¶
运算符 | 功能 |
---|---|
+ (单目) | 正 |
- (单目) | 负 |
* (双目) | 乘法 |
/ | 除法 |
% | 取模 |
+ (双目) | 加法 |
- (双目) | 减法 |
单目与双目运算符
单目运算符(又称一元运算符)指被操作对象只有一个的运算符,而双目运算符(又称二元运算符)的被操作对象有两个。例如 1 + 2
中加号就是双目运算符,它有 1
和 2
两个被操作数。此外 C++ 中还有唯一的一个三目运算符 ?:
。
算术运算符中有两个单目运算符(正、负)以及五个双目运算符(乘法、除法、取模、加法、减法),其中单目运算符的优先级最高。
其中取模运算符 %
意为计算两个整数相除得到的余数,即求余数。
而 -
为双目运算符时做减法运算符,如 2-1
;为单目运算符时做负值运算符,如 -1
。
使用方法如下
op=x-y*z
得到的 op
的运算值遵循数学中加减乘除的优先规律,首先进行优先级高的运算,同优先级自左向右运算,括号提高优先级。
位运算符¶
运算符 | 功能 |
---|---|
~ | 逐位非 |
& (双目) | 逐位与 |
| | 逐位或 |
^ | 逐位异或 |
<< | 逐位左移 |
>> | 逐位右移 |
位操作的意义请参考 位运算 页面。需要注意的是,位运算符的优先级低于普通的算数运算符。
自增/自减 运算符¶
有时我们需要让变量进行增加 1(自增)或者减少 1(自减),这时自增运算符 ++
和自减运算符 --
就派上用场了。
自增/自减运算符可放在变量前或变量后面,在变量前称为前缀,在变量后称为后缀,单独使用时前缀后缀无需特别区别,如果需要用到表达式的值则需注意,具体可看下面的例子。详细情况可参考 引用 介绍的例子部分。
i = 100;
op1 = i++; // op1 = 100,先 op1 = i,然后 i = i + 1
i = 100;
op2 = ++i; // op2 = 101,先 i = i + 1,然后赋值 op2
i = 100;
op3 = i--; // op3 = 100,先赋值 op3,然后 i = i - 1
i = 100;
op4 = --i; // op4 = 99,先 i = i - 1,然后赋值 op4
复合赋值运算符¶
复合赋值运算符实际上是表达式的缩写形式。
op=op+2
可写为 op+=2
op=op-2
可写为 op-=2
op=op*2
可写为 op*=2
比较运算符¶
运算符 | 功能 |
---|---|
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
== | 等于 |
!= | 不等于 |
其中特别需要注意的是要将等于运算符 ==
和赋值运算符 =
区分开来,这在判断语句中尤为重要。
if(op=1)
与 if(op==1)
看起来类似,但实际功能却相差甚远。第一条语句是在对 op 进行赋值,若赋值为非 0 时为真值,表达式的条件始终是满足的,无法达到判断的作用;而第二条语句才是对 op
的值进行判断。
逻辑运算符¶
运算符 | 功能 |
---|---|
&& | 逻辑与 |
|| | 逻辑或 |
! | 逻辑非 |
Result = op1 && op2; // 当 op1 与 op2 都为真时则 Result 为真
Result = op1 || op2; // 当 op1 或 op2 其中一个为真时则 Result 为真
Result = !op1; // 当 op1 为假时则 Result 为真
逗号运算符¶
逗号运算符可将多个表达式分隔开来,被分隔开的表达式按从左至右的顺序依次计算,整个表达式的值是最后的表达式的值。逗号表达式的优先级在所有运算符中的优先级是 最低 的。
exp1, exp2, exp3; // 最后的值为 exp3 的运算结果。
Result = 1 + 2, 3 + 4, 5 + 6;
//得到 Result 的值为 3 而不是 11,因为赋值运算符 "="
//的优先级比逗号运算符高,先进行了赋值运算才进行逗号运算。
Result = (1 + 2, 3 + 4, 5 + 6);
// 若要让 Result 的值得到逗号运算的结果则应将整个表达式用括号提高优先级,此时
// Result 的值才为 11。
成员访问运算符¶
运算符 | 功能 |
---|---|
[] | 数组下标 |
. | 对象成员 |
& (单目) | 取地址/获取引用 |
* (单目) | 间接寻址/解引用 |
-> | 指针成员 |
这些运算符用来访问对象的成员或者内存,除了最后一个运算符外上述运算符都可被重载。与 &
, *
和 ->
相关的内容请阅读 指针 和 引用 教程。这里还省略了两个很少用到的运算符 .*
和 ->*
,其具体用法可以参见 C++ 语言手册 。
auto result1 = v[1]; // 获取v中下标为2的对象
auto result2 = p.q; // 获取p对象的q成员
auto result3 = p -> q; // 获取p指针指向的对象的q成员,等价于 (*p).q
auto result4 = &v; // 获取指向v的指针
auto result5 = *v; // 获取v指针指向的对象
C++ 运算符优先级总表¶
来自 百度百科 ,有修改。
运算符 | 描述 | 例子 | 可重载性 |
---|---|---|---|
第一级别 | |||
:: | 作用域解析符 | Class::age = 2; | 不可重载 |
第二级别 | |||
() | 函数调用 | isdigit('1') | 可重载 |
() | 成员初始化 | c_tor(int x, int y) : _x(x), _y(y*10){}; | 可重载 |
[] | 数组数据获取 | array[4] = 2; | 可重载 |
-> | 指针型成员调用 | ptr->age = 34; | 可重载 |
. | 对象型成员调用 | obj.age = 34; | 不可重载 |
++ | 后自增运算符 | for (int i = 0; i < 10; i++) cout << i; | 可重载 |
-- | 后自减运算符 | for (int i = 10; i > 0; i--) cout << i; | 可重载 |
const_cast | 特殊属性转换 | const_cast<type_to>(type_from); | 不可重载 |
dynamic_cast | 特殊属性转换 | dynamic_cast<type_to>(type_from); | 不可重载 |
static_cast | 特殊属性转换 | static_cast<type_to>(type_from); | 不可重载 |
reinterpret_cast | 特殊属性转换 | reinterpret_cast<type_to>(type_from); | 不可重载 |
typeid | 对象类型符 | cout << typeid(var).name(); cout << typeid(type).name(); | 不可重载 |
第三级别 (从右向左结合) | |||
! | 逻辑取反 | if( !done ) … | 可重载 |
~ | 按位取反 | flags = ~flags; | 可重载 |
++ | 前自增运算符 | for (i = 0; i < 10; ++i) cout << i; | 可重载 |
-- | 前自减运算符 | for (i = 10; i > 0; --i) cout << i; | 可重载 |
- | 负号 | int i = -1; | 可重载 |
+ | 正号 | int i = +1; | 可重载 |
* | 指针取值 | int data = *intPtr; | 可重载 |
& | 值取指针 | int *intPtr = &data; | 可重载 |
new | 动态元素内存分配 | long *pVar = new long; MyClass *ptr = new MyClass(args); | 可重载 |
new [] | 动态数组内存分配 | long *array = new long[n]; | 可重载 |
delete | 动态析构元素内存 | delete pVar; | 可重载 |
delete [] | 动态析构数组内存 | delete [] array; | 可重载 |
(type) | 强制类型转换 | int i = (int) floatNum; | 可重载 |
sizeof | 返回类型内存 | int size = sizeof floatNum; int size = sizeof(float); | 不可重载 |
第四级别 | |||
->* | 类指针成员引用 | ptr->*var = 24; | 可重载 |
.* | 类对象成员引用 | obj.*var = 24; | 不可重载 |
第五级别 | |||
* | 乘法 | int i = 2 * 4; | 可重载 |
/ | 除法 | float f = 10.0 / 3.0; | 可重载 |
% | 取余数(模运算) | int rem = 4 % 3; | 可重载 |
第六级别 | |||
+ | 加法 | int i = 2 + 3; | 可重载 |
- | 减法 | int i = 5 - 1; | 可重载 |
第七级别 | |||
<< | 位左移 | int flags = 33 << 1; | 可重载 |
>> | 位右移 | int flags = 33 >> 1; | 可重载 |
第八级别 | |||
< | 小于 | if( i < 42 ) ... | 可重载 |
<= | 小于等于 | if( i <= 42 ) ... | 可重载 |
> | 大于 | if( i > 42 ) ... | 可重载 |
>= | 大于等于 | if( i >= 42 ) ... | 可重载 |
第九级别 | |||
== | 等于 | if( i == 42 ) ... | 可重载 |
!= | 不等于 | if( i != 42 ) ... | 可重载 |
第十级别 | |||
& | 位与运算 | flags = flags & 42; | 可重载 |
第十一级别 | |||
^ | 位异或运算 | flags = flags ^ 42; | 可重载 |
第十二级别 | |||
| | 位或运算 | flags = flags | 42; | 可重载 |
第十三级别 | |||
&& | 逻辑与运算 | if (conditionA && conditionB) ... | 可重载 |
第十四级别 | |||
|| | 逻辑或运算 | if (conditionA || conditionB) ... | 可重载 |
第十五级别 (从右向左结合) | |||
? : | 条件运算符 | int i = a > b ? a : b; | 不可重载 |
= | 赋值 | int a = b; | 可重载 |
+= | 加赋值运算 | a += 3; | 可重载 |
-= | 减赋值运算 | b -= 4; | 可重载 |
*= | 乘赋值运算 | a *= 5; | 可重载 |
/= | 除赋值运算 | a /= 2; | 可重载 |
%= | 模赋值运算 | a %= 3; | 可重载 |
&= | 位与赋值运算 | flags &= new_flags; | 可重载 |
^= | 位异或赋值运算 | flags ^= new_flags; | 可重载 |
|= | 位或赋值运算 | flags |= new_flags; | 可重载 |
<<= | 位左移赋值运算 | flags <<= 2; | 可重载 |
>>= | 位右移赋值运算 | flags >>= 2; | 可重载 |
第十六级别 (从右向左结合) | |||
throw | 异常抛出 | throw EClass("Message"); | 不可重载 |
第十七级别 | |||
, | 逗号分隔符 | for (i = 0, j = 0; i < 10; i++, j++) ... | 可重载 |
buildLast update and/or translate time of this article,Check the history
editFound smelly bugs? Translation outdated? Wanna contribute with us? Edit this Page on Github
peopleContributor of this article Ir1d, aofall
translateTranslator of this article Visit the original article!
copyrightThe article is available under CC BY-SA 4.0 & SATA ; additional terms may apply.