C語言記憶體中是否存在乙個區域,儲存著變數的符號,變數的型別和變數的首位址?

時間 2021-06-02 01:14:44

1樓:fx991ESplus

沒有,編譯器在編譯的時候就已經完成了變數/函式名到實際位址(或者說是偏移量)的轉換了。

分割線順便提乙個有趣的事情,vs的編譯器為了能夠讓程式設計師較快的查出陣列下標越界之類的bug,在debug模式下分配記憶體的時候,每個陣列/變數之間都留下一大塊空白,裡面儲存著特定的資訊。

這就是有時候初學者的程式輸出詭異的「錕斤拷」,「燙燙燙燙燙」的原因啦╮( ̄▽ ̄")╭

2樓:文非尹

占個坑,晚上細答。先簡單說下。 很多答案說的結論都是對的,不過我估計剛接觸程式設計的新人看不懂。

你的想法是這樣:

程式設計師只輸入了變數的識別符號,然後系統,準確的找到了在記憶體中找到了這個變數的存放位置,並且讀取了合適的位元組長度

簡答:編譯器直接把所有變數翻譯成了位址,執行的時候cpu直接去對應位址取值。

觀眾:廢話麼。

那麼,為了清晰地展示這個過程,我碼了一大段字,發現還是不如上圖簡單。首先,我們選取乙個非常普通沒有特別意義的數字1024,做個實驗。

按照題主的猜測,計算機會先給a、b各分配乙個位址,然後把這兩個位址儲存在乙個表中。

接下來我要把變數a的值賦給變數b,所以計算機從位址表查詢到符號a對應的位址,取值,然後查詢符號b對應的位址,把值寫入。

那麼,這段程式編譯完,計算機到底怎麼處理的呢?廣告之後。。。咳咳,見圖,這是除錯時顯示的彙編資訊,我們造彙編就是方便human理解的CPU指令:

警察蜀黍快看!1024就在這裡,披上16進製制的馬甲也沒用!

a=1024是怎麼執行的?程式進入函式時,會被分配一段記憶體,我們叫他『棧』,這個棧是從頂部開始使用的,棧頂位址儲存在CPU的ebp暫存器中。

第11行這裡,-0x10(%ebp)在彙編中我們叫做相對定址,它表示ebp暫存器儲存的位址前面0x10個位元組,1024被儲存在了棧頂位址的前面0x10個位元組處;

第12行,2048被儲存在了棧頂位址的前面0x14個位元組處;

b=a怎麼執行呢?

第13行,把ebp前面第16個位元組(也就是0x10)的記憶體中的值,儲存到eax暫存器中;

第14行,把eax暫存器中的值,寫入-0x14(%ebp),也就是變數b的位址。

你看,計算機壓根不造什麼a啊b啊,他只管把記憶體中的資料讀出來,處理。至於讀取哪個記憶體位址的資料,怎麼處理,這些都是由編譯器完成的。

答完睡午覺嘍。

3樓:

如果是C++的話,有一些途徑。

C++的RTTI可以獲取型別資訊,不過要訪問存放這些型別資訊的記憶體的話比較困難。

如果乙個物件的型別有虛函式的話,虛函式表的第乙個元素的前乙個元素會存放乙個type_info的型別資訊。不過不同的編譯器生成的虛函式表的構成可能不一樣,這個方法也不是總成立,依賴於編譯器的具體實現。

4樓:

在C/C++的原始碼編譯後,是不會存在「變數名」/「變數符號」這種東西了,一切都轉換為實際的位址(或者和棧頂/EBP的偏移)操作了。而這個轉換的步驟,就是在編譯過程中完成的。

當然,有些時候為了除錯方便,編譯器會在編譯時,把變數符號對應的位址關係寫到可執行檔案中。這樣,如果出了問題,debug會比較方便。例如說gcc編譯時,加上-g引數就ok了。

不過即使是這樣,也未必是全部符號都會記錄,有些變數會在編譯過程中被優化掉的,那就真的徹底找不到了。

5樓:Milo Yip

C語言標準應該沒有說編譯後的東西是怎樣的,或可以說,即使編譯結果含有問題中的資訊,也沒有符合C語言標準的方式去獲取這些資訊。

而正常的編譯器在一般情況下不會儲存這些資訊,但是為了除錯或效能剖析,常會把類似的資訊(如debug symbol)儲存在可執行檔案或其他除錯檔案中,所以在偵錯程式裡你是能看到識別符號與其值的對應關係。

6樓:Xi Yang

通常沒有,而是在編譯的時候,把那塊記憶體當作某種型別使用。

指標型別的變數,其內容就是儲存某乙個東西的「首位址」,用於執行時可以變化的效果。C++簡陋的RTTI系統,才提供了執行時的型別標籤。

指令碼語言才會真的存乙個變數名和函式名的表,以及型別資訊,而且它們的變數通常不是基本型別,函式也不是native函式。

c語言的乙個疑問?

最佳答案就在C語言的標準裡,C99標準裡定義了6種statement 語句 for語句屬於 iteration statementif語句屬於 selection statement所謂花括號 屬於compound statement而帶分號 的語句屬於expression statement這裡需...

C 中define乙個常量和const是否完全相同?

scientificworld NO.define是直接定義巨集,在預處理階段你如果看一下輸出檔案就會發現裡面肯定已經沒有乙個 define了,同時那些用到了這個巨集的地方也已經被替換掉了。包括像 if,ifdef,ifndef,else,endif,progma這些也沒了 const是常量,不會被...

關於C語言, GCC MSVC中,如何寫出乙個真正意義上的不依賴庫的程式?

很多微控制器程式是不依賴庫的,它們會有中斷呼叫。很多微控制器的編譯器是用GCC。既然問題又提到MSVC,就意味著Windows程式,不依賴庫是不行的,因為作業系統已經將軟硬體隔離,任何呼叫都需要經過作業系統一層,可以寫出看不到依賴庫的程式 方法是從 Process Envirorment Block...