C++中的前/后增量指针

3

*(p1++)

int array[10] = {1,2};
int *p1 = array;
*p1=24;
*p1= *(p1++);
for (int i : array)
    cout << i << " ";

Output is 24 24

*(++p1)

int array[10] = {1,2};
int *p1 = array;
*p1=24;
*p1= *(++p1);
for (int i : array)
    cout << i << " ";

输出结果为24 2。

这似乎是与使用值进行递增的完全相反的操作。有人能解释一下这里发生了什么吗?谢谢!


4
未定义行为并非总是如你所预期,以下是更多有趣的例子。 - JSF
你确定这两个例子的输出没有颠倒吗? - J. Murray
好的,看起来这是未定义的行为。考试上问这个问题有点奇怪。编辑:输出结果是正确的。 - Patrick Duncan
@JSF 我们应该引用哪个标准?问题中没有指定具体的 C++ 版本。 - David Schwartz
在任何C++0x存在之前,这是UB行为,我相信在C++17中仍然是UB,当C++还很新而标准没有告诉你它是UB时,它仍然是UB,而标准只是不够完整以告诉你。这不是特定于版本的。 - JSF
显示剩余7条评论
3个回答

2

在IT技术中存在未定义的行为。

*p1 = *(p1++);

因为引用了§1.9/15:

如果对标量对象的副作用在与同一标量对象上的另一个副作用或使用相同标量对象的值计算相对无顺序,那么行为是未定义的。

这里的副作用是对p1进行增量操作,值计算是使用p1计算地址。

所以你不应该依赖于你的例子的确切结果。


1
标准非常模糊,但我会把这个当作答案。 - Mike Nakis
1
@MikeNakis,这是标准中较为易懂的部分之一 =)。 - vitaut

1
*p1= *(p1++);

这根本就没有意义。这个操作的语义意义取决于首先评估 = 的哪一侧,因此你无法从中获得任何意义。


-1

对于 *(p1++):

*p1 = *(p1++)

p1++会将p1增加到数组中的索引1,并返回p1的先前值(索引0)。因此,*(p1++)将返回24,*p1现在将等于2。*p1然后被赋予该返回值(24),因此数组将变为{24,24}

对于*(++p1)

*p1 = *(++p1)

++p1 将会将 p1 增加到数组中的第二个索引位置,并返回当前的 p1 值(即索引位置 1)。因此,*(++p1) 将返回 2,而 *p1 现在将等于 2。然后,*p1 被赋予该返回值(2),这是 p1 索引位置上的原始值(1),因此数组将保持为 {24,2}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接