当前位置:嗨网首页>书籍在线阅读

01-运算符优先级

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

附录D 运算符优先级

运算符优先级决定了运算符用于值的顺序。C++运算符分为18个优先级组,如表D.1所示。第1组中的运算符的优先级最高,第2组中运算符的优先级次之,依此类推。如果两个运算符被用于同一个操作数,则首先应用优先级高的运算符。如果两个运算符的优先级相同,则C++使用结合性规则来决定哪个运算符结合得更为紧密。同一组中运算符的优先级和结合性相同,不管是从左到右(表中L-R)还是从右到左(表中R-L)结合。从左到右的结合性意味着首先应用最左边的运算符,而从右到左的结合性则意味着首先应用最右边的运算符。

表D.1 C++运算符的优先级和结合性

| 运 算 符 | 结 合 性 | 含义 | | :----- | :----- | :----- | :----- | :----- | | 优先级第1组 | | :: | | 作用域解析运算符 | | 优先级第2组 | | (表达式) | | 分组 | | () | L-R | 函数调用 | | () | | 值构造,即type(expr) | | [ ] | | 数组下标 | | -> | | 间接成员运算符 | | . | | 直接成员运算符 | | const_cast | | 专用的类型转换 | | dynamic_cast | | 专用的类型转换 | | reinterpret_cast | | 专用的类型转换 | | static_cast | | 专用的类型转换 | | typeid | | 类型标识 | | ++ | | 加1运算符,后缀 | | - - | | 减1运算符,后缀 | | 优先级第3组(全是一元运算符) | | ! | R-L | 逻辑非 | | ~ | | 位非 | | + | | 一元加号(正号) | | - | | 一元减号(负号) | | ++ | | 加1运算符,前缀 | | - - | | 减1运算符,前缀 | | & | | 地址 | | | | 解除引用(间接值) | | () | | 类型转换,即(type)expr | | sizeof | | 长度,以字节为单位 | | new | | 动态分配内存 | | new [ ] | | 动态分配数组 | | delete | | 动态释放内存 | | delete [ ] | | 动态释放数组 | | 优先级第4组 | | . | L-R | 成员解除引用 | | -> | | 间接成员解除引用 | | 优先级第5组(全是二元运算符) | | | L-R | 乘 | | / | | 除 | | ^ | | 模(余数) | | 优先级第6组(全是二元运算符) | | + | L-R | 加 | | - | | 减 | | 优先级第7组 | | << | L-R | 左移 | | >> | | 右移 | | 优先级第8组 | | < | L-R | 小于 | | <= | | 小于或等于 | | >= | | 大于或等于 | | > | | 大于 | | 优先级第9组 | | = = | L-R | 等于 | | != | | 不等于 | | 优先级第10组(一元运算符) | | & | L-R | 按位AND | | 优先级第11组 | | ^ | L-R | 按位XOF(异或) | | 优先级第12组 | | | | L-R | 按位OR | | 优先级第13组 | | && | L-R | 逻辑AND | | 优先级第14组 | | || | L-R | 逻辑OR | | 优先级第15组 | | :? | R-L | 条件 | | 优先级第16组 | | = | R-L | 简单赋值 | | * = | | 乘并赋值 | | /= | | 除并赋值 | | %= | | 求模并赋值 | | += | | 加并赋值 | | -= | | 减并赋值 | | &= | | 按位AND并赋值 | | ^= | | 按位XOR并赋值 | | |= | | 按位OR并赋值 | | <<= | | 左移并赋值 | | >>= | | 右移并赋值 | | 优先级第17组 | | throw | L-R | 引发异常 | | 优先级第18组 | | , | L-R | 将两个表达式合并成一个 |

有些符号(如*或&)被用作多个运算符。在这种情况下,一种形式是一元(一个操作数),另一种形式是二元(两个操作数),编译器将根据上下文来确定使用哪种形式。对于同一个符号可以两种方式使用的情况,表D.1将运算符标记为一元组或二元组。

下面介绍一些优先级和结合性的例子。

对于下面的例子,编译器必须决定先将5和3相加,还是先将5和6相乘:

3 + 5 * 6

*运算符的优先级比+运算符高,所以它被首先用于5,因此表达式变成3 +30,即33。

对于下面的例子,编译器必须决定先将120除以6,还是先将6和5相乘:

120 / 6 * 5

/和的优先级相同,但这些运算符从左到右结合的。这意味着首先应用操作数(6)左侧的运算符,因此表达式变为205,即100。

对于下面的例子,编译器必须决定先对str递增还是先对str解除引用:

char * str = "Whoa";
char ch = *str++;

后缀++运算符的优先级比一元运算符高,这意味着加号运算符将对str进行操作,而不是对str进行操作。也就是说,将指针加1,使之指向下一个字符,而不是修改被指针指向的字符。不过,由于++是后缀形式,因此将在将*str的值赋给ch后,再将指针加1。因此,上述表达式将字符W赋给ch,然后移动指针str,使之指向字符h。

下面是一个类似的例子:

char * str = "Whoa";
char ch = *++str;

前缀++运算符和一元运算符的优先级相同,但它们是从右到左结合的。因此,str(不是str)将被加1。因为++运算符是前缀形式,所以首先将str加1,然后将得到的指针执行解除引用的操作。因此,str将指向字符h,并将字符h赋给ch。

注意,表D.1在“优先级”行中使用一元或二元来区分使用同一个符号的两个运算符,如一元地址运算符和二元按位AND运算符。

附录B列出了一些运算符的替代表示。