從變數到指標到引用

2021-07-31 22:09:19 字數 1871 閱讀 8652

1. 再熟悉不過的說法,引用是變數的別名,操作引用跟操作變數的效果是一樣的;

2. 引用不是物件,因此,不會給引用分配記憶體空間;

3. 引數傳遞如果形參是引用,那麼此時引用的表現就像指標一樣,可以直接改變變數的值。

這三個特點聽起來簡單,但是如果深入思考一下,就不由得疑惑

究竟是什麼造成了引用的這些特點,而引用或者「別名」又到底是什麼東西?

變數定義的特點:

1. 對於 int a 這條語句,編譯器會分配乙個 4 位元組的記憶體單元(典型的32位機上,假設起始位址是0x124efdd8),並將這個記憶體單元和 a 這個變數名繫結在一起;

2. 我們知道,編譯的過程中,對於函式名、變數名等都會替換成相應的符號,所以我們假設編譯後 a 變數名被替換為符號 l1,那麼這個過程的示意如下:

3. 當我們訪問變數 a 時,其實就是通過 l1 這個符號訪問相應的記憶體單元的。所以,變數一旦定義之後,無論我們會把哪個變數賦給 a ,其實質只是把該變數的內容寫到 0x124efdd8 這塊記憶體單元中而已,l1 和 0x124efdd8 的繫結關係是永遠不變的。

引用定義的特點:

1. 假設 int &aref = a 即 aref 是 變數 a 的引用,那麼此時編譯器對 aref 會做出怎樣的行為呢?

2. 根據 「引用不是物件,不會分配記憶體單元」 的特徵,我們可以得出結論,引用定義時,編譯器沒有為引用分配記憶體空間,只是簡單的把引用替換為乙個符號(我們假設是 l2);

3. 根據 「引用是變數的別名」 的特徵,其實我們已經可以知道,編譯器是把引用和變數的記憶體空間繫結起來了,即將l2 和 0x124efdd8 繫結到一起,示意如下:

4. 當我們訪問引用時,也是通過符號 l2 進行訪問,所以,訪問 aref 時最終訪問的也是 0x124efdd8 ,這樣就解釋了「操作引用和操作變數的效果是一樣的」這一特點。

那麼指標和引用的區別又在**呢?

1. 假設 int *p = &a 即定義指標 p 指向變數 a ;

2. 指標也是乙個變數,所以編譯器遇到指標時,也會為指標分配儲存空間(假設是 0x3473afb4),然後把替換後的符號(假設是 l3)和這一塊記憶體單元繫結起來,同時,我們知道,指標的內容是變數的位址,所以可得如下示意圖:

3. 從上圖我們就可以明白,當我們訪問指標時,通過 l3 訪問到0x3473afb4 ,但是我們如果想要訪問它所指向的物件時,就要進行解引用(*p) 才能訪問到變數 a ,而引用就不需要解引用這一操作,因為它直接就指向了變數 a;

指標和引用在引數傳遞時,編譯器的行為:

1. 兩種情況下都不用複製操作物件,也都可以修改操作物件;

2. 但是實現機制不同,以指標為引數時,編譯器同樣對指標進行了值傳遞(變數的傳遞都是值傳遞,指標也是變數,所以指標傳遞的時候,指標本身也是值傳遞),然後利用這個臨時指標訪問變數(需要解引用),假設指標臨時變數符號是 l4 ,記憶體位址是 0x3473feda ,則示意如下:

3. 以引用為引數時,因為引用根本就不是變數,所以編譯器不會建立引用的臨時變數。其實質是當編譯器遇到引用形參時,是直接用實參的標號來訪問變數的,即直接通過 l2 來訪問變數,所以同樣可以修改變數的值(不需要解引用)。

以上就是對變數、指標、引用的簡單總結。如有錯誤之處,歡迎指出~

從變數到常量

現階段,我是乙個 變數 而且在接下來很長的一段時間內,我都無法改變我是乙個 變數 的狀況。為什麼說自己是變數呢?因為,我覺得自己容易受他人影響。看部落格 看新聞 看微博 和別人聊天 看 看書,都是被別人影響的過程。被別人影響不一定是壞事,但問題是有多少人 多少知識在影響你,有多少人和資訊能對你的人生...

作文 從指標變數到指標函式,路過函式指標

從最簡單的指標變數出發,比如int a 那麼a是乙個整形變數 現在int a 那麼a是乙個指標變數 指標a表達的是某個位址,它需要依託某個實實在在的東西 比如 typedef struct ringbuff t static ringbuff t ringbuff ringbuff t pringb...

從變數到函式,從函式和全域性變數到模組,從模板到包

總體來說關係從上到下 包 子包 模組 全域性變數 函式,函式 變數。一 包 packages 包是指乙個包含模組與乙個特殊的 init py檔案的資料夾。二 模組 modules 乙個模組可以被其他程式匯入並執行其功能。通常通過使用 import 和 from.import 語句來實現。比如 imp...