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
2 2
3 3 3
4 4 4 4
然后,依次从栈顶取元素并打印。 所以,结果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入栈后为4 i入栈后为5 i入栈后为6 i入栈后为7
6
5 5
4 4 4
3 3 3 3
可以将上面的表头看成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 ++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
表格第一个 i++ 时,前边只自加了一次,所以现在 i 为4,把4压入栈,然后执行自加一; 同理,第二个 i++ 时,前面自加了三次,所以现在 i 为6,把6压入栈,然后执行自加一。 而 ++i 和 i 都是把 i 的地址压入栈。 所以最后从栈顶依次打印,便成了 8, 8, 6, 8, 8, 4, 8, 8
  • 最后
  • 以上结果不同编译系统结果可能不同
  • 。。。
发布了45 篇原创文章 · 获赞 14 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_34438779/article/details/83685671