鉴于以下代码
char buf[] = "asfsf";
char *a=buf;
++*a++;
cout<<*a;
我希望结果是下一个字符&#39;&#39;那是&#39;#,但结果仍然是&#39;。为什么呢?
为什么++ * a ++与
不同*a++;
++*a;
cout<<*a;
对于++ i ++,这真的是一个重复的问题吗?我知道++ i ++是一个未定义的行为,会导致编译错误,但++ * i ++实际上可以运行。我的情况也是未定义的行为吗?
答案 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
- 但任何阅读代码的人都将被完全原谅如果他们讨厌你这样写的话。