c 语言的一个问题,请各位大佬解答

2019-12-17 05:08:40 +08:00
 evilhero

有如下代码:

int a, *b;
a = 10;
b = &a;
printf("%d  %d\n", ++a, --a);

加上 b= &a; 的输出:11 10
不加上 b = &a; 的输出:10 10

不加上的应该是`printf```的参数在进行运算前就确定了。

现在问题是:

为什么加上 b = &a; 后,在 printf 中的自增 /自减运算就会在 printf 确定参数前先一步执行?

4162 次点击
所在节点    C
15 条回复
xcstream
2019-12-17 06:26:23 +08:00
c 语言未定义的行为
编译器不同,结果也不同
evilhero
2019-12-17 06:56:36 +08:00
@xcstream 谢谢! c 语言万岁…太可怕了
crc8
2019-12-17 09:43:30 +08:00
gcc 下输出是 10 10 和 10 9
azcvcza
2019-12-17 10:04:22 +08:00
c 语言的自增在前或者在后,语义都不一样。++a 是先对 a 做递增,再输出,a++则是先输出旧 a 再更新 a 的值。
一般还是写 a+=1 好一些
xxdd
2019-12-17 10:07:56 +08:00
记得老早知乎的薛飞 擅长这个(狗头)
daimiaopeng
2019-12-17 10:39:30 +08:00
不同的编译器的参数入栈顺序不一样,gcc 好像从右往左
summer20100514
2019-12-17 10:54:09 +08:00
确实和 3 楼一样的结果,应该是编译器的优化。gcc -S 看下汇编,是不一样的
evilhero
2019-12-17 10:59:03 +08:00
@azcvcza 正常人当然不会++a 这样子写…试卷上就会,哈哈
tianshilei1992
2019-12-17 11:02:56 +08:00
我猜是因为两次 alias analysis 的结果不同导致 instruction reorder 的结果也不同,也正如楼上所说,由于这是未定义的行为,所以表现如何就真看编译器怎么做了。
BTW 在我的电脑上用 LLVM 两个结果都是 11 10,无论是 -O 几。
evilhero
2019-12-17 11:06:07 +08:00
@summer20100514
@daimiaopeng
@xxdd
@azcvcza
@crc8
@xcstream

谢谢各位大哥了,既然是编译器问题,就不深究了,毕竟这只是考试题。
InkStone
2019-12-17 11:08:27 +08:00
@evilhero C++ primer 上有很多*iter++的写法。其实只要你自己够熟悉,并且不要滥用,就没什么关系。
evilhero
2019-12-17 11:08:59 +08:00
@tianshilei1992 谢谢解答,看来要多装几个编译器了
evilhero
2019-12-17 11:10:39 +08:00
@InkStone 主要是只是&a 取了地址给 b,其他没有对 a 进行任何操作,结果竟然不一样,感觉好神奇
anonymous256
2019-12-17 13:16:33 +08:00
不是编译器问题! 你 google 搜这个关键词: sequence point, 就明白了.

写出这样的代码是不应该的. 你表达式的顺序是不确定的, 行为未定义.
https://stackoverflow.com/questions/3575350/sequence-points-in-c
https://en.wikipedia.org/wiki/Sequence_point
evilhero
2019-12-17 13:24:44 +08:00
@anonymous256 确实不应该这样写,但是试卷是就是这样…

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/629658

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX