0. 什么是优先级
当表达式中只有一个运算符的时候,例如a + b
,不存在优先级,因为一定是计算加法。
当表达式中含有2个或2个以上的运算符的时候,表达式被称为复合表达式(compound expression)。
优先级(precedence) 指的是在计算复合表达式时,运算符按照规定的顺序计算。
例如a + b * c
要先计算乘法b * c
再计算加法。
本文将列出C++中所有的运算符及其优先级。
1. 优先级表
下面的表格,按照优先级将运算符分组。
- 组的位置越靠前,优先级越高;
- 同一组内的优先级相同。
(参考《C++ Primer(第5版)》)
结合律 | 运算符 | 功能 | 用例 | 左值与右值 |
---|---|---|---|---|
左 | :: | 全局作用域 | ::name | |
左 | :: | 类作用域 | class::name | |
左 | :: | 命名空间作用域 | namespace::name | |
左 | . | 成员访问 | object.member | 与运算对象相同 |
左 | -> | 成员访问 | pointer->member | 运算对象是一个指针类型,返回一个左值 |
左 | [ ] | 下标 | expr[expr] | |
左 | () | 函数调用 | name(expr_list) | |
左 | () | 类型构造 | type(expr_list) | |
右 | ++ | 后置递增运算符 | lvalue++ | 运算对象是左值,对象原始值的副本作为右值返回 |
右 | – | 后置递减运算符 | lvalue– | 运算对象是左值,对象原始值的副本作为右值返回 |
右 | typeid | 类型ID | typeid(type) | |
右 | typeid | 运行时类型ID | typeid(expr) | |
右 | explicit cast | 类型转换 | cast_name<type>(expr) | |
右 | ++ | 前置递增运算 | ++lvalue | 运算对象是左值,对象本身作为左值返回 |
右 | – | 前置递减运算符 | –lvalue | 运算对象是左值,对象本身作为左值返回 |
右 | ~ | 位求反 | ~expr | |
右 | ! | 逻辑非 | !expr | 运算对象和求值结果都是右值 |
右 | - | 一元负号 | -expr | 运算对象和求值结果都是右值 |
右 | + | 一元正号 | +expr | 运算对象和求值结果都是右值 |
右 | * | 解引用 | *expr | |
右 | & | 取地址 | &lvalue | |
右 | () | 类型转换 | (type) expr | |
右 | sizeof | 对象的大小 | sizeof expr | |
右 | sizeof | 类型的大小 | sizeof(type) | |
右 | sizeof… | 参数包的大小 | sizeof…(name) | |
右 | new | 创建对象 | new type | |
右 | new [] | 创建数组 | new type[size] | |
右 | delete | 释放对象 | delete expr | |
右 | delete [] | 释放数组 | delete [] expr | |
右 | noexcept | 能否抛出异常 | noexcept(expr) | |
左 | ->* | 指向成员选择的指针 | ptr->*ptr_to_member | |
左 | .* | 指向成员选择的指针 | obj.*ptr_to_member | |
左 | * | 乘法 | expr * expr | 运算对象和求值结果都是右值 |
左 | / | 除法 | expr / expr | 运算对象和求值结果都是右值 |
左 | % | 取模(取余) | expr % expr | 运算对象和求值结果都是右值 |
左 | + | 加法 | expr + expr | 运算对象和求值结果都是右值 |
左 | - | 减法 | expr - expr | 运算对象和求值结果都是右值 |
左 | << | 向左移位 | expr << expr | |
左 | >> | 向右移位 | expr >> expr | |
左 | < | 小于 | expr < expr | 运算对象和求值结果都是右值 |
左 | <= | 小于等于 | expr <= expr | 运算对象和求值结果都是右值 |
左 | > | 大于 | expr > expr | 运算对象和求值结果都是右值 |
左 | >= | 大于等于 | expr >= expr | 运算对象和求值结果都是右值 |
左 | == | 相等 | expr == expr | 运算对象和求值结果都是右值 |
左 | != | 不相等 | expr != expr | 运算对象和求值结果都是右值 |
左 | & | 位与 | expr & expr | |
左 | ^ | 位异或 | expr ^ expr | |
左 | | | 位或 | expr | expr | |
左 | && | 逻辑与 | expr && expr | 运算对象和求值结果都是右值 |
左 | || | 逻辑或 | expr || expr | 运算对象和求值结果都是右值 |
右 | ? : | 条件 | cond ? expr1 : expr2 | 当expr1和expr2都是左值或者能转换成同一种左值类型时,结果是左值;否则结构是右值 |
右 | = | 赋值 | lvalue = expr | 左侧运算对象是一个可修改的左值,结果是一个左值 |
右 | *=, /=, %= | 复合赋值 | lvalue += expr等 | 与赋值运算符一样 |
右 | +=, -= | |||
右 | <<=, >>= | |||
右 | &=, |=, ^= | |||
右 | throw | 抛出异常 | throw expr | |
左 | , | 逗号 | expr1, expr2 | 如果expr2是左值,则结果是左值;否则右值 |