printf 引數入棧順序
阿新 • • 發佈:2019-02-15
先看一段程式碼
a=1; printf("%d %d\n",a,a++);
a=1; printf("%d %d\n",a++,a);
a=1; printf("%d %d %d\n",a,a++,a);
a=1; printf("%d %d %d %d\n",a,++a,a++,a);
其輸出為:
2 1
1 2
2 1 2
3 3 1 3
因為C語言函式引數入棧順序是從右到左的,所以計算順序是從右到左開始計算的;對於a++的結果,是有ebp定址函式棧空間來記錄中間結果的,在最後給printf壓棧的時候,再從棧中把中間結果取出來;而對於++a的結果,則直接壓暫存器變數,暫存器經過了所有的自增操作。
/*再下面這個例子*/
int a = 1;
printf("%d %d %d %d %d %d\n",a++, ++a, a++, ++a, a++, ++a );
/*結果
6 7 4 7 2 7*/
關於C語言函式引數的入棧順序為什麼要選擇從右至左,查了一直些文獻得知,引數入棧順序是和具體編譯器實現相關的。比如,Pascal語言中引數就是從左到右入棧的,有些語言中還可以通過修飾符進行指定,如Visual C++.即然兩種方式都可以,為什麼C語言要選擇從右至左呢?
進一步發現,Pascal語言不支援可變長引數,而C語言支援這種特色,正是這個原因使得C語言函式引數入棧順序為從右至左。具體原因為:C方式引數入棧順序(從右至左)的好處就是可以動態變化引數個數。通過棧堆分析可知,自左向右的入棧方式,最前面的引數被壓在棧底。除非知道引數個數,否則是無法通過棧指標的相對位移求得最左邊的引數。這樣就變成了左邊引數的個數不確定,正好和動態引數個數的方向相反。
因此,C語言函式引數採用自右向左的入棧順序,主要原因是為了支援可變長引數形式。換句話說,如果不支援這個特色,C語言完全和Pascal一樣,採用自左向右的引數入棧方式。