问题1:如下一段代码输出什么?
#include <iostream>
int main()
{
int i = 0;
printf("%d, %d", i++, i++);
return 0;
}
解析:很多人第一反应是输出0,1,但实际输出是1,0。
原因是X86/X64下函数的参数是从右到左入栈的,先计算右边的,再计算左边的,由于i++是后置,所以最右边那个i输出0,然后左边那个i是1,最后结果就是1,0。
Tips:
上面特意强调是X86/X64下的结果是1,0,是因为在ARM下该代码的结果是0,1。因为ARM架构的函数入参不是放到栈里面,而是放到函数参数寄存器里面。所以是从左到有的顺序,更符合人的常规习惯。
问题2:如下一段代码输出什么?
#include
int main()
{
int i = 0;
printf("%d, %d", ++i, ++i);
return 0;
}
解析:有了上面的学习,这道题和上面就一个i++从后置变成了++i前置,很多人第一反应是输出2,1,但是又错了,实际输出是2,2。
前面提到X86/X64下函数的参数是从右到左入栈的,先计算右边的,再计算左边的。但是还有一点:printf从右向左遍历参数的时候,不是遍历一个就打印一个,而是走完整个过程,统一打印最后的一个值。只有后置++或--是特例,因为它们使用了一个临时变量存了++或--之前的值。
Tips:
考虑到ARM是用寄存器存参数的,而且是从左到右的顺序,所以我猜测ARM下该段反面的结果是1,2。读者不妨一试。
关于这部分的详细介绍,可以参考: