Post-C++ 运算符优先级中的增量和赋值 table
Post-increment vs Assignment in C++ operation precedence table
我偶然发现了https://en.cppreference.com/w/cpp/language/operator_precedence
在图表上,我看到 post-增量运算符 (++) 远高于赋值运算符 (=)。
不过,我知道
int a[] = {10,20};
int* b = &a[0];
*(b++) = 5;
cout << a[0] << endl; // 5
cout << a[1] << endl; // 20
cout << *b << endl; // 20, now points to a[1]
我总是想当然地认为 post-increment 发生在赋值运算符之后。但是,如果我按照操作优先级表,那么 post-increment 是不是应该在 =
操作之前发生?答案不是应该是 a={10, 5}
而不是 a={5, 20}
吗?
Post 增量 (b++
) 增量 b
, 然后 returns b
的前一个值.
预递增(++b
)递增b
,然后returnsb
.[=18的新值=]
要获得您期望的行为,请将 post-increment 更改为 pre-increment。
例如:
#include <iostream>
int main() {
int a[] = {10, 20};
int *b = &a[0];
*(++b) = 5;
std::cout << a[0] << std::endl;
std::cout << a[1] << std::endl;
std::cout << *b << std::endl;
}
产生以下输出:
10
5
5
"Precedence" 具有误导性。它通常与 求值顺序 (先发生的事情)没有什么关系,而是为了求值的目的确定每个运算符的操作数是什么。但是让我们检查一下您的示例。
*(b++) = 5;
意思是5
要赋给左边的左值。从 C++17 开始,我们知道 5
完全在 *(b++)
之前求值。在此之前,它们可以按任何顺序进行评估。
现在,b++
具有"increment b
, but evaluate to its previous value"的含义。所以 b++
可能会导致增量发生在赋值发生之前,是的,但是 (b++)
的值是增量发生之前的地址。这就是为什么 b
在一个表达式中更新为指向下一个元素,同时修改当前元素。
Table 是正确的。结果没有混淆。
只要记住 post increment(PI) or decrement(DI),在当前包含 PI 或 DI 的语句之后执行 +1 或 -1 update。
*(b++) = 5;
第一个 b++ 将首先发生,因为它在括号中。但是 b 接下来还没有动。因为编译器总是记得在 post 操作中它会在当前语句之后执行它。所以就像:
*b = 5; // a[0]=5;编译器记住了 b=b+1;待执行。
所以现在 b = b+1;
因此 b 现在指向 a[1];
我偶然发现了https://en.cppreference.com/w/cpp/language/operator_precedence
在图表上,我看到 post-增量运算符 (++) 远高于赋值运算符 (=)。
不过,我知道
int a[] = {10,20};
int* b = &a[0];
*(b++) = 5;
cout << a[0] << endl; // 5
cout << a[1] << endl; // 20
cout << *b << endl; // 20, now points to a[1]
我总是想当然地认为 post-increment 发生在赋值运算符之后。但是,如果我按照操作优先级表,那么 post-increment 是不是应该在 =
操作之前发生?答案不是应该是 a={10, 5}
而不是 a={5, 20}
吗?
Post 增量 (b++
) 增量 b
, 然后 returns b
的前一个值.
预递增(++b
)递增b
,然后returnsb
.[=18的新值=]
要获得您期望的行为,请将 post-increment 更改为 pre-increment。
例如:
#include <iostream>
int main() {
int a[] = {10, 20};
int *b = &a[0];
*(++b) = 5;
std::cout << a[0] << std::endl;
std::cout << a[1] << std::endl;
std::cout << *b << std::endl;
}
产生以下输出:
10
5
5
"Precedence" 具有误导性。它通常与 求值顺序 (先发生的事情)没有什么关系,而是为了求值的目的确定每个运算符的操作数是什么。但是让我们检查一下您的示例。
*(b++) = 5;
意思是5
要赋给左边的左值。从 C++17 开始,我们知道 5
完全在 *(b++)
之前求值。在此之前,它们可以按任何顺序进行评估。
现在,b++
具有"increment b
, but evaluate to its previous value"的含义。所以 b++
可能会导致增量发生在赋值发生之前,是的,但是 (b++)
的值是增量发生之前的地址。这就是为什么 b
在一个表达式中更新为指向下一个元素,同时修改当前元素。
Table 是正确的。结果没有混淆。 只要记住 post increment(PI) or decrement(DI),在当前包含 PI 或 DI 的语句之后执行 +1 或 -1 update。
*(b++) = 5;
第一个 b++ 将首先发生,因为它在括号中。但是 b 接下来还没有动。因为编译器总是记得在 post 操作中它会在当前语句之后执行它。所以就像:
*b = 5; // a[0]=5;编译器记住了 b=b+1;待执行。
所以现在 b = b+1;
因此 b 现在指向 a[1];