printf函数为其参数建立一个[栈],从右到左将参数压入栈,再从栈内将里面的元素依次打印。
- 函数举例
#include <stdio.h>
int p(int a)
{
printf("%d\n",a);
return a;
}
int main()
{
int a=5,b=1;
printf("%d %d %d %d\n",p(1),p(2),p(3),p(4));
return 0;
}
结果如下:
可以看出,函数是从右到左执行的,并且当一个函数执行完毕,将返回值压入栈内。
p() 执行完毕,栈内情况如下:
p(4) | p(3) | p(2) | p(1) |
---|---|---|---|
1 | |||
2 | 2 | ||
3 | 3 | 3 | |
4 | 4 | 4 | 4 |
- 万恶之源(i++, ++i)
i++的神奇操作
i++为后缀的加1运算符,先引用i,再将i的值加一
#include<stdio.h>
int main()
{
int i=3;
printf("%d, %d, %d, %d\n",i++,i++,i++,i++);
printf("i is %d\n",i);
return 0;
}
结果如下:
可以看出,printf从右往左压入i,i压入后加一
i入栈后为4 | i入栈后为5 | i入栈后为6 | i入栈后为7 |
---|---|---|---|
6 | |||
5 | 5 | ||
4 | 4 | 4 | |
3 | 3 | 3 | 3 |
++i的表现有点神奇
#include<stdio.h>
int main()
{
int i=3;
printf("%d, %d, %d, %d\n",++i,++i,++i,++i);
printf("i is %d\n",i);
return 0;
}
结果如下:
为什么全部是7呢?
有大佬的解释是:
Go to Dessembly说出了迷底。
对于a++的结果,是有ebp寻址函数栈空间来记录中间结果的,在最后给printf压栈的时候,再从栈中把中间结果取出来;
而对于++a的结果,则直接压寄存器变量,寄存器经过了所有的自增操作。
这就是a++和++a的压栈的区别。
以上出处
我觉得他的意思是 ++i 和 i 都是将 i 的地址压入栈,而 i++ 是将自加前的 i 的副本压入栈
- 以下为我个人猜想
#include<stdio.h>
int main()
{
int i=3;
printf("%d, %d, %d, %d, %d, %d, %d, %d\n",i,++i,i++,++i,i,i++,++i,i);
printf("i is %d\n",i);
return 0;
}
结果如下:
可以看出 ++i 和 i 都是经过一系列骚操作后 i 的值;
而 i++ 则是将其入栈时 i 的副本,所以 i++ 只是显示当时 i 的值。
i | ++i | i++ | i | ++i | i++ | ++i | i |
---|---|---|---|---|---|---|---|
i | |||||||
i | i | ||||||
6 | 6 | 6 | |||||
i | i | i | i | ||||
i | i | i | i | i | |||
4 | 4 | 4 | 4 | 4 | 4 | ||
i | i | i | i | i | i | i | |
i | i | i | i | i | i | i | i |
- 最后
- 以上结果不同编译系统结果可能不同
- 。。。