i++ 與 ++i 的不同
1 i=1; printf("%d %d\n",i,i++); //結果 2 1 2 i=1; printf("%d %d\n",i++,i); //結果 1 2 3 i=1; printf("%d %d %d\n",i,i++,i); //結果 2 1 2 4 i=1; printf("%d %d %d %d\n",i,++i,i++,i); //結果 3 3 1 3
解析:
已知前提:
- printf輸出時,壓棧順序為從右往左,也就是說從右往左的計算;
- 入棧時先進后出,先進入的在棧的高地址,后進入的在棧的低地址;
- printf后面的表達式,比如i++, 此操作為計算,”計算“ 是計算,但是不等於“輸出”的結果;
- i++的結果,是有ebp尋址函數棧空間來記錄中間結果的,在最后給printf壓棧的時候,再從ebp棧中把中間結果取出來壓入printf分配的棧中;
- ++i的結果,是直接寄存器進行自增操作,然后把該寄存器的地址壓入printf分配的棧中。
i++是先計算后自加,而++i是先自加后計算。
1 int main() 2 { 3 int i = 0; 4 //i++ = 100;//直接報錯,編譯出錯: error C2106: “=”: 左操作數必須為左值 5 ++i=100;//通過,沒有錯誤 6 printf("%d", i);//直接打印100 7 return 0; 8 }
從上面的代碼情況可以認為編譯器在處理i++和++i的方式不同
- i++完成之后返回的是右值也就是一個常量
- ++i完成之后返回的是左值也就是i的內存,對++i賦值相當於給i賦值
結論:printf壓棧的時候,i++其實壓的是ebr中間結果的值,也就是一個常量。而++i 因為計算后的結果是一個左值,故會將i對應的地址進行壓棧。
例題說明
i=1; printf("%d %d %d %d\n",i,++i,i++,i); //結果 3 3 1 3
++i 是直接真值進行自加,而 i++ 則是通過在ebr中存放的臨時副本進行加1后再賦值給i
| 棧 | 運算式 | 真值(寄存器中) | 副本(ebr中) |
| 低位 | i | 3 | |
| ++i | 3 | ||
| i++ | 2 | 1 | |
| 高位 | i | 1 |
最終 i 的真值為3,i++ 的ebr定值為1, 故最后的輸出結果為:3 3 1 3
