不要試圖去固化理解編譯器的行為,尤其是C語言規範中沒有定義的行為。這些行為包括但不限於:變數分佈,++/--混用的時候的優先順序,函式呼叫時引數的計算次序等等。你這個問題裡,區域性變數在棧上的排列次序是語言標準中沒有規定的內容,所以:它們怎麼排列,間隔是多大,完全看編譯器的設計者,換句話說,可能是任何形式。如果你們老師非要說區域性變數地址一定是從下到上,那麼,你們老師錯了。舉幾個例子:1. 在比較老的編譯器裡,如果沒有對變數取地址的操作,那麼有些區域性變數是透過暫存器儲存的,不佔棧上記憶體,根本不存在記憶體中如何排列的問題,比如TurboC 2.0這種。2. 在一些較新的編譯器裡,區域性變數有些是根據使用頻率來排列的,這樣可以降低cache的miss率,所以怎麼排列完全根據使用頻率。3. 大部分主流編譯器的區域性變數地址確實是從下到上,但也有反過來的。從下到上排列的好處之一是編譯器處理一個函式的時候,可以動態增長棧的長度,不需要先判斷區域性變數有多少個。4. 還有一些非主流編譯器會調整變數的排列次序,使得其在各個變數基本對齊的情況下佔用的棧空間最小,對於一些嵌入式裝置來說,非常有用。所以,你的第一個問題,如果你非要研究編譯器,也可以,但這不是常態,不同編譯器行為可能不同。同一款編譯器在不同平臺上也可能不同。第一個問題裡,a的地址範圍是XXXX6BE8-XXXX6BEB,中間空出3個位元組,然後是c的地址,正好對齊到4位元組。至於為什麼c的地址是XXXX6BEF,而不是XXX6BEC,這個可能就是編譯器的特性吧。第二個問題:結構體佔的位元組大小,這個確實會有對齊的情況,但除非你用packed之類的編譯引數指定,否則在不同的硬體平臺上,效果可能也不完全一樣。
不要試圖去固化理解編譯器的行為,尤其是C語言規範中沒有定義的行為。這些行為包括但不限於:變數分佈,++/--混用的時候的優先順序,函式呼叫時引數的計算次序等等。你這個問題裡,區域性變數在棧上的排列次序是語言標準中沒有規定的內容,所以:它們怎麼排列,間隔是多大,完全看編譯器的設計者,換句話說,可能是任何形式。如果你們老師非要說區域性變數地址一定是從下到上,那麼,你們老師錯了。舉幾個例子:1. 在比較老的編譯器裡,如果沒有對變數取地址的操作,那麼有些區域性變數是透過暫存器儲存的,不佔棧上記憶體,根本不存在記憶體中如何排列的問題,比如TurboC 2.0這種。2. 在一些較新的編譯器裡,區域性變數有些是根據使用頻率來排列的,這樣可以降低cache的miss率,所以怎麼排列完全根據使用頻率。3. 大部分主流編譯器的區域性變數地址確實是從下到上,但也有反過來的。從下到上排列的好處之一是編譯器處理一個函式的時候,可以動態增長棧的長度,不需要先判斷區域性變數有多少個。4. 還有一些非主流編譯器會調整變數的排列次序,使得其在各個變數基本對齊的情況下佔用的棧空間最小,對於一些嵌入式裝置來說,非常有用。所以,你的第一個問題,如果你非要研究編譯器,也可以,但這不是常態,不同編譯器行為可能不同。同一款編譯器在不同平臺上也可能不同。第一個問題裡,a的地址範圍是XXXX6BE8-XXXX6BEB,中間空出3個位元組,然後是c的地址,正好對齊到4位元組。至於為什麼c的地址是XXXX6BEF,而不是XXX6BEC,這個可能就是編譯器的特性吧。第二個問題:結構體佔的位元組大小,這個確實會有對齊的情況,但除非你用packed之類的編譯引數指定,否則在不同的硬體平臺上,效果可能也不完全一樣。