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

时间:2015-04-13 22:18:53

标签: c++ pointers prefix

鉴于以下代码

char buf[] = "asfsf";

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

我希望结果是下一个字符&#39;&#39;那是&#39;#,但结果仍然是&#39;。为什么呢?

为什么++ * a ++与

不同
*a++;
++*a;
cout<<*a;

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

2 个答案:

答案 0 :(得分:3)

根据语言语法,运营商关联为:

++(*a++)

注意:关联性并不意味着操作顺序。

*a++评估指定a最初指向的位置的左值,并具有修改a的副作用。到目前为止一切都很好。

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

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

答案 1 :(得分:2)

现在看来,你的代码有不确定的行为,因为它试图修改字符串文字的内容。

阻止编译器接受此类代码的一种方法(可能是首选方法)是定义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 - 但任何阅读代码的人都将被完全原谅如果他们讨厌你这样写的话。