版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 4.0
本次内容是:复合表达式的求值。尤其是 优先级 和 结合性 部分可以作为字典查看。
1、优先级
在表达式求解过程中,优先级关系到表示如何分组,会影响整个表达式的值。其次是结合性,当优先级相同时,结合性决定求解次序。算术操作符具有左结合性,即从左至右结合
1 | 3 + 2 * 3 / 2 - 1 |
等价于
1 | int tmp = 2 * 3; |
括号可以改变优先级,括号内的表达式先行计算。
2、结合性
结合性规定了具有相同优先级的操作符如何分组。如 赋值操作符 =
具有右结合性,所以允许将多个赋值操作串连起来:
1 | val1 = val2 = val3; |
而 算术操作符 具有右结合性:
1 | val1 * val2 / val3; |
下表是按照优先级顺序给出操作符,并用空行分成不同的段,每段内的优先级相同,且都高于后面各段的优先级。
操作符 | 结合性 | 功能 | 用法 |
---|---|---|---|
:: | L | 全局作用域 | ::name |
:: | L | 类作用域 | class::name |
:: | L | 名字空间作用域 | namespace::name |
- | - | - | |
. | L | 成员选择 | object.member |
-> | L | 成员选择 | pointer->member |
[] | L | 下标 | variable[expr] |
() | L | 函数调用 | name(expr_list) |
() | L | 函数构造 | type(expr_list) |
- | - | - | |
++ | R | 后自增 | lvalue++ |
– | R | 后自减 | lvalue– |
typeid | R | 类型ID | typeid(type) |
typeid | R | 运行时ID | typeid(expr) |
显式强制类型转换 | R | 类型转换 | cast_name |
- | - | - | |
sizeof | R | 对象大小 | sizeof expr |
sizeof | R | 类型大小 | sizeof(type) |
++ | R | 前自增 | ++lvalue |
– | R | 前自减 | –lvalue |
~ | R | 位求反 | ~expr |
! | R | 逻辑非 | !expr |
- | R | 一元负号 | -expr |
+ | R | 一元正号 | +expr |
* | R | 解引用 | *expr |
& | R | 取地址 | &expr |
() | R | 类型转换 | (type)expr |
new | R | 创建对象 | new type |
delete | R | 释放对象 | delete expr |
delete[] | R | 释放数组 | delete[] expr |
- | - | - | |
->* | L | 指向成员操作的指针 | ptr->*ptr_to_member |
.* | L | 指向成员操作的指针 | obj.*ptr_to_member |
- | - | - | |
* | L | 乘法 | expr * expr |
/ | L | 除法 | expr / expr |
% | L | 求模(求余) | expr % expr |
- | - | - | |
+ | L | 加法 | expr + expr |
- | L | 减法 | expr - expr |
- | - | - | |
<< | L | 位左移 | expr << expr |
>> | L | 为右移 | expr >> expr |
- | - | - | |
< | L | 小于 | expr < expr |
<= | L | 小等于 | expr <= expr |
> | L | 大于 | expr > expr |
>= | L | 大等于 | expr >= expr |
- | - | - | |
== | L | 等于 | expr == expr |
!= | L | 不等于 | expr != expr |
- | - | - | |
& | L | 位与 | expr & expr |
- | - | - | |
^ | L | 位异或 | expr ^ expr |
- | - | - | |
| | L | 位或 | expr | expr |
- | - | - | |
&& | L | 逻辑与 | expr && expr |
- | - | - | |
|| | L | 逻辑或 | expr || expr |
- | - | - | |
?: | R | 条件操作 | expr |
- | - | - | |
= | R | 赋值操作 | lvalue = expr |
*=, /=, %= | R | 复合赋值操作 | expr *= expr等 |
+=, -= | R | 复合赋值操作 | expr += expr等 |
<<=, >>= | R | 复合赋值操作 | expr <<= expr等 |
&=, |=, ^= | R | 复合赋值操作 | expr &= expr等 |
- | - | - | |
throw | R | 抛出异常 | throw expr |
- | - | - | |
, | R | 逗号 | expr, expr |
举例
考虑:如果字符串不是以’s’结尾则加上’s’,分析下列语句
1 | string s = s + s[s.size() - 1] == 's' ? "" : "s"; |
分析:
根据上表知道优先级为:.
= ()
= []
> -
= +
> ==
> ?:
> =
;可知上述语句的结合顺序是
1 | (string s = (((s + (s[(s.size()) - 1])) == 's') ? "" : "s")); |
很明显不能得到想要的结果,改成如下形式即可
1 | string s = s + (s[s.size() - 1] == 's' ? "" : "s"); |
END.