在《從彙編看c++的引用和指標》一文中,雖然談到了引用,但是只是為了將兩者進行比較。這裡將對引用做進一步的分析。
int下面來看一下main函式的彙編碼:main()
int從上邊初始化指標和引用的彙編碼可以看出:兩者都是儲存的變數的位址,雖然初始化指標的時候明確使用了&運算子,但是初始化引用的時候,編譯器仍然儲存的是變數i的位址。main()
而在用指標和引用操作各自所指的變數的時候,對於引用,雖然沒有使用*運算子,通過儲存的位址獲取變數的對應值,但是,編譯器已經幫我們做了,可以把對引用和指標的操作的彙編碼進行比較,可以發現,二者是一樣的。
因此,對於指標,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++原始碼如下:
//下面是main函式對應的彙編碼:該函式傳遞引用也返回引用
int& f(int&i)
intmain()
7 : int可以看到,傳遞給函式f的引數時實際引數變數i的位址,這和上面講的ri=i一樣,只不過這裡使用實參初始化形參引用。main()
下面是函式f的彙編碼:
;可以看到,函式f返回的值也是乙個位址,即實參i的位址。2 : int& f(int& 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上面的c++**可以通過編譯。x ;void f(x&x) {}
intmain()
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 常用的乙個重要內容之一,正確 靈活地使用引用,可以使程式簡潔 高效。我在工作中發現,許多人使用它僅僅是想當然,在某些微妙的場合,很容易出錯,究其原由,大多因為沒有搞清本源。故在本篇中我將對引用進行詳細討論,希望對大家更好地理解和使用引用起到拋磚引玉的作用。一 引用簡...