關於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++在計算過程中會產生快取區,返回的值就是快取區的值,既是在加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++);