C語言中內存地址是否佔用存儲空間呢?

比如內存地址0028FF1C 這些數字和字母是否需要佔用存儲空間呢?原因是?

計算機如何識別這些代碼?謝謝


要看具體的情況。基本上有兩種情況,棧變數和堆變數。

棧變數是直接聲明出來的,比如 int i. 那麼 int i 計算機是怎麼處理的呢。編譯器會對一個函數的棧變數總長度有一個記錄。當時調用一個函數的時候,內存會分配一段空間儲存你所有聲明的變數。就像大學分宿舍,所有人住到特定的床位上去,而且是一次性分配的。這時候你的床位號本身並不需要有一個床位。床位號只是每個人的一個位置描述。

另外一種是堆變數。也就是你用malloc出來的空間。malloc的空間放在一個地方,它的指針你肯定需要一個堆變數來存儲它。比如int *i = malloc(4). 實際上這裡有兩個變數被創造,一個是那個真正的int,一個是那個指針。那個int是堆變數,4位元組,指針是棧變數, 8位元組(64位機)。這時候這個指針是佔了空間的。但是這個指針的指針又不佔用空間,因為這個指針是棧變數。


要,而且肯定要。

不過可能作為代碼的一部分,也可能作為數據的一部分。

但絕大多數情況下不是英文加數字,而是十六進位。

很簡單,程序就像一個快遞員,在一排房子里送快遞。你需要知道目的地在哪,就必須要存儲這個地址。

不過存儲的方式是多樣的,可以是第10幢房子,也可以是現在的房子往後數五幢,也可以是第八幢房子里放的快遞單上寫的地址往後數兩幢。

也就是說你想表達地球上一個確定的地點,你就必須說出這個地點的經緯度,可以是絕對的經緯度,也可以是相對當前位置偏移的經緯度,也可以是相對其他位置偏移的經緯度---但總之,總要存儲一部分地址的數據,而不能憑空說「那個地方」,而不存儲位置。

不過看題主的描述也可能是問,內存的每個位元組是不是都掛著一個門牌號,這個門牌號是不是需要佔地方。

如果是這樣的話,答案是不用。就像學生按學號順序排成一列或者一個方陣,你只要知道了排列的順序和第一個人在的位置,就能直接根據學號找到那個學生,而不用一個個去看他們佩戴的號碼牌。


假如佔用,那麼它又有了自身的地址,自身的地址也得佔用空間呀,……。得,無限遞歸了。


肯定佔用,只不過佔用的不是內存空間,而是寄存器的存儲空間。

內存地址實際上是一種偏移量,存儲於段寄存器中。內存地址只是一種抽象,不是真正的物理內存地址,而是邏輯地址。由邏輯地址尋找到物理地址需要經過 邏輯地址-&>線性地址-&>物理地址 轉換過程,而這些過程都是基於寄存器完成的。地址是16進位,關於計算機如何識別16進位,甚至關於內存地址更詳細的知識,題主可以通過看相關書籍(比如CSAPP,操作系統相關的書籍,了解操作系統如何進行內存映射)進一步深入了解。

謝邀。


1.內存地址要不要佔據內存空間?

這裡有一個非常重要的關鍵點,那就是顯示器。顯示器具有很大的迷惑性,他會讓你產生錯覺,認為代碼是你寫出來的。

其實你用腳想一想,顯示器上面的字是你寫的么?代碼真的是你打出來的?你用筆在上面寫字,還是用刀刻,使顯示器出現字?

而且,顯示器對於計算機來講並不是必要的。

所以,你所看的一切都是假的,人們真正所做的事情,就是敲擊鍵盤,或者點擊滑鼠。

當你敲鍵盤,點滑鼠的時候,會產生一道道微弱的電流,會稍微改變計算機電路裡面的部分電壓。計算機裡面的一切,都是以電壓的形式存在。而顯示器唯一的作用,就是通過層層抽象,把電壓的變換抽象出來,變成代碼讓你看到。

內存也是一坨龐雜無比的電路。經過層層抽象,最終才會顯示出來幾個16進位數供你操控。每個16進位位,都代表4根線。0028FFEC有8個16進位位,意味著這是一個32位的計算機。這意味著地址的變化會改變32根線的電壓。這也是你通過鍵盤的按壓實現的。

可是這個和地址佔不佔據空間有什麼關係呢?

其實你的問題應該稍微修改一下,最好分裂成文兩個。

第一個,顯示器上面出現的代碼和地址到底佔不佔空間?

回答:顯示器上面出現的任何東西都會佔據空間。只要是你通過鍵盤打的字,都會佔據空間。

第二個,內存地址到底是什麼?

回答:你用c語言寫程序的時候,左邊會有12345678...的行號,尤其是你寫大程序和調試的時候。行號是很重要的。它能幫你精確的定位。

如果把內存想像成為篇巨長的程序,或者一篇巨長的文章。那麼內存地址就是相當於行號之類的東西。

