优先级

版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 4.0

本次内容是:复合表达式的求值。尤其是 优先级结合性 部分可以作为字典查看。

1、优先级

在表达式求解过程中,优先级关系到表示如何分组,会影响整个表达式的值。其次是结合性,当优先级相同时,结合性决定求解次序。算术操作符具有左结合性,即从左至右结合

1
3 + 2 * 3 / 2 - 1

等价于

1
2
3
4
int tmp = 2 * 3;
int tmp2 = tmp / 2;
int tmp3 = tmp2 + 3;
int result = tmp3 - 1;

括号可以改变优先级,括号内的表达式先行计算。

2、结合性

结合性规定了具有相同优先级的操作符如何分组。如 赋值操作符 = 具有右结合性,所以允许将多个赋值操作串连起来:

1
2
val1 = val2 = val3;
(val1 = (val2 = val3)); //与上式等价

算术操作符 具有右结合性:

1
2
val1 * val2 / val3;
((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(expr)
  - - -
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.