2010-09-10 84 views

回答

50
  • 本地變量可以存儲在棧中或在數據段取決於它們是否是自動的或靜態的。 (如果沒有明確指定既不自動或靜態的,假設自動)

  • 全球變量存儲在一個數據段(除非編譯器可以優化他們離開,見常量),並具有從申報點的可視性編譯單元的結尾。

  • static變量存儲在數據段中(同樣,除非編譯器可以優化它們)並且從聲明點到包含範圍的末尾都具有可見性。非靜態的全局變量在其他編譯單元中也可見(請參見extern)。

  • auto變量總是本地的,並存儲在堆棧中。

  • 寄存器修飾符告訴編譯器儘可能將變量保存在寄存器中,如果可能的話。否則它將存儲在堆棧中。

  • extern變量存儲在數據段中。 extern修飾符告訴編譯器,一個不同的編譯單元實際上正在聲明該變量,所以不要創建它的另一個實例,否則會在鏈接時產生名稱衝突。

  • const變量可以存儲在堆棧或只讀數據段中,具體取決於它們是自動還是靜態。但是,如果編譯器可以確定它們不能從其他編譯單元引用,或者代碼沒有使用const變量的地址,則可以自由優化它(每個引用可以由常量值替換) 。在這種情況下,它不存儲在任何地方。

  • 揮發性修飾符告訴一個變量的值可以在改變它的編譯器隨時從外部影響(通常是硬件),因此它不應該試圖從存儲器優化掉任何重新加載到寄存器中時變量被引用。這意味着靜態存儲。

順便說一句這一切適用到C & C++以及Objective-C的。

+0

除了談論const時,「text segment」指的是「數據段」。 – JeremyP 2010-09-10 13:58:19

+0

@JeremyP - 是的,當然:-) – Ferruccio 2010-09-10 14:21:22

+0

太棒了! +1的輝煌答案。如果您在這種情況下提及堆內存和指針,它將會更完美! – 2015-01-10 11:48:12

2

局部變量通常存儲在堆棧中,全局變量存儲在程序的「文本」段(如果是字符串常量)或堆中(如果它們是動態分配的)。自動變量通常用在函數/方法中,通常在堆棧上傳遞(有時在寄存器中也取決於架構)。寄存器變量曾經存儲在寄存器中,但是現在大多數編譯器忽略寄存器關鍵字並將它們放在任何他們認爲合適的地方 - 堆棧或寄存器中。 Extern,const和volatile成員是修飾符,因此它們沒有存儲的明確位置。

所以簡短的回答就像往常一樣,「取決於」。

5

Local和auto變量存儲在堆棧中。 Global和static變量存儲在DATA頁面中。 register如果可能的話,變量存儲在CPU的寄存器中,否則存儲在堆棧中。 extern,constvolatile不指定變量的存儲位置;該變量存儲在其他存儲說明符所說的地方。

+1

文本段通常只讀。全局變量將位於數據段中。 – JeremyP 2010-09-10 13:59:40

+0

@JeremyP:你是對的,那裏有一個小小的頭腦風暴。 – 2010-09-10 14:10:32

11

在什麼樣的抽象層次上尋找答案?

在物理層面,它們都可能存儲在柵極電容和磁疇中。 (如果你的交換磁盤是wifi或光纖連接,甚至可能是光子)

在一個硬件級別,任何和所有這些變量的副本可能存在於寄存器,數據緩存(可能是多個級別) ,主內存和/或存儲層次結構,從完全換出到磁盤或NV存儲(取決於任何需求分頁的虛擬內存子系統的存在,實現和當前狀態),甚至可能是寄存器中的所有內容(如果您的應用程序大小而且一生都很小。由於最熟悉的編譯器和運行時實現,內存(也許是虛擬的)被切割成堆棧和堆棧。鑑於正式的語言定義,這種斬波可能或可能不需要。

在編譯器優化級別,許多這些變量可能已經被優化了。除了作爲抽象,它們不會被存儲在任何地方。

+0

+100希望我可以多次投票,以使這個投票答案最多:) – pmg 2010-09-10 18:07:08

+0

我最喜歡抽象部分。 – 2010-09-11 06:54:42

1

LOCAL-範圍在函數中使用的局部變量。它可以是自動或靜態兩種類型。 如果它被聲明爲簡單int var.Compiler視爲自動存儲類。 自動變量存儲在堆棧中。 靜態變量存儲在數據段中。

寄存器變量存儲在CPU中。如果沒有寄存器可用於存儲變量,則編譯器視爲自動變量。

全局變量存儲在數據段區域中。

const變量存儲在只讀區域,即memeory的代碼段區域。