1. 程式人生 > >Windows下DEVC++ 5.11 的printf函式對引數的執行順序

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
  • 最後
  • 以上結果不同編譯系統結果可能不同
  • 。。。