通过指针取消引用并递增给出不同的值并递减它而不是 C++
Dereferencing through pointer and incrementing gives a different value and decrements it instead C++
我正在尝试用 C++ 中的指针做一些实验,我确实了解了一些优先级的概念,但是下面的程序混杂在我的脑海中,无法理解它
代码:
#include <iostream>
using namespace std;
int main() {
int x = 9;
int* ptr = &x;
cout << "The value of x is " << x << endl << "The value of ptr is " << ptr << endl << *ptr << endl << (*ptr)++ << endl << (*ptr)++ << endl << (*ptr)++ << endl;
return 0;
}
在这个程序中,x 的初始值为 9,我希望编译器给我 x 的值为 9,然后使用指针递增它,所以我希望答案为 9,Address,9 ,10 ,11,12 但是我在每个编译器中得到的答案是 x 的值为 12 其余的就像这样 12,Address,11,10,9
请帮助我理解这是 C++ 的新手
这与优先级无关,但与评估顺序有关。您假设评估顺序是从左到右,但事实并非如此。如您所见,在您的情况下,它是从右到左。
然而,这是 C++ 发生变化的领域。在 C++17 版本中,上述表达式的规则发生了变化,以保证从左到右的求值顺序。因此,如果可以,请使用强制版本 C++17 的编译器选项,您应该会看到结果发生变化。
并不能保证从左到右的求值顺序,例如给定 A + B,它仍然可能是 A 在 B 之前或 B 在 A 之前。可以找到完整的详细信息 here。
这是一个undefined behavior。
更详细的信息,你可以去这个post:
使用 ++(*ptr)
而不是 (*ptr)++
来获得您想要的结果。
++x
增加 x
的值,然后 returns 增加新的值,而 x++
增加 x
但 returns 以前的值( x
.
的副本)
并且根据您对 9, Address, 9, 10, 11, 12
的期望,您确实希望具有 ++x
的行为,因此需要使用 ++(*ptr)
。
您可以在操作中看到更正后的代码 here online。
更新.
事实上,即使 pre-increment ++(*ptr)
在不同编译器上的表现也不同,我的 MSVC 2015 和 2019 输出 12 addr 12 12 12 12
如果我使用 /std:c++latest
MSVC 中的标志然后输出是正确的预期 9 addr 9 10 11 12
,因此行为在 C++11
或更高版本中发生了变化。
所以这意味着此类表达式的行为是未定义的,这意味着它在不同的编译器上是不同的,甚至可能是随机的。
所以如果你想在所有版本的编译器中兼容,你需要绝对避免这样的表达。或者对 MSVC 使用 /std:c++latest
,对其他编译器使用类似的标志,以强制使用最新的 C++ 标准。
为避免出现问题,您可以将递增的结果存储到单独的变量或数组中,然后将其输出到 cout
。
我正在尝试用 C++ 中的指针做一些实验,我确实了解了一些优先级的概念,但是下面的程序混杂在我的脑海中,无法理解它
代码:
#include <iostream>
using namespace std;
int main() {
int x = 9;
int* ptr = &x;
cout << "The value of x is " << x << endl << "The value of ptr is " << ptr << endl << *ptr << endl << (*ptr)++ << endl << (*ptr)++ << endl << (*ptr)++ << endl;
return 0;
}
在这个程序中,x 的初始值为 9,我希望编译器给我 x 的值为 9,然后使用指针递增它,所以我希望答案为 9,Address,9 ,10 ,11,12 但是我在每个编译器中得到的答案是 x 的值为 12 其余的就像这样 12,Address,11,10,9 请帮助我理解这是 C++ 的新手
这与优先级无关,但与评估顺序有关。您假设评估顺序是从左到右,但事实并非如此。如您所见,在您的情况下,它是从右到左。
然而,这是 C++ 发生变化的领域。在 C++17 版本中,上述表达式的规则发生了变化,以保证从左到右的求值顺序。因此,如果可以,请使用强制版本 C++17 的编译器选项,您应该会看到结果发生变化。
并不能保证从左到右的求值顺序,例如给定 A + B,它仍然可能是 A 在 B 之前或 B 在 A 之前。可以找到完整的详细信息 here。
这是一个undefined behavior。
更详细的信息,你可以去这个post:
使用 ++(*ptr)
而不是 (*ptr)++
来获得您想要的结果。
++x
增加 x
的值,然后 returns 增加新的值,而 x++
增加 x
但 returns 以前的值( x
.
并且根据您对 9, Address, 9, 10, 11, 12
的期望,您确实希望具有 ++x
的行为,因此需要使用 ++(*ptr)
。
您可以在操作中看到更正后的代码 here online。
更新.
事实上,即使 pre-increment ++(*ptr)
在不同编译器上的表现也不同,我的 MSVC 2015 和 2019 输出 12 addr 12 12 12 12
如果我使用 /std:c++latest
MSVC 中的标志然后输出是正确的预期 9 addr 9 10 11 12
,因此行为在 C++11
或更高版本中发生了变化。
所以这意味着此类表达式的行为是未定义的,这意味着它在不同的编译器上是不同的,甚至可能是随机的。
所以如果你想在所有版本的编译器中兼容,你需要绝对避免这样的表达。或者对 MSVC 使用 /std:c++latest
,对其他编译器使用类似的标志,以强制使用最新的 C++ 标准。
为避免出现问题,您可以将递增的结果存储到单独的变量或数组中,然后将其输出到 cout
。