C++ 运算符优先级和关联性

在本教程中,我们将借助示例来了解C ++中运算符的优先级和关联性。

C ++运算符优先级

如果单个表达式中有多个运算符,则不会同时评估这些运算。 相反,具有较高优先级的运算符将首先对其操作进行评估。

让我们看一个实例:

int x = 5 - 17 * 6;

在此,乘法运算符 * 的优先级高于减法运算符 - 。因此,17 * 6首先进行评估。

结果,以上表达式等效于

int x = 5 - (17 * 6);

如果我们想先进行评估5 - 17,则必须将它们放在括号内

int x = (5 - 17) * 6;

示例1:运算符优先级

#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 ++运算符优先级表

下表显示了C ++运算符的优先级。优先级1表示优先级最高的运算符,而优先级17表示优先级最低的运算符。

优先级
运算符
描述结合律
1::作用域从左至右
2a++
a--
type( )
type{ }
a( )
a[ ]
.
->
后缀/后缀增量
后缀/后缀减量

函数风格转型

函数风格转型

函数调用
下标
从对象访问成员
从对象ptr访问成员
从左至右
3++a
--a
+a
-a
!
~
(type)
*a
&a
sizeof
co_await
new new[ ]
delete delete[]
前缀增量
前缀减量


逻辑非
按位非
C风格转型
间接(解引用)
取地址
取大小
await表达式
动态内存分配
动态内存释放
从右至左
4.*
->*

成员对象选择器

成员指针选择器

从左至右
5a * b
a / b
a % b

取模

从左至右
6a + b
a - b

从左至右
7<<
>>

按位左移

按位右移

从左至右
8<=>三向比较运算符从左至右
9<
<=
>
>=
小于
小于或等于
大于
大于或等于
从左至右
10==
!=

等于

不相等

从左至右
11&按位与从左至右
12^按位异或从左至右
13|按位或从左至右
14&&逻辑与从左至右
15||逻辑或从左至右
16a ? b : c
throw
co_yield
=
+=
-=
*=
/=
%=
<<=
>>=
&=
^=
|=
三元条件运算
throw 运算符
yield 表达式(C++ 20)
赋值
加法赋值
减法赋值
乘法赋值
除法分配
模数赋值
按位左移赋值
按位右移赋值
按位与赋值
按位异或赋值
按位或赋值
从右至左
17,逗号运算符从左至右

关联性的属性将在稍后讨论。

C ++运算符的关联性

运算符的关联性是计算表达式的方向。例如,

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

示例2:运算符的关联性

#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