在指针上同时使用前缀和后缀时出现奇怪的输出
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
的旧值)。
给出下面的代码
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
的旧值)。