在本教程中,我们将借助示例来了解C ++中运算符的优先级和关联性。
如果单个表达式中有多个运算符,则不会同时评估这些运算。 相反,具有较高优先级的运算符将首先对其操作进行评估。
让我们看一个实例:
int x = 5 - 17 * 6;
在此,乘法运算符 * 的优先级高于减法运算符 - 。因此,17 * 6首先进行评估。
结果,以上表达式等效于
int x = 5 - (17 * 6);
如果我们想先进行评估5 - 17,则必须将它们放在括号内:
int x = (5 - 17) * 6;
#include <iostream> using namespace std; int main() { // 首先评估17 * 6 int num1 = 5 - 17 * 6; //与num1等效的表达式 int num2 = 5 - (17 * 6); //强制编译器首先评估5-17 int num3 = (5 - 17) * 6; cout << "num1 = " << num1 << endl; cout << "num2 = " << num2 << endl; cout << "num3 = " << num3 << endl; return 0; }
输出结果
num1 = -97 num2 = -97 num3 = -72
注意:由于C ++中有很多运算符具有多个优先级,因此强烈建议我们使用括号使代码更具可读性。
下表显示了C ++运算符的优先级。优先级1表示优先级最高的运算符,而优先级17表示优先级最低的运算符。
优先级 | 运算符 | 描述 | 结合律 |
---|---|---|---|
1 | :: | 作用域 | 从左至右 |
2 | a++ a-- type( ) type{ } a( ) a[ ] . -> | 后缀/后缀增量 后缀/后缀减量 函数风格转型 函数风格转型 函数调用下标 从对象访问成员 从对象ptr访问成员 | 从左至右 |
3 | ++a --a +a -a ! ~ (type) *a &a sizeof co_await new new[ ] delete delete[] | 前缀增量 前缀减量 正 负 逻辑非 按位非 C风格转型 间接(解引用) 取地址 取大小 await表达式 动态内存分配 动态内存释放 | 从右至左 |
4 | .* ->* | 成员对象选择器 成员指针选择器 | 从左至右 |
5 | a * b a / b a % b | 乘 除 取模 | 从左至右 |
6 | a + b a - b | 加 减 | 从左至右 |
7 | << >> | 按位左移 按位右移 | 从左至右 |
8 | <=> | 三向比较运算符 | 从左至右 |
9 | < <= > >= | 小于 小于或等于 大于 大于或等于 | 从左至右 |
10 | == != | 等于 不相等 | 从左至右 |
11 | & | 按位与 | 从左至右 |
12 | ^ | 按位异或 | 从左至右 |
13 | | | 按位或 | 从左至右 |
14 | && | 逻辑与 | 从左至右 |
15 | || | 逻辑或 | 从左至右 |
16 | a ? b : c throw co_yield = += -= *= /= %= <<= >>= &= ^= |= | 三元条件运算 throw 运算符 yield 表达式(C++ 20) 赋值 加法赋值 减法赋值 乘法赋值 除法分配 模数赋值 按位左移赋值 按位右移赋值 按位与赋值 按位异或赋值 按位或赋值 | 从右至左 |
17 | , | 逗号运算符 | 从左至右 |
关联性的属性将在稍后讨论。
运算符的关联性是计算表达式的方向。例如,
int a = 1; int b = 4; // a = 4 a = b;
请看a=4;语句。 = 运算符的关联性是从右到左。 因此,b的值被赋值给a。
同样,多个运算符可以具有相同的优先级(如上表所示)。在表达式中使用相同优先级的多个运算符时,将根据它们的关联性对它们进行求值。
int a = 1; int b = 4; b += a -= 6;
运算符+=和-=运算符具有相同的优先级。由于这些运算符的关联性是从右到左,因此这是最后一条语句的求值方式。
a -= 6 首先评估。因此,a将为-5
然后,b += -5将被评估。因此,b将为-1
#include <iostream> using namespace std; int main() { int a = 1; int b = 4; // a -= 6 首先进行评估 b += a -= 6; cout << "a = " << a << endl; ; cout << "b = " << b; }
输出结果
a = -5 b = -1