i++,++i 作为参数
C++11Prime里说过不同的编译器读取参数的方向不同,有的从左到右,有的从右到左。
我在想他说的是不是指,32位系统通过栈把参数压入,所以从右到左,而64位前6个是寄存器存取,所以从左到右。
还是说,对于精简指令集的机器,一般采用压,弹两种方式的机器,而复杂指令集则多了个寄存器方式。我 也是一知半解,也请各位指教。
一、
i++; 使用完毕后再自加,遇到分号结束" ; "
++i; 先对 i 自加,然后再使用它
++i; 先对 i 自加,然后再使用它
i = 2;
num = (i++) + (i++) + (i++) + (i++);
输出 num = 8,i = 6;
num = (i++) + (i++) + (i++) + (i++);
输出 num = 8,i = 6;
num = (++i) + (++i) + (++i) + (++i);
3 4 5 6
输出 num = 18,i = 6;
3 4 5 6
输出 num = 18,i = 6;
i = (i++) + (++i) + (i++) + (++i)
i = 3 + 3 + 3 + 4 + 1 + 1 = 15;
i = (++i) + (i++) + (++i) + (++i)
i = 3 + 3 + 4 + 5 + 1 = 16;
i = i * ((i++) + (++i))
i = 3 * (3 + 3 ) + 1 = 19;
i = 3 + 3 + 3 + 4 + 1 + 1 = 15;
i = (++i) + (i++) + (++i) + (++i)
i = 3 + 3 + 4 + 5 + 1 = 16;
i = i * ((i++) + (++i))
i = 3 * (3 + 3 ) + 1 = 19;
二、
int main()
{
int i = 2;
func(i++,++i);
return 0;
}
void func(int a,int b)
{
printf("a = %d\n",a);
printf("b = %d\n",b);
}
输出 a = 3
b = 4
{
int i = 2;
func(i++,++i);
return 0;
}
void func(int a,int b)
{
printf("a = %d\n",a);
printf("b = %d\n",b);
}
输出 a = 3
b = 4
解释: 函数传参是从右边开始传参的,++i 被替换成变量, i++被替换成数值,分号,逗号和函数的小括号都是i++的结束标志。
从汇编我们可以看到 93,9A可以看到先压入eax,再压入ecx,也就是先压入3后压入4,先压入i++,后压入,++i;而其计算是在上面统一计算的,也就是计算是从左到右计算的,压入是从右至左,只是在计算第一个参数时,把他复制到最后,作为返回的i,所以上网上一些的说法是错误的。
从下面X64又加深了我对上面的理解:都是从左至右计算,只是,因为寄存器不要像栈那样逆向取出,所以执行函数进直接从两个寄存器取出即可。而栈则从一个栈取出两 个参数
我用X64又调试了一下:如下:
可以看到这个和上面不同,但是思路很清晰,先是把i++ 处理完把i值从ptr[i]复制放到最后,再处理++i;全用的寄存器.可以说纯粹的从左至右。
限于作者水平有限,如有问题可以提出来讨论,用的是visual studio 2017 ,win7 X64 , Debug选了32和64得出以上两种结果。