Windows下DEVC++ 5.11 的printf函数对参数的执行顺序

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
22
333
4444
然后,依次从栈顶取元素并打印。 所以,结果main函数里面的printf打印出来就是 1 2 3 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;
}

结果如下:
i++
可以看出,printf从右往左压入i,i压入后加一

i入栈后为4i入栈后为5i入栈后为6i入栈后为7
6
55
444
3333
可以将上面的表头看成i在一次入栈后的值,下面依次是将i自加前,将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;
}

结果如下:
++i

为什么全部是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++ii++i++ii++++ii
i
ii
666
iiii
iiiii
444444
iiiiiii
iiiiiiii
表格第一个 i++ 时,前边只自加了一次,所以现在 i 为4,把4压入栈,然后执行自加一; 同理,第二个 i++ 时,前面自加了三次,所以现在 i 为6,把6压入栈,然后执行自加一。 而 ++i 和 i 都是把 i 的地址压入栈。 所以最后从栈顶依次打印,便成了 8, 8, 6, 8, 8, 4, 8, 8
  • 最后
  • 以上结果不同编译系统结果可能不同
  • 。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值