printf函式引數壓棧順序
阿新 • • 發佈:2019-02-02
printf函式的引數的壓棧順序和求值順序(VC++6.0編譯器)
有以下程式段:
設int arr[]={6,7,8,9,10};
int *ptr=arr;
*(ptr++)+=123;
printf("%d,%d",ptr,(++ptr));
答案為什麼是:8,8
這是一道華為面試題。
這個題考的關鍵就是printf的運算順序。
這個是比較繞的一個問題,主要考驗的是i++ 和++i :
我們逐個分析:
int arr[]={6,7,8,9,10};
int *ptr=arr;
//這裡ptr是陣列的首地址。
*(ptr++)+=123;
//這個我們將之拆分
//1. 首先是 ptr++, 這個時候重點看到是後++,也就是說返回的ptr還是原來的ptr的值,也就是arr的首地址。
//那麼這句話也就轉換成了 a[0]+=123,即運算後 a[0] = 129
//2. 這整句執行完之後,ptr才真正的++。也就是說,這個時候ptr指向的陣列第二個位置,也就是7
printf("%d,%d",ptr,
//這一句有一個函式引數入棧的順序,一般VC的編譯器是從右往左入棧,那麼這個運算也自然是從右往左。
//++ptr之後ptr再次向後一個位置移動,即a[2],8。
//前面的*ptr自然也就是8,所以這句執行之後輸出的是8,8
printf函式的壓棧順序和求值順組不一樣 壓棧順序是從右向左的,是固定的,而求值順序是不定的,根據每個編譯器的不同而不同。比如VC++6.0就是從右向左 C語言那樣的引數壓棧比較適合不定引數的實現,也就是比如 f(int ,float, …) 如果考慮效率,也可以用用pascal方式(它的壓棧循序與c的相反),求值的循序如果對程式有影響的話,也不用去關心程式的實現是從左到右還是從右到左,而應在呼叫函式之前確定好