【问题标题】:C++ Incrementing a PointerC++ 递增指针
【发布时间】:2017-01-05 18:16:42
【问题描述】:

为什么我可以做 *x = *x+1; 之类的事情,却做 *x = *x++; 之类的事情好像没什么影响?

代码:

// Example program
#include <iostream>
#include <string>

using namespace std;

void doSomething(int *x, int *y)
{
    *x = *x++;
    *y = *y + 5;
}

int main()
{
    int x = 4;
    int y = 3;
    doSomething(&x, &y);
    cout << "x is now: " << x << endl; //outputs 4
    cout << "y is now: " << y << endl; //outputs 8
    return 0;
}

【问题讨论】:

  • 你不是在“增加一个指针”,你是在“增加一个指针指向的东西”。
  • 试试++*x怎么样?
  • 我不知道为什么这会被否决。我在@ 31:25 旁边关注这个视频是对上面代码的引用:youtube.com/watch?v=Rxvv9krECNw
  • 完全偏离主题的语法纠正:效果,不影响。

标签: c++ pointers post-increment pre-increment


【解决方案1】:

此声明

*x = *x+1;

可以这样写

*x = ++*x;

当然你可以写

++*x;

至于这个说法

*x = *x++;

那么就等价于

*x = *( x++ );

并且具有未定义的行为,因为后增量运算符的副作用未排序。

【讨论】:

  • *x = ++*x 也是 UB。
  • @OliverCharlesworth:它将是 C++03 中的 UB,但我不确定 C++11。在 for = 之前有一些关于排序的内容。
  • @Cheersandhth.-Alf 在 C++ 11 中,这样的表达式语句被采纳为有效。
  • 好的,我不知道 C++11 中的行为发生了变化。无论如何,世界上仍有很大一部分是 UB(无论哪种方式,都可能在读者中引起混淆/不信任)。为什么不建议只写++*x;
  • @OliverCharlesworth 我展示了如何使用作者想要的增量运算符正确编写它。
【解决方案2】:

后缀运算符++ 的优先级高于dereference * 运算符。语句*x = *x++;执行如下*x = (*(x++))

如您所见,首先执行++ 运算符,使指针指向它所指向的位置。从那里执行dereference 运算符。如果你想增加x 的实际值,只需写++*x;

【讨论】:

  • x++的表达式结果是x的原始值。
【解决方案3】:

因为所有表达式都遵循operators precedence rule

正如您在表格中看到的,运算符operator++ 的优先级高于operator*

你可以更好地跟随括号,代码:

*x = *x++;

相当于:

*x = *(x++);

简而言之,您正在递增指针的值,之后您取消引用它。

在内存中会发生这样的事情:

|  x = 4   |     <---- &x
|  trash   |
|  trash   |

你增加指向内存中下一个单元格的指针:

|  x = 4   |     
|  trash   |     <---- &x+1
|  trash   |

并且将其值分配给自己,无论如何它都是垃圾。


解决方案

为了避免误解,括号的用法应该是一个有效的帮助。

修复它:

*x = ++(*x);

【讨论】:

  • *x = (*x)++; 现在你有另一个问题。 (*x)++; 怎么样?
  • @BoPersson 抱歉太快了,我修好了
  • “你正在增加指针的值,并且在你取消引用它之后”。真的吗?增量是可能在分配之前或之后发生的副作用。我的理解是*x++ 将始终取消引用x 的原始位置,然后x 将移动到指向下一个位置。所以结果是不确定的?也许垃圾箱的位置被赋值为 4?
猜你喜欢
  • 2010-09-23
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 2021-03-04
  • 1970-01-01
  • 2013-05-06
  • 2021-12-11
相关资源
最近更新 更多