C++ 複合類型之引用和指針
複合類型是指基於其他類型定義的類型。C++有很多複合類型,介紹其中的引用和指針
對變量的聲明的解釋:一條簡單的聲明語句是由一個數據類型和緊隨其後的變量名列表組成。其實更通用的描述是:一條聲明語句由一個基本數據類型和緊隨其後的一個聲明符列表組成。每個聲明符命名了一個變量並指定該變量是與基本數據類型有關的某種類型。
2.3.1 引用
引用即別名,引用是爲已存在的對象所起的另外一個名字。在初始化變量時,初始值會被拷貝到新建的對象中。而在定義引用時,程序會把引用和它的初始值綁定在一起,而不是拷貝。一旦初始化完成,引用將和初始化對象一直綁定在一起。因爲無法令引用重新綁定到另外一個對象,因此引用必須初始化。
- 引用即別名,對引用的操作實際是對引用所綁定對象的間接操作
- 給引用賦值必須是已存在的對象(變量),
- 引用必須初始化。
int val = 1024;
int &temp = val;
int &temp2 = temp;
cout<<--temp<<" "; //1023
cout<<val<<" "; //1023
cout<< --temp2<<" "; //1022
cout<<temp<<" "<<val<<" "; //1022 1022
int &refval = 10; //錯誤 引用類型的初始值必須是一個對象
double dval = 3.12;
int &ref = dval; //錯誤 此處引用的初始值必須是int型對象
int i,&r1 = i;
i = 5;
r1 =10;
cout<<i<<" "<<r1<<endl; //10 10
2.3.2 指針
指針是指向另外一種類型的複合類型,與引用類似,指針也實現對其他對象的間接訪問。而指針與引用有很多不同點,其一,指針本身就是一個對象,允許對指針賦值和拷貝,而且在指針的生命週期內可以先後指向多個不同對象。而引用初始化一旦完成,引用將和初始化對象一直綁定在一起。其二,指針不必須初始化,若沒有初始化指針,將指向隨機地址,即不確定的值。
int *P1,*P2;
double dp1,*dp2; //dp1是double類型變量,dp2是指向double類型的指針變量
double dval;
double *p = dval; //正確 指針p是指向double類型的指針
double *p2 = p; //正確 指針p2也是指向double類型的指針
int *pi = dval; //錯誤 試圖把double類型賦值給int型指針
int *pi = p; //同上
指針的值(即地址)應屬於下列4種狀態之一
1、指向一個對象
2、指向緊鄰對象所佔空間的下一個地址
3、空指針,沒有指向任何對象
4、無效指針,即除上述三種的其他類型
試圖以拷貝或其他方式訪問無效指針的值都將報錯,這一點和使用未經初始化的變量是一樣的(變量會默認初始化隨機值),編譯器並不負責檢查此類錯誤。因此訪問無效指針的後果無法預計。
儘管2 3種指針是有效的,但其使用也收到限制。顯然這些指針沒有指向任何具體對象,所以試圖訪問此類指針對象的後果也不確定,無法預計。
int* p1,p2; //p1是指向int的指針,p2是int類型的數據,這樣寫容易產生誤導
//規範寫法:
int *p1,*p2;
通過*個數可以區分指針的級別,**表示指向指針的指針, * * *表示指向指針的指針的指針,以此類推。
int ival = 44.45;
int *pi = &ival; //一級指針
int *pd = &val; //pd和pi指向同一個對象val
int **ppi = π //ppi指向pi指針 所指對象
如圖描述了他們的關係:
指針可以嵌套使用,解地址運算符*同樣也需要嵌套使用。如, *pi的值是int型數ival的值,而 *ppi的值是指針 *pi,**ppi纔是最初指向的int型數ival。
引用只是一個其綁定變量的別名,引用不是對象,因此不存在指向引用的指針。但指針是變量,可以定義對指針的引用
int i = 40;
int val = 100;
int *p = &i;
cout << p << endl; //輸出i的地址
int *&r = p; //定義指針的引用,r指向 指針變量p
r = &val; //r引用了指針p,因此現在p指向變量val
cout << *r << endl; //100
cout << p << endl; //輸出val的地址
cout << *p<<endl; //100
*r = 0; //解地址r = 0; val的值,*p和*r的值都爲0
Test:
下面定義合法嗎?原因?
int i=424; void *p =&i; long *lp = &i;
說明變量的類型和值:
int *ip,i, &r = i;
int i,*ip = 0;
int * ip,ip2;
- 其他指針操作
int val = 1024;
int *p1 = 0; //合法 空指針
int *p2 = &val; //合法 p2指向val
if(p1) //p1空指針 值0 false
...
if(p2) //p2存放val的地址 true
...