然而對於計算機來講,就是通過真實的線路來操控地址的。32位的計算機意味著它有32根線,任意改變,計算機就會根據電壓變化重新定位到一個內存。

2. 計算機怎麼識別內存地址?

計算機根本就不需要識別內存地址。它是由硬體電路實現的。就像發電廠發的電點亮了你家電燈一樣。是因為你家的電燈的電路連接了發電廠的電路,而不是因為發電機能夠自動識別你家地址。

也就是說,內存地址是人類從電路裡面抽象出來的給人識別的,而不是給機器識別的。

它本質上是一個數據選擇器。內存地址在機器看來就是一堆選擇線。

也就是說,雖然發電機已經連接了你家的電燈,但是你依然需要合上你家門口的閘刀,來讓電路導通。這樣你家的電燈才會亮。

如果我們對家門口的閘刀進行編碼,假設0為斷開狀態,1為合上狀態。假設有八戶人家。我們輸入00000001(手動扳開關),這時候就有一戶人家的燈是點亮的。輸入00100010(手動去人家門口扳閘刀),就會有兩戶人家的燈是亮的。但是你能說,是因為發電機能夠識別人家的地址嗎?

我們對計算機輸入地址(比如FF0062BC)的時候本質上也是一樣的,它會使用二進位的形式存在內存裡面。而內存中的數據實際上是通過電信號的方式存儲的(也就是說,在內存裡面,0就是一段低電平的導線,1就是一段高電平的導線)。

你可以想像成為,內存裡面有許許多多的閘刀,當你輸入一個地址,他就會自動改變電信號,扳動內存裡面的閘刀,使得其中一些導線可以被使用。

計算機只是提前連接好了所有的線路,你可以直接想像你輸入地址就是扳動了內存裡面的開關,讓裡面的的一部分數據可以使用。(就和扳動開關那一家的燈就能使用的原理是一樣的)


要的,不然怎麼會有pointer


比如內存地址 0028FF1C 這些數字和字母是否需要佔用存儲空間呢?原因是?

計算機如何識別這些代碼?謝謝

---

問題描述嚴重不清晰不明確,所以無從解釋。

比如說,一個指針 hold 了一個地址,或者該地址作為參數傳遞而被 push 到 stack ,那麼這個指針當然佔用存儲空間,比如 0028FF1C 如果是一個指令中的立即數,當然也會佔用存儲空間,直接嵌在代碼段的指令中。


我的理解是:

假如有一條語句,功能是將一個變數值賦值給另一個。

那麼這個變數是在程序的某個地方聲明的。

假設現在程序沒有跑在有MMU的處理器上,各段由ld在編譯時固定指配。變數為全局變數

那麼編譯後這個變數就會有一個地址,並且是固定的(在有MMU的操作系統上它相對虛擬地址空間也是固定的)

這個固定的地址會在數據段的某個部分。

在執行這個語句的時候要把這個變數值讀進CPU寄存器對吧,MOV語句執行的是內存和寄存器之間的數據交換對吧,所以在執行x = y大概是先MOV Y內存地址到寄存器A,再MOV A到X內存地址,在這個過程中只存在對地址的操作。指令中寫的就是把地址叉叉叉放到叉叉叉。

至於變數名……

機器代碼中是沒有變數名的,吧…


需要佔用的,由操作系統維護的一個內存表。這個是邏輯內存表,比物理地址大。而且不只是只有地址,還有對應的有沒有使用的標記。

為什麼會比物理內存大呢?想想虛擬內存,虛擬內存也是需要地址,所以當訪問的地址是的數據是虛擬內存上,操作系統會把地址對應的虛擬內存從硬碟拷貝到內存里,然後將物理地址和邏輯地址關聯。

這樣子物理內存夠存嗎?內存表並非是儲存完全的邏輯地址對應物理地址,而且有一定的數據結構。內存分頁、分段等概念多少應該聽過吧,系統會將內存分塊管理起來。這就像樹結構一樣,沒使用到的地方是不會佔用空間的,當程序運行用到時,才會建立更詳細的內存表去維護,所以就夠存啦。

咱不是專門研究操作系統的,只是稍微了解過,用自己所理解的、非專業的詞語表達。o( ̄ε ̄*)


我是這樣理解的,內存地址就像是對機器原件的編號,比如第一車間,第二車間,是印刷在門上的東西,門都是一樣的。


不佔用,因為地址只是計算機對位元組賦予的編號,並一一對應。地址可以說是一個硬性的"標識符",不能改變。而內存中的位元組內容是可以讀寫的。

以上只是我的個人見解,題主可以參考


推薦閱讀:

如何評價清華大學網路科學與網路空間研究院?
如何限制電腦,禁止玩大型遊戲?
計算機博士換導師?
筆記本在接通電源的時候電池應該取下嗎?

TAG:編程 | 計算機 | C編程語言 | 計算機技術 | CC |