通过指针解引用并递增给出一个不同的值,并取而代之的是C ++

问题描述

我试图用C ++对指针进行一些实验,我确实了解了优先级的概念,但是下面的程序在我的脑海中and绕,无法理解

代码:

#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

有关更多详细信息,您可以转到这篇文章:What made i = i++ + 1; legal in C++17?

,

使用++(*ptr)代替(*ptr)++来获得所需的结果。

++x使x的值递增,然后返回新的递增值,而x++使x的值递增,但返回x的先前值(副本)。 / p>

根据您对拥有9,Address,9,10,11,12的期望,您确实希望拥有++x的行为,因此需要使用++(*ptr)

您可以在操作here online中看到更正的代码。

更新

实际上,即使在没有预增++(*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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...