1. 程式人生 > >關於printf("%d,%d",i--,i++)的問題

關於printf("%d,%d",i--,i++)的問題

首先看幾種情況

1、

	int i=1;
	printf("%d,%d\n",i--,i++);
執行結果為:2,1

這與編譯器有關,通過彙編可以很清楚的看到


第一步:把i的值存入快取器[ebp-0E8h]=1;

第二步:i值加1,i=i+1=2;

第三步:把i的值存入快取器[ebp-0ECh]=2;

第四步:i值減1,i=i-1=1;

第五步:把快取器[ebp-0E8h]=1,入棧

第六步:把快取器[ebp-0ECh]=2,入棧

故,列印輸出為 2,1

總結:

由++或者--運算的順序是從右向左,故先計算i++,i++在計算過程中會產生快取區返回的值就是快取區的值,既是在加1之前需要先備份,這裡的快取區地址就是[ebp-0E8h]=1,

之後,i=i+1=2;

同理,第二個表示式的快取區[ebp-0ECh]=2,

之後,i=i-1=1;

然後把第一,第二個表示式的返回值分別入棧【1,2】故輸出為 2 1;

2、

	int i=1;
	printf("%d,%d\n",i++,++i);

第一步:i值加1,i=i+1=2;

第二步:把i的值存入快取區[ebp-0E8h]=2;

第三步:i值加1,i=i+1=3;

第四步:把i=3,入棧

第五步:把快取區[ebp-0E8h]=2,入棧

故,輸出為2,3

總結:

由++或者--運算的順序是從右向左,故先計算++i,++i的返回值為i本身,本應該是2,但是後面的運算卻影響i的值,另外printf輸出流的快取棧是在所有表示式計算完後再入棧的,只需要知道首先入棧的是

i的地址裡面存的值,

下面該表示式i++,i++在計算過程中會產生快取區,返回的值就是快取區的值,既是在加1之前需要先備份,這裡的備份地址就是[ebp-0E8h]=2,之後i=i+1=3,返回的值為快取區[ebp-0E8h]=2,第二次入棧的就是第二個表示式的返回值[ebp-0E8h]=2,而第一次入棧的是第一個表示式的返回值i的值(此時已經改為3),故輸出棧裡面是【3,2】,列印輸出 2,3.

下面的幾個例子是具有兩個變數的,道理是類似的,要注意,具有後置++/--的,返回的都是快取區的值,前置的都是返回變數本身的值,另外本身的值可能受另一個表示式的影響,所以,在沒有計算完之前,是不知道i的值的。

1、

	int x=2,y=3;
	printf("%d,%d\n",(x++)+y,++y);//等價x+++y

第一個入棧的是y值本身,而其他表示式對其無影響,故入棧y==4

第二個入棧的是表示式的快取區的值,為x+y=2+4=6,故入棧 6

輸出值為6 4

下面的例子可以自己分析試試,看看反彙編就立刻明白含義了,就不一一說明了

2、

	int x=2,y=3;
	printf("%d,%d\n",x+y++,++y);

3、
	int x=2,y=3;
	printf("%d,%d\n",x+y,++y);

4、

	int x=2,y=3;
	printf("%d,%d\n",x+y,y++);