朋友問我一道題他碰到的筆試題:
sizeof(b)求b所占用的空間,這個是3沒有問題。
strlen僅僅根據'/0'的出現判斷字串大小,而不管'/0'是不是出現在陣列之內。由於b的末尾沒有'/0',所以strlen(b)的值依賴於程式的記憶體布局。
我記得李先靜兄在《系統程式設計師成長計畫》裡提到過gcc對臨時變數的進棧順序處理,查了一下:
「gcc不同版本的處理是不一樣的,對於老版本的gcc(如gcc3.4),第乙個臨時變數放在最高的位址,第二個其次,依次順序分布。而對於新版本的gcc(如gcc4.3),臨時變數的位置是反的,即最後乙個臨時變數在最高的位址,倒數第二個其次,依次順序分布。」
不管是臨時變數在棧中的順序是遞增還是遞減,只要是有序的,那麼strlen(b)的值就應該是6,我估計這也是出題者在b的前後各放了乙個4位元組長的陣列的原因。
朋友驗證之後告訴我,他在gcc4.4.1下輸出是7 3,於是我做了下面的實驗,驗證臨時變數在stack中的排列順序:
unbuntu + gcc 4.4.1
輸出:bffff448 bffff444 bffff44d bffff440
7 3從記憶體布局可以看出,gcc調整了變數的順序,難道是為了32bit對齊所作的優化?
接著來,多定義了乙個char變數:
輸出:bffff448 bffff444 bffff44c bffff440
3 3果然是把新定義的char變數放到了b的後面,這些不對齊的變數放到了堆疊的高位址(先入棧)。
接著驗證:
輸出:bffff44c bffff448 bffff444 bffff440
7 4b也是32bit對齊後,變成了先定義的在堆疊高位址(先宣告先入棧)。
再來:
輸出:bffff448 bffff444 bffff440 bffff43c
7 4再次加入char 型別變數之後,不是32bit對齊的char放在了堆疊的高位址處。
windows下用 codeblock + mingw(gcc 4.4.4)測試了一下題目的**:
堆疊裡的資料如下:
gcc4.4.4沒有優化32bit對齊,先宣告先入棧。
結論:
臨時變數在棧中的順序沒有強制規定,完全依賴於編譯器的實現,不應該對它做任何假設。
題外話:
這些沒有標準可查、像期末考試題一樣的筆試題不知道什麼時候才能消失。
C C 中的臨時變數
說到臨時變數,我們大家也許都挺熟悉,但是我自己對臨時變數的理解卻一直存在乙個誤區。通常情況下,我會把為了做某一件事情而臨時建立的乙個變數叫做臨時變數。比如說在交換兩個變數的值時,通常我們會建立第三個變數來達到我們最終的目的,而我們稱之為 臨時變數 然而,大師scott meyers告訴我們,事實不是...
程式設計中臨時變數的使用 20175204
提交 編譯執行沒有問題後,git add git commit m 陣列元素刪除,插入 git push 提交碼雲上你完成的 的鏈結。任務 定義乙個陣列,比如 int arr 列印原始陣列的值 for int i arr system.out.println 新增 刪除上面陣列中的5 列印出 1 2...
程式設計中臨時變數的使用 20175225
提交 編譯執行沒有問題後,git add git commit m 陣列元素刪除,插入 git push 提交碼雲上你完成的 的鏈結。任務 定義乙個陣列,比如 int arr 列印原始陣列的值 for int i arr system.out.println 新增 刪除上面陣列中的5 列印出 1 2...