標籤:style color 使用 strong 資料 問題 代碼 c++
引用
引用為對象起了另外一個名字,參考型別引用另外一個類型。通過將聲明符寫成&d的形式來定義參考型別,其中d是聲明的變數名:
int ival=1024;
int &refval=ival; //refval指向ival(是ival的另一個名字)
int &refval2; //報錯:引用必須初始化
一般在初始設定變數的時,初始值會被拷貝到建立的對象中。然而定義引用時,程式把引用和它的初始值綁定在一起,而不是將初始值拷貝給引用。一旦初始化完成,引用將和它的初始值對象一直綁定在一起。因為無法令引用重新綁定到另外一個對象,因此引用必須初始化。
引用即別名
引用並非對象,相反的,它只是為一個已經存在的對象所起的另外一個名字。
定義一個引用之後,對其進行的所有操作都是在與之綁定的對象上進行的:
refval=2;//把2賦給refval指向的對象,此處即是賦給了ival
int li=refval; //與li=ival執行結果一樣
為引用賦值,實際上是把值賦給了與引用綁定的對象。擷取引用的值,實際上是擷取了與引用綁定的對象的值。同理,以引用作為初始值,實際上是以與引用綁定的對象作為初始值:
//正確:refval3綁定到了那個與refval綁定的對象上,這裡就是綁定到了ival上
int &refval3=refval;
//利用與refval綁定的對象的值初始設定變數i
int i=refval; //正確: i被初始化為ival的值
因為引用本身不是一個對象,所以不能定義引用的引用。
使用引用要注意的兩點:
1 一般的,參考型別要和與之綁定的對象嚴格匹配。
2 引用只能綁定在對象上,而不能與字面值或某個運算式的計算結果綁定在一起。
指標
指標是指向另一種類型的複合類型。與引用類似,指標也實現了對其它對象的間接訪問。然而指標與引用相比又有很多不同點。其一,指標本身就是一個對象,允許對指標賦值和拷貝,而且在指標的聲明周期內它可以先後指向幾個不同的對象。其二,指標無須在定義時賦初值。和其他內建類型一樣,在塊範圍內定義的指標如果沒有被初始化,它將擁有一個不確定的值。
指標值
指標的值(即地址)應屬於下列4中狀態之一:
1 指向一個對象
2 指向緊鄰對象所佔空間的下一個位置
3 null 指標,意味著指標沒有指向任何對象
4 無效指標,也就是上述情況之外的其他值
利用指標訪問對象
如果指標指向了一個對象,則允許使用解引用符(操作法*)來訪問該對象。
解引用操作符僅適合用於那些確實指向了某個對象的有效指標。
null 指標
null 指標不指向任何對象,在試圖使用一個指標之前代碼可以首先檢查他是否為空白。以下列出幾個產生null 指標的方法:
int *p1=nullptr; //等價於int *p1=0;
int *p2=0; //直接將p2初始化為字面常量0
//需要首先#include cstdlib
int *p3=NULL; //等價於int *p3=0;
得到null 指標最直接的方法就是用字面值nullptr來初始化指標,這是C++11新標準剛剛引入的一種方法。nullptr是一種特殊類型的字面值,它可以被轉換成任意其他的指標類型。另一種方法就如對p2的定義一樣,也可以通過將指標初始化為字面值0來產生null 指標。
賦值和指標
指標和引用都能提供對其他對象的間接訪問,然而在具體實現細節上二者有很大不同,其中最重要的一點就是引用本身並非一個對象。一旦定義了引用,就無法令其再綁定到另外的對象,之後每次使用這個引用都是訪問它最初綁定的那個對象。
指標和它存放的地址之間就沒有這種限制了。和其他任何變數(只要不是引用)一樣,給指標賦值就是令他存放一個新的地址,從而指向一個新的對象。
有時候要想搞清楚一條指派陳述式到底是改變了指標的值還是改變了指標所指的對象的值不太容易,最好的辦法就是記住賦值永遠改變的是等號左側的對象。當寫出如下語句時,
pi=&ival; //pi的值被改變,現在pi指向了ival
意思是為pi賦一個新的值,也就是改變了那個存放在pi內的地址值。相反的,如果寫出如下語句:
*pi=0; //ival的值被改變,指標pi並沒有改變
則*pi(也就是指標pi指向的那個對象)發生改變。
指向指標的指標
一般來說,聲明符中修飾符的個數並沒有限制。當有多個修飾符連寫在一起時,按照其邏輯關係詳加解釋即可。以指標為例,指標是記憶體中的對象,像其他對象一樣也有自己的地址,因此允許把指標的地址再存放到另一個指標當中。
通常*的個數可以區分指標的層級。也就是說,**表示指向指標的指標,***表示指向指標的指標的指標,以此類推:
int ival=1024;
int *pi=&ival; //pi指向一個int型的數
int **ppi=π //ppi指向一個int型的指標
此處pi是指向int型數的指標,而ppi是指向int型指標的指標。
解引用int型指標會得到一個int型的數,同樣,解引用指向指標的指標會得到一個指標。此時為了訪問最原始的那個對象,需要對指標的指標做兩次解引用。
指向指標的引用
引用本身不是一個對象,因此不能定義指向引用的指標。但指標是對象,所以存在對指標的引用:
int i=42;
int *p; //p是一個int型的指標
int *&r=p; //r是一個對指標p的引用
r=&i; //r引用了一個指標,因此給r賦值&i 就是令p指向i
*r=0; //解引用r得到i,也就是p指向的對象,將i的值改為0
要理解r的類型到底是什麼,最簡單的辦法是從右向左閱讀r的定義。離變數名最近的符號(此例中是&r的符號&)對變數的類型有最直接的影響。因此r是一個引用。聲明符的其餘部分用以確定r引用的類型是什麼,此例中的符號*說明r引用的是一個指標。最後,聲明的基礎資料型別 (Elementary Data Type)部分指出r引用的是一個int指標。
面對一條比較複雜的指標或引用的聲明語句時,從右向左閱讀有助於弄清楚它的真實含義。