C 11筆記(3) 引用 指標辨析

2021-07-22 04:08:11 字數 3080 閱讀 7569

引用為物件起了另外乙個名字,引用必須被初始化,引用本身不是乙個物件,所以不能定義引用的引用。

int ival = 1024;

int &refval = ival; //refval指向ival(是ival的別名)

int &refval2; //報錯:引用必須被初始化

refval = 2; //把2賦給了refval所指向的物件,即ival

int ii = refval; //與ii = ival執行結果一樣

引用的型別一般(有例外後面再說)都要和與之繫結的物件嚴格匹配。而且,引用只能繫結在物件上,不能與字面值或某個表示式的計算結果繫結在一起:

int &refval3 = 10;		//錯誤:引用型別的初始值必須是乙個物件

double dval = 3.14;

int &refval4 = dval; //錯誤:此處引用型別初始值必須是int型物件

一旦定義了引用,就無法令其再繫結到另外的物件,引用是「從一而終」的。

指標:與引用類似,指標也實現了對其他物件的間接訪問。兩者不同點:**一、**指標本身就是乙個物件,允許對指標進行賦值和拷貝,而且在指標的生命週期內它可以先後指向幾個不同物件。二、指標無需在定義時賦初值。和其他內建型別一樣,指標如果沒有被初始化,將擁有乙個不確定的值。

指標存放的是某個物件的位址,想獲取該位址用取位址符(&)。

int *p1, *p2;	//p1 p2都是指向int型物件的指標

int ival = 42;

int *p = &ival; //p存放ival的「位址」,或說p是指向變數ival的指標

int *p2 = p; //初始值是指向int物件的「指標」

int *p3 = nullptr; //空指標,等價於int *p3 = 0

int *p4 = null; //空指標,與上類似

cout<< *p 指向乙個物件。

指向緊鄰物件所佔空間下一位置。

空指標,意味著指標沒有指向任何物件。

無效指標,也就是上述情況外的其他值。

在宣告語句中(等號左邊),&和*用於組成復合型別;在表示式中(等號右邊),它們角色又變成運算子。

得到空指標最直接的辦法是用字面值nullptr初始化指標,這也是c++11標準引入的方法。過去還會用到乙個名為null的預處理變數給指標賦值,在標頭檔案cstdlib中定義,值就是0;現在最好用nullptr,同時盡量避免使用null。

有時候想搞清楚一條賦值語句到底是改變了指標的值還是改變了指標所指向的物件的值不太容易,最好的辦法就是記住賦值永遠改變的是等號左側物件。

pi = &ival; //pi值被改變,現在pi指向ival】

*pi = 0; //pi指向物件的值改變

對於兩個型別相同的合法指標相比較,用==或!=比較,返回布林型別。如果兩指標存放的位址值相同,則相等。兩個指標相等有三種情況:一、都為空;二、都指向同一物件;三、都指向了同一物件的下一位址。需要注意的是,如果乙個指標指向某物件,同時另乙個指標指向另外乙個物件的下一位址,此時也有可能出現兩指標相等的情況。

指向指標的指標

通過的個數可以區分指標的級別, **表示指向指標的指標

int ival = 1024;

int *p1 = &ival; //p1指向int物件

int **p2 = &p1; //p2指向乙個int指標

cout<< *p1 引用本身不是乙個物件,因此不能定義指向引用的指標。但指標是物件,存在對指標的引用:

int i = 42;

int *p; //p是乙個int指標

int *&r = p; //r是乙個對指標p的引用,注意與int &r = p區別(因為引用兩邊型別要一致)

r = &i; //r引用了乙個指標,因此給r賦值&i就是令p指向i

*r = 0; //解引用r得到i,也就是令p指向的物件,將i的值改為0

r = i; //給r賦值i就是令p指向以i為位址的物件

要理解r的型別到底是什麼,最簡單辦法是從右向左閱讀r定義(int *&r = p;)離變數名最近的符號(此例中是&r的符號&)對變數的型別有最直接的影響,因此r是乙個引用。宣告符的其餘部分用以確認r引用的型別是什麼,此例中的符號*說明r引用的是乙個指標。最後,宣告的基本型別部分指出r引用的是乙個int指標。

指標常量與常量指標

// 指標常量:const靠近*,指標不能變,即位址不能變,位址中儲存內容可以變

int a, b;

int * const pint = &a;

*pint = 10; // ok

pint = &b; // error!

// 常量指標:const靠近int,內容不能變,位址可以變

const int * pint = &a;

*pint = 10; // error!

pint = &b; // ok

int a = 10;

const int * const pint = &a;

快速記憶方法:**1、先把double *ptr寫好。三種方法中,double *ptr這三者順序是不變的。

2、const double *ptr; // const讀作常量,*讀作指標,按順序讀為常量指標。

3、double const *ptr; // const讀作常量,讀作指標,按順序為常量指標。

4、double * const ptr; // 讀作指標,const讀作常量,按順序為指標常量。

5、const靠近還是double,誰就是不變的。

c 11 筆記,c 筆記

find if的使用 bool isthe const string s1 vectora auto aaa find if a.begin a.end isthe aaa為第乙個符合要求的位址。aaa為取到的值。aaa為迭代器 lambda 表示式 auto f cout auto aaa fin...

深入應用C 11 筆記(四)

1.8 tupe元組 構造tuple 標頭檔案為 使用make tuple 構造乙個tuple char sendpack int nsendsize tuple char int tp make tuple sendpack,nsendsize 使用std tie構造 tuple char int...

深入理解C 11 筆記

include using namespace std classa a 對於含有堆記憶體的類,需要提供深拷貝的拷貝建構函式,避免預設的拷貝構造使用淺拷貝導致堆記憶體的重複刪除。a const a a m ptr new int a.m ptr 通過移動構造,a 作為函式引數,只使用淺拷貝避免臨時物...