在指针上同时使用前缀和后缀时出现奇怪的输出

Weird output when use prefix and postfix on pointer together

给出下面的代码

char buf[] = "asfsf";

char *a=buf;
++*a++;
cout<<*a;

我希望结果是 's' 的下一个字符 't',但结果仍然是 's'。为什么?

为什么++*a++和

不一样
*a++;
++*a;
cout<<*a;

这真的是++i++的重复问题吗?我知道 ++i++ 是未定义的行为,会导致编译错误,但 ++*i++ 实际上可以 运行。我的情况也是未定义的行为吗?

就目前而言,您的代码具有未定义的行为,因为它试图修改字符串文字的内容。

防止编译器接受此类代码的一种方法(可能是首选方法)是将您的 a 定义为:

char const *a="asfsf";

这样,++*a 部分将无法编译。

为了便于说明,让我们稍微更改一下代码,变成:

#include <iostream>

int main(){ 

    char x[]="asfsf";
    char *a = x;
    ++*a++;
    std::cout<<x;
}

现在 a 指向我们可以实际写入的内存,并获得有意义的结果。这会打印出 bsfsf。如果我们打印出 a,我们将得到 sfsf.

发生的事情是 a++ 递增 a 仍然产生 a 的原始值。即取消引用,给出对 x 的第一个元素的引用。然后对其应用预增量,将其从 a 更改为 b.

如果你想增加指针,取消引用结果,然后增加它,你会使用:++*++a;。好吧,不,你不会用它——或者至少我希望你不会。它确实递增 a 以指向数组的第二个元素,然后递增第二个元素以将其从 s 更改为 t——但任何阅读代码的人都会被完全原谅如果他们讨厌你那样写。

根据语言语法,运算符关联为:

++(*a++)

注意:结合性并不意味着运算顺序。

*a++ 评估为指定 a 最初指向的位置的左值,具有修改 a 的副作用。目前一切正常。

对该左值应用前缀-++ 会增加存储在那里的值(将 'a' 更改为 'b')。

虽然这两个增量是无序的,但这不会导致UB,因为不同的对象正在增加,并且指定后一个位置的左值不依赖于增量。 (它使用 a 的旧值)。