版权声明:自由转载-非商用-非衍生-保持署名 | 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.