i=3 printf("%d %d %d %d\n", i++, ++i, i++, ++i); 求结果解释

2015-07-12 11:37:03 +08:00
 nobodybutme
int i=3, j = 3, z = 3;
printf("%d %d %d %d\n", i++, ++i, i++, ++i);
printf("%d %d %d %d\n", j++, ++j, ++j, ++j);
printf("%d %d %d\n", ++z, ++z, ++z);

结果为:
6 7 4 7
6 7 7 7
6 6 6

printf 参数从右往左压栈, 我一直以为z的输出应该是6 5 4,有人帮忙解释下么?
8030 次点击
所在节点    问与答
21 条回复
zhjits
2015-07-12 11:39:08 +08:00
undefined behavior
FrankFang128
2015-07-12 11:40:02 +08:00
结果就是写这行代码的程序员被开除。
然后把这行重写
choury
2015-07-12 11:42:23 +08:00
你学的是谭浩强的C语言吗,要是我们组有人敢写这样的代码,我非得喷死他
nobodybutme
2015-07-12 11:43:20 +08:00
@zhjits 我win下codeblocks和linux下gcc跑的都是这个结果。 不同编译器怎么实现的? 比如i的那个,6 7 4 7 怎么得出来的?
onlyice
2015-07-12 11:51:16 +08:00
@nobodybutme 看生成的汇编代码,就知道怎样实现了
说实话知道了也没什么用
chaucerling
2015-07-12 11:53:25 +08:00
++i的优先级
lingo233
2015-07-12 11:55:30 +08:00
这一定是谭浩强C
zhjits
2015-07-12 11:58:04 +08:00
@nobodybutme Windows 下面的 codeblocks 自带一个 gcc。

Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) 运行结果:
3 5 5 7
3 5 6 7
4 5 6
zhjits
2015-07-12 11:58:41 +08:00
@nobodybutme 至于具体编译器怎么实现的可以 RTFM 或者看生成的汇编啊
johnsmith123
2015-07-12 12:11:38 +08:00
SB
loveuqian
2015-07-12 12:19:34 +08:00
了解这段代码的含义对实际开发帮助不大
nobodybutme
2015-07-12 12:23:49 +08:00
@zhjits Thank you! ^_^
101
2015-07-12 12:27:23 +08:00
我记得不同的编译器实现是不一样的,类似事例似乎在 TCPL 出现过?
dndx
2015-07-12 12:36:55 +08:00
有时间干啥不好非研究这种蛋疼且毫无意义的玩意。
18000rpm
2015-07-12 12:41:00 +08:00
你们喷完还是帮人家解决一下问题嘛
LZ 可以参考一下这个 http://docs.linuxtone.org/ebooks/C&CPP/c/ch16s03.html
yksoft1
2015-07-12 13:08:56 +08:00
不同编译器,不同系统,不同CRT对这个实现都可能不同,因此不要在实际开发中这么写
XiXiLocked
2015-07-12 13:10:55 +08:00
这和压栈顺序在概念上是无关的(实现上相关那是另一回事
有关的是参数的计算顺序,
比如printf("%d %d %d\n", ++z, ++z, ++z); 补上计算过程中的临时变量,那就相当于7条无序语句
z+=1;
int temp1 = z;
z+=1;
int temp2 = z;
z+=1;
int temp3 = z;
printf("%d %d %d\n", temp1, temp2, temp3);
除了print必须最后执行,初始化temp必须在z+=1之后,并没有其他约束。所以temp1,2,3的顺序可以换,temp的初始化的时机也可以后延。要出现666只要把3条temp尽量往后挪就行。

再说这样写并不好,虽然我觉得这不是undefined behavior,而是implementation specific behavior,因为我记得语言规范上故意不限定求值顺序是为了方便编译器优化,但不管是哪种,代码已经不受自己控制了。
en3073
2015-07-12 15:42:45 +08:00
xcode的答案
3 5 5 7
3 5 6 7
4 5 6
你怎么看?
wy315700
2015-07-12 15:47:30 +08:00
函数参数是从右往左压栈,但是没有定义是哪个参数先行计算
Tink
2015-07-12 16:31:14 +08:00
自己算的 3 5 5 7

3 5 6 7

4 5 6

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

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

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

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

© 2021 V2EX