2010-08-13 71 views
15

C/C++中的變量是如何工作的?C/C++中的變量是如何工作的?

我的意思是,一個指針存儲一個變量的地址,然後你必須解引用它來訪問它引用的對象,所以我認爲一個變量是一個指針,它在使用時會自動解除引用。這有什麼意義?

+5

指針只是一個變量,其內容是一個地址。 – Cascabel 2010-08-13 12:32:59

+0

你原來的想法是作爲C++中的引用語義實現的。參考文獻就是你所說的。在java中,除了像int這樣的值類型外,所有東西都是引用。 http://en.wikipedia.org/wiki/Reference_(C%2B%2B) – gtrak 2010-08-13 14:11:27

回答

29

變量是計算機上內存位置的抽象(方便的名稱)。在C/C++中,如果變量類型爲int它將是一個保存整數值的內存地址的方便名稱。

和一個變量不是一個指針自動解除引用。一個變量只保存它應該保持的值。如果它是一個指針,它將保存一個內存地址,如果它是一個整數,它將保存一個整數值,如果它是一個浮點數,它將保存一個浮點數......等等等等等等......

+6

變量可能並不總是存在於內存中的偏移量,例如局部變量,它們專門存儲在寄存器中。除此之外,+1簡而言之:) – Necrolis 2010-08-13 12:27:24

+1

確實如此。感謝您指出了這一點。雖然,您可以將**寄存器**視爲一種內存。你不能嗎? – 2010-08-13 12:29:05

+1

可能,但你不能指向一個寄存器 – 2010-08-13 12:31:28

-2

變量實際上並沒有做任何工作。相反,程序可能會對變量起作用。

+0

我想你誤解了他的問題。他打算問一下變量是如何實施的。 – jalf 2010-08-13 13:24:22

12

考慮以下定義

char *string="abc"; 
int b = 10; 
int *bptr = &b; 

我這簡化了一點點,使用十進制值,變量(名稱)是不會忽略佔位符,這些adressess具體的值存儲。

Adr content 
1000 a b c 0 // "abc" : string literal '\0' terminated 
1004 1000 // *string: pointer to string (address 1000) 
1008  10 // b = 10 : integer value 
1012 1008 // *bptr : pointer to &b 

通過使用例如, printf(「%s \ n」,字符串);你不想複製整個字符串,而是給出字符串開始的地址(通過引用調用)。

+0

謝謝大家的回答:) – Hugo 2010-08-13 12:44:24

2

局部變量可以存儲在內存中,也可以存在於寄存器中,也可以在程序執行的不同階段在兩者之間浮動,也可以與另一個變量共享空間。編譯器可以自由地爲變量分配最有效的空間。

如果你將一個指針指向一個變量,那麼編譯器需要將該變量放入內存中,以便它具有唯一的地址。但是如果你永遠不會拿一個指針指向它,那麼你的變量可能會保留在它自己的CPU寄存器中。或者如果你有兩個局部變量,並且你從不同時使用它們,那麼編譯器可以讓它們佔用相同的內存或CPU寄存器。

http://en.wikipedia.org/wiki/Register_allocation

0

不是好友 指針是一組變量,並區分它們,除了變量的數量,數值(整數,字符)必須是不同的!

6

變量是隻是一種抽象。它是的一個命名值,您可以參考,讀取和(有時取決於其類型)修改的

它存儲在硬件中的地方只是一個實現細節。通常是,它們通過將數據存儲在某個存儲器地址,然後在訪問變量時使用該地址來實現,因此從這個意義上講,它通常是一個「自動解除引用的指針」。

但有時,變量存儲在寄存器中而不是存儲器中。然後它沒有地址,並且不能創建指向它的指針。

有時,它甚至可能不存在於編譯後的代碼中。有時,編譯器可能會轉換代碼,因此變量不再必要,或者該變量可能會轉換爲單個編譯時常量。

最終,變量只存在於源代碼中。一旦你的代碼執行,變量不再存在。一些變量被轉換成內存位置,一些被完全移除,或者被轉換成你甚至不認爲是變量的東西。

例如,這樣的代碼:

int x = 10; 
y += 10; 

可以由表示x和y如存儲器位置進行編譯,然後加入由諸如「從存儲器地址x的值添加到的指令進行值在內存地址y「。

但是,編譯器也可以將常量10編碼到指令本身中,從而生成一個「在存儲器地址y上增加10的值」指令。當然,x是原始源代碼中的變量,但它不再是內存位置。它被直接編碼到指令流中。

0

變量只是保存它應該保持的值。如果它是一個指針,它將保存一個內存地址,如果它是一個整數,它將保存一個整數值,如果它是一個浮點數,它將保存一個浮點數...

8

要讀/寫一個變量是在已知位置讀取/寫入一段字節。 「知道位置」是編譯器已知的位置,它可以是:

  • 固定地址。編譯器知道全局變量的所有地址。如果我們讀取/寫入一個全局變量,編譯器將這樣的指令放在這裏:「讀取/寫入地址0x00235A87」
  • 固定堆棧偏移量。局部變量被壓入堆棧。指向堆棧頂部的指針(「堆棧指針」或「SP」)存儲在處理器寄存器中。編譯器知道堆棧頂部的局部變量偏移量是多少。如果我們讀取/寫入一個局部變量,編譯器會像這樣放置指令:「在地址'SP-0x05'處讀取/寫入內存」。
  • 處理器寄存器。變量在使用時加載到處理器寄存器中。編譯器知道哪些寄存器。要使用它們,不需要存儲器讀/寫,編譯器只需使用寄存器的指令,如「將寄存器B的內容添加到寄存器A」。

訪問變量實際上是以處理器指令的形式寫入的算法。變量可以是固定存儲器地址,計算的存儲器地址(使用固定偏移量和保存在寄存器中的值)或處理器寄存器的地址。編譯器放置在存儲器/寄存器之間和寄存器/寄存器之間移動變量值的指令。內存中甚至可能不存在變量,它可以一直保存在寄存器中。

你說的有某種比喻。

考慮到上述情況,請記住指針是保持地址(是整數)的變量。如果我們取消引用一個指針並讀取指向值,那麼必須完成兩個步驟。首先我們必須像讀取其他變量一樣讀取指針變量。之後,地址在寄存器中。然後我們用如下指令讀取指向變量:「在存儲在寄存器A中的地址處讀取存儲器」。

1

變量是指一個位置的名稱。位置解析爲編譯時間 - 編譯器在編譯時計算出位置,並將所有變量替換爲它們各自的位置。基本上,每當編譯器找到一個變量定義時,它就會將該名稱放入一個所謂的符號表中。它至少有兩列:名稱(如果您願意的話)和位置。簡而言之,當編譯器處理完所有變量並找出它們的位置時,編譯器會將所有變量引用替換爲它們各自的位置。 (還有更多的是這個,但這是一本值得物質的書...)

指針是變量也是。使指針有用的是存儲在(指針)變量位置的內容可用於讀取或寫入不同位置的值。這就是所謂的解引用指針。這在運行時間完成。在這方面,你不能真正說出自動解引用的變量,因爲工作從編譯時間延遲到運行時間。