淺談指針的本質


  

內存地址(普通指針)或偏移地址(成員指針)。

 

指向變量的指針,是數據內存的地址,指向函數的指針是代碼內存的地址,指向數據的指針指向數組開始位置的地址。

 

抽象點說,就是以一種統一的方式產生對不同數據結構的元素的引用

 

理解指針要注意以下幾個點:

  -- 每個指針都有類型,類型決定指針移動時的步長(假設可移動:++ / -- / +n / -n)

  -- 從內容上講,指針就是地址,尤其是在機器級層面上

  -- 對指針進行類型轉換,僅僅是改變了解釋指針所指內存區域的方式,位模式沒有變

  -- 指針可以指向函數,其值是函數對應機器代碼的第一條指令的地址

  -- 指針和數組關系曖昧,如果你明白比例變址尋址,你就能清除數組名,下標,指針類型之間的關系,簡單說:數組名即基地址(立即數),下標即變址,指針類型即比例因子,而指針的值就是:偏移量 + 變址 * 比例因子 +基地址【IA32】,這樣你就明白數組名是個常量(在機器眼里就是個立即數尋址時對變址沒有限制也就說明了C語言對下標越界不檢查

 

 

  指針是儲存地址的一個變量

 

指針變量儲存的就是一個地址, 可以有如下行為:
  * 改變該變量的值;
  * 取得該變量的值
這和其他變量是一樣的, 但是指針還可以做到:
  * 改變該變量指向的那個地址的值
  * 取得該變量指向的地址的值
這只是編譯器賦予指針的特定行為而已(通過& * 等語法), 在匯編層面大概就是間接尋址了.
因此指針就是儲存地址, 糾結「指針的指針」什么的可以退散了.

指針為什么要有類型

匯編中數據是沒有類型的, 所以指針的類型是編譯器在規定的, 通過了指針的類型檢查, 才能保證你少犯錯.
因為其他數據有類型, 所以指針也得有類型.


指針的類型表明: 你期望從這個地址里取出來的數據, 是什么類型的.

  大部分時候, 我們想從一個 *int 指針中取出來的值總是 int, 只有在特殊情況下我們才會想把 int 當成 uint 取出來, 類型檢查就幫我們減少弄錯類型的可能.

  另外, 類型也規定了指針移動的粒度, 你期望從一個 *int 取出一個 int, 那 *(int + 1) 如果是地址+1的話, 不就取出了奇怪的數字?
所以這里的 *(int + 1) 的 1 起始是指代一個 sizeof(int), 這樣你才能方便地訪問連續的內存數據.
在匯編中大概就是 [arr + 4]. (32位限定), 編譯器根據指針的類型幫你做了這一步轉換.
 
  你會發現計算機的本質就是計算,計算的內容是什么呢,就是數據,數據哪里來呢,需要有東西搬過來,這里面就需要用到寄存器了,在這里也可以理解成指針,不然計算機里面這么多數據,鬼知道要用到哪些數據來計算呢,要知道運算器只知道計算,再談指針的類型??不就是告訴運算器或者說是計算機這些數據的內存范圍嗎,當然也有其他用途。對指針的理解不能止步於此,深入了解還得指望匯編了,無奈暫時沒時間學習匯編,暫時粗粗的看看反匯編代碼罷了,日后再整理。
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM