日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語言 正文

C++詳細(xì)分析講解引用的概念與使用_C 語言

作者:beyond.myself ? 更新時(shí)間: 2022-07-06 編程語言

1.引用的概念

引用不是新定義一個(gè)變量,而是給已存在變量取了一個(gè)別名,編譯器不會(huì)為引用變量開辟內(nèi)存空間,它和它引用的變量共用同一塊內(nèi)存空間。

2.引用的格式

類型 & 引用變量名 ( 對(duì)象名 ) = 引用實(shí)體;

舉例如下:

注意:引用類型必須和引用實(shí)體是同種類型的

3.引用的特性

(1). 引用在 定義時(shí)必須初始化

例如:int& d; 這樣就是沒有初始化是錯(cuò)的

(2). 一個(gè)變量可以有多個(gè)引用

?? ?int a = 10;
?? ?int& b = a;
?? ?int& c = b;
?? ?int* p = &b; ? ?//p是指針

(3). 引用一旦引用一個(gè)實(shí)體,再不能引用其他實(shí)體

4.取別名原則

對(duì)原引用變量,權(quán)限只能縮小,即 可讀可寫(普通類型) 可以改成 只讀(const);不能放大:,即 只讀 不能改成 可讀可寫的

例子1:權(quán)限的放大,不能把const給非const

例子2:權(quán)限的縮小 非const 既可以給非const,也可以給const:

例子3:權(quán)限縮小和放大規(guī)則:適用于引用和指針間

例子4: 權(quán)限不適用于普通賦值:

難點(diǎn):隱式類型轉(zhuǎn)換的引用

整形e能否做雙精度浮點(diǎn)型d的別名呢?

直接賦值是不行的,需要加上const才正確。即:const int& e = d; 正確

解釋:隱式類型轉(zhuǎn)換的普通賦值的情況,上面的例子:int f=d;從語法上看把8字節(jié)的d不能直接給4字節(jié)的f,因?yàn)楦↑c(diǎn)數(shù)和整形的存儲(chǔ)形式就不一樣,沒辦法直接截取,所以d需要先把整數(shù)部分給一個(gè)4字節(jié)的臨時(shí)變量,再把臨時(shí)變量給f

再看引用:int& e=d; 臨時(shí)變量具有常性,所以這里把臨時(shí)變量給引用e的時(shí)候,相當(dāng)于是把自帶const的臨時(shí)變量賦值給非const的e,把只讀的給可讀可寫的是放大了權(quán)限,所以錯(cuò)誤;必須改成const int& e=d;才正確!

5.引用的使用場(chǎng)景

做參數(shù)

(1)傳參:實(shí)參給形參傳值和傳地址都需要傳一份值/地址的拷貝,引用傳參可以減少拷貝,提高效率

void Swap(int& x, int& y)
{
	int tmp = x;
	x = y;
	y = tmp;
}
void Swap(double& x, double& y)
{
	double tmp = x;
	x = y;
	y = tmp;
}
int main()
{
	int a = 0, b = 1;
	swap(a, b);
	double c = 1.1, d = 2.2;
	swap(c, d);
	return 0;
}

(2)作輸出型參數(shù):

leetcode上的題往往有輸出型參數(shù),在c++中就可以用引用代替更加方便

做返回值

int&Count()的講解

傳值返回:會(huì)有一個(gè)拷貝

傳引用返回:沒有這個(gè)拷貝了,函數(shù)返回的直接就是返回變量的別名

int& Count()
{
	int n = 0;
	n++;
	return n;
}
int main()
{
	int ret = Count();
	return 0;
}

首先我們來看普通的傳值返回:普通的傳值返回需要把返回值n給一個(gè)函數(shù)類型int的臨時(shí)變量(函數(shù)類型就是返回值類型),再把臨時(shí)變量給ret。

為什么設(shè)計(jì)一個(gè)臨時(shí)變量,直接把n給ret不行嗎?

答:不行,因?yàn)楫?dāng)函數(shù)Count里執(zhí)行完各種代碼后,返回n,等出了Count函數(shù)的作用域后n就會(huì)銷毀,所以不能直接把n給ret,需要一個(gè)臨時(shí)變量。

如何證明返回時(shí)存在臨時(shí)變量呢?:如果你用int& ret 接收,寫成int& ret = Count(); 發(fā)現(xiàn)無法運(yùn)行,因?yàn)榕R時(shí)變量有常性,所以需要寫成const int& ret = Count();才能通過。

此時(shí)再看傳引用返回:

當(dāng)用引用接收引用返回時(shí):這里ret和n的地址一樣,也就意味著ret其實(shí)就是n的別名。但是因?yàn)閚出作用域不會(huì)立即被覆蓋,所以第一次通過ret可以打印是1,當(dāng)打印第二次時(shí),因?yàn)榍懊嬉呀?jīng)調(diào)用過一次打印函數(shù),已 "銷毀" 的Count函數(shù)棧幀在此時(shí)被打印函數(shù)覆蓋,再打印ret就會(huì)是隨機(jī)數(shù)了!

即:如果函數(shù)返回時(shí),出了函數(shù)作用域,如果返回對(duì)象還未還給系統(tǒng),則可以使用引用返回,如果已 經(jīng)還給系統(tǒng)了,則必須使用傳值返回。

用static修飾n后:用static靜態(tài)變量使n只初始化一次且改變其生命周期,把n放進(jìn)了靜態(tài)區(qū),這樣n就一直存在,就可以通過ret找到n了,再怎么打印ret都是1.

傳值傳引用效率比較

以值作為參數(shù)或者返回值類型,在傳參和返回期間,函數(shù)不會(huì)直接傳遞實(shí)參或者將變量本身直接返回,而是傳遞實(shí)參或者返回變量的一份臨時(shí)的拷貝,因此用值作為參數(shù)或者返回值類型,效率是非常低下的,尤其是 當(dāng)參數(shù)或者返回值類型非常大時(shí),效率就更低。 總結(jié):傳值和指針在作為傳參以及返回值類型上效率相差很大 。

6.引用和指針的不同點(diǎn)

1. 引用 在定義時(shí) 必須初始化 ,指針沒有要求

2. 引用 在初始化時(shí)引用一個(gè)實(shí)體后,就 不能再引用其他實(shí)體 ,而指針可以在任何時(shí)候指向任何一個(gè)同類型 實(shí)體

3. 沒有 NULL 引用 ,但有 NULL 指針

4. 在 sizeof 中含義不同 : 引用 結(jié)果為 引用類型的大小 ,但 指針 始終是 地址空間所占字節(jié)個(gè)數(shù) (32 位平臺(tái)下占 4 個(gè)字節(jié) )

5. 引用自加即引用的實(shí)體增加 1 ,指針自加即指針向后偏移一個(gè)類型的大小

6. 有多級(jí)指針,但是沒有多級(jí)引用

7. 訪問實(shí)體方式不同, 指針需要顯式解引用,引用編譯器自己處理

8. 引用比指針使用起來相對(duì)更安全

引用和指針在語法上是不一樣的,但是實(shí)際上從反匯編的代碼上我們能看到引用和指針的底層實(shí)現(xiàn)是一樣的!

這就好比保時(shí)捷的卡宴和大眾的途銳汽車,他們的三大件底盤,發(fā)動(dòng)機(jī),變速箱都是一樣的,但是他們的品牌不一樣,價(jià)格不同

原文鏈接:https://blog.csdn.net/zhang_si_hang/article/details/124689560

欄目分類
最近更新