再談c 中的引用

2022-05-15 09:41:54 字數 2196 閱讀 5374

在《從彙編看c++的引用和指標》一文中,雖然談到了引用,但是只是為了將兩者進行比較。這裡將對引用做進一步的分析。

int

main()

下面來看一下main函式的彙編碼:

int

main()

從上邊初始化指標和引用的彙編碼可以看出:兩者都是儲存的變數的位址,雖然初始化指標的時候明確使用了&運算子,但是初始化引用的時候,編譯器仍然儲存的是變數i的位址。

而在用指標和引用操作各自所指的變數的時候,對於引用,雖然沒有使用*運算子,通過儲存的位址獲取變數的對應值,但是,編譯器已經幫我們做了,可以把對引用和指標的操作的彙編碼進行比較,可以發現,二者是一樣的。

因此,對於指標,pj它儲存的是變數j的位址,但是如果我們要通過指標變數pj獲取j的指標,必須自己用*運算子做這種定址操作;但是,但我們是用引用的時候,ri雖然也儲存的是變數i,但是獲取變數i的值的時候不必使用*運算子來定址,因為編譯器已經幫我們做了,正因為省略了用*運算子定址的過程,使得引用使用起來更像普通變數一樣,也就是說使用引用ri和使用變數i的效果是一樣的。我覺得,這就是把引用稱為變數的別名的原因。

作為一種特殊的型別,引用也有它自己的特點:

1 必須初始化

2 不能指向null

3 一旦初始化了引用,這個引用就一直引用某一變數,無法改變。比如,ri只能是i的引用,不能通過ri=j使其引用變數j,這條指令只是將ri引用的變數i賦值為j的值,ri仍然引用的是i,也就是說儲存的仍然是變數i的位址,即給引用賦值,只能在初試化的時候。

4 永遠也無法獲取引用的位址,即無法通過&ri獲取ri的位址,這樣獲取的都是變數i的位址

5 沒有引用型別的陣列,即,不能宣告int& a[3];

下面來看引用作為引數和返回值的情況:

c++原始碼如下:

//

該函式傳遞引用也返回引用

int& f(int&i)

intmain()

下面是main函式對應的彙編碼:

7    : int

main()

可以看到,傳遞給函式f的引數時實際引數變數i的位址,這和上面講的ri=i一樣,只不過這裡使用實參初始化形參引用。

下面是函式f的彙編碼:

;

2 : int& f(int& i)

可以看到,函式f返回的值也是乙個位址,即實參i的位址。

從上面可以總結,當引用作為引數和返回值的時候,實際上也是傳遞和返回的位址

當用引用作為引數時,可能產生臨時變數,然後用臨時變數的位址初始化引用引數,但是產生臨時變數有條件:

c++原始碼如下:

void f(int&i) {}

intmain()

編譯之後,就會產生如下錯誤:

出現這種錯誤,是因為要呼叫函式f,必須為其傳遞乙個位址,但是(i + 1)並不是乙個變數,也就是說,並沒有為(i + 1)生成臨時變數,無法獲取位址,它只是乙個非左值。下面就來看一下生成臨時變數的條件:

在引用引數為const的情況下:

1 實參的型別正確,但是不是左值(上面的型別就是這種情況)

2 實參的型別不正確,但是可以轉換成正確的型別

所謂左值,就是可以被引用的資料物件,常規變數(可以修改的左值)和const變數(不可以修改的左值)都可以看成左值,而非左值,包括字面常量(比如單純的數字1,但用引號括起來的字串除外,他們有位址表示)和包含多項的表示式,他們不能被取位址,也不允許賦值。

因此,如果把上述函式f的引數型別改成const int&就可以通過編譯,因為這時候會為(i + 1)生成臨時變數。

為什麼作為函式引數的引用型別要是const才能生成臨時變數?因為使用引用作為函式引數的目的,就是可以修改做為引數傳遞的變數,但是,建立臨時變數會阻止這種意圖,也就是說,如果作為引數的引用沒有const關鍵字,而臨時變數依然可以產生,那麼,引用操作的將是這些臨時變數,而不是傳遞進來的引數本身(這和傳值差不多)。而有const關鍵字的時候,表示函式不能改變這些傳進來的引數,因此,用生成的臨時變數來初始化這些引數也就無所謂了。

但是,上面的規則,只是對於內建型別成立,而對於復合型別(結構體和類,不包括陣列,因為沒有引用型別的陣列,陣列只能通過指標傳遞),總是會生成臨時變數:

class

x ;void f(x&x) {}

intmain()

上面的c++**可以通過編譯。

C 中的引用

最近重新看c 看到些以前沒注意的dd,溫故而知新,暫且記下。引用是能自動間接引用的一種指標,即不必使用間接引用運算子 就可以得到乙個引用值。引用可以為變數起別名,它主要用作函式引數以及函式的返回型別。1 引用的定義 如 int i int j i j是i的引用。1 定義引用時,必須立即對它進行初始化...

C 中的引用

例1 int a int ra a 定義引用ra,它是變數a的引用,即別名 說明 1 在此不是求位址運算,而是起標識作用。2 型別識別符號是指目標變數的型別。3 宣告引用時,必須同時對其進行初始化。4 引用宣告完畢後,相當於目標變數名有兩個名稱,即該目標原名稱和引用名,且不能再把該引用名作為其他變數...

C 中的引用

引用是c 引入的新語言特性,是c 常用的乙個重要內容之一,正確 靈活地使用引用,可以使程式簡潔 高效。我在工作中發現,許多人使用它僅僅是想當然,在某些微妙的場合,很容易出錯,究其原由,大多因為沒有搞清本源。故在本篇中我將對引用進行詳細討論,希望對大家更好地理解和使用引用起到拋磚引玉的作用。一 引用簡...