簡體   English   中英

為什么C變量存儲在特定的內存位置?

[英]Why C variables stored in specific memory locations?

昨天我接受采訪時面試官問我存儲變量的存儲類。

我的回答是戰爭:

Local Variables are stored in Stack.       
Register variables are stored in Register
Global & static variables are stored in data segment.  
The memory created dynamically are stored in Heap.

他問我的下一個問題是: 他們為什么要存儲在那些特定的記憶區域? 為什么Local variable 沒有存儲在register (雖然我需要在我的程序中經常使用auto變量)? 或者為什么全局變量或靜態變量not存儲在stack

然后我一無所知。 請幫我。

因為存儲區域決定了變量的范圍生命周期

您可以根據需要選擇存儲規范,即:
生命周期:您期望特定變量需要存活且有效的持續時間。
范圍:您希望變量可訪問的范圍(區域)。

簡而言之,每個存儲區域提供不同的功能,您需要各種功能,因此需要不同的存儲區域。

實際上,C語言沒有定義任何變量的存儲位置。 但是,它確實定義了三個存儲類:靜態,自動和動態。

靜態變量在程序初始化期間( main()之前main()創建,並保持存在直到程序終止。 文件范圍('全局')和靜態變量屬於該類別。 雖然這些通常存儲在數據段中,但C標准並不要求這種情況,並且在某些情況下(例如,C解釋器),它們可以存儲在其他位置,例如堆。

自動變量是在函數體中聲明的局部變量。 它們是在程序流程到達聲明時或之前創建的,並在它們超出范圍時被銷毀; 為遞歸函數調用創建了這些變量的新實例。 堆棧是實現這些變量的便捷方式,但同樣,它不是必需的。 如果你選擇的話,你也可以在堆中實現自動化,並且它們通常也放在寄存器中。 在許多情況下,自動變量將在其生命周期內在堆棧和堆之間移動。

請注意,自動變量的register注釋是一個提示 - 編譯器沒有義務對它做任何事情,事實上許多現代編譯器完全忽略它。

最后,動態對象(C中沒有動態變量這樣的東西)引用使用malloccalloc或其他類似分配函數顯式創建的值。 它們在顯式創建時存在,並在顯式釋放時被銷毀。 堆是放置這些的一個方便的地方 - 或者更確切地說,一個堆基於執行這種分配方式的能力來定義堆。 但同樣,編譯器實現可以隨意做任何事情。 如果編譯器可以執行靜態分析來確定動態對象的生命周期,則可能能夠將其移動到數據段或堆棧(但是,很少有C編譯器執行此類“轉義分析”)。

這里的關鍵外賣是,C語言標准只定義了一個給定的值是多久存在了。 並且這個生命周期的最小界限 - 它可能會比所需的更長。 究竟如何將其置於記憶中是一個主題,其中語言和庫實現給予了很大的自由。

它實際上只是一個方便的實現細節。

如果他願意,編譯器可以根據需要在堆上生成局部變量。

在堆棧上創建它們更容易,因為在離開函數時,您可以根據堆棧的增長方向通過簡單的加/減來調整幀指針,從而自動釋放用於下一個函數的已用空間。 然而,在堆上創建本地人意味着更多的管家工作。

另一點是不能在堆棧上創建局部變量,如果編譯器認為更合適並且有足夠的寄存器來執行,則可以將它們存儲並僅用在寄存器中。

在大多數情況下,局部變量存儲在寄存器中,因為當您進行函數調用時,寄存器會從堆棧中推送和加載它看起來像是在堆棧上。

實際上沒有像寄存器變量那樣的東西,因為它只是C中一些很少使用的關鍵字,它告訴編譯器嘗試將它放在寄存器中。 我認為大多數編譯器都會忽略這個關鍵字。

那就是為什么問你更多,因為他不確定你是否深刻理解話題。 事實上,寄存器變量實際上是堆棧。

在嵌入式系統中,我們有不同類型的存儲器(只讀非易失性(ROM),讀寫非易失性(EEPROM,PROM,SRAM,NVRAM,閃存),易失性(RAM)),我們也有不同的要求(不能改變)並且在電源循環后仍然存在,可以改變並且在電源循環后持續存在,可以隨時更改我們擁有的數據。 我們有不同的部分,因為我們必須樂觀地將我們對數據的要求映射到不同類型的可用存儲器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM