欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

[C++]C++入門--引用-創(chuàng)新互聯(lián)

?

成都創(chuàng)新互聯(lián)成都網(wǎng)站建設(shè)按需定制設(shè)計(jì),是成都網(wǎng)站維護(hù)公司,為汽車玻璃修復(fù)提供網(wǎng)站建設(shè)服務(wù),有成熟的網(wǎng)站定制合作流程,提供網(wǎng)站定制設(shè)計(jì)服務(wù):原型圖制作、網(wǎng)站創(chuàng)意設(shè)計(jì)、前端HTML5制作、后臺(tái)程序開發(fā)等。成都網(wǎng)站營(yíng)銷推廣熱線:13518219792

🥁作者: 華丞臧
📕????專欄:【C++】
博主Gitee
各位讀者老爺如果覺得博主寫的不錯(cuò),請(qǐng)諸位多多支持(點(diǎn)贊+收藏+關(guān)注)。如果有錯(cuò)誤的地方,歡迎>在評(píng)論區(qū)指出。
推薦一款刷題網(wǎng)站 👉LeetCode


文章目錄
  • 一、引用概念
  • 二、引用特性
  • 三、常引用
  • 四、使用場(chǎng)景
    • 4.1 做參數(shù)
    • 4.2 做返回值
  • 五、引用和指針的區(qū)別


一、引用概念

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

//類型& 引用變量名 = 引用實(shí)體;
如下:
int a = 10;
int& ra = a; //定義引用類型,必須初始化
二、引用特性
  1. 引用在定義時(shí)必須初始化;
  2. 一個(gè)變量可以有多個(gè)引用;
  3. 引用一旦引用一個(gè)實(shí)體,再不能引用其他實(shí)體。
void TestRef()
{int a = 10;
   // int& ra;   // 該條語(yǔ)句編譯時(shí)會(huì)出錯(cuò)
   int& ra = a;
   int& rra = a;
   printf("%p %p %p\n", &a, &ra, &rra);  
}

在這里插入圖片描述
可以看到a,ra,rra三個(gè)變量地址一致,從這里可以看出引用其實(shí)就是變量實(shí)體的別名,與實(shí)體共用同一塊空間。

三、常引用
void TestConstRef()
{const int a = 10;
    //int& ra = a;   // 該語(yǔ)句編譯時(shí)會(huì)出錯(cuò),a為常量
    const int& ra = a;
    // int& b = 10; // 該語(yǔ)句編譯時(shí)會(huì)出錯(cuò),b為常量
    const int& b = 10;
    double d = 12.34;
    //int& rd = d; // 該語(yǔ)句編譯時(shí)會(huì)出錯(cuò),類型不同;
    const int& rd = d; 
}

指針和引用賦值中,變量的權(quán)限可以縮小,但不可以放大。

類型轉(zhuǎn)換、整型提升、截?cái)噙@些的過程中都會(huì)產(chǎn)生一個(gè)臨時(shí)變量,語(yǔ)法規(guī)定臨時(shí)變量具有常性即不能修改。

四、使用場(chǎng)景 4.1 做參數(shù)

在C語(yǔ)言當(dāng)中,調(diào)用一個(gè)函數(shù)傳參分為兩種:一是傳值二是傳地址,在這兩種方式中只有傳地址才能通過函數(shù)中的形參改變實(shí)參;而現(xiàn)在C++當(dāng)中使用引用做形參同樣能達(dá)到相同的效果。

//這是一個(gè)例子
void Swap(int& left, int& right)
{int temp = left;
   left = right;
   right = temp;
}

引用做參數(shù)的優(yōu)點(diǎn):

  1. 減少拷貝,提高效率;
  2. 輸出型參數(shù),函數(shù)中修改形參實(shí)參也修改了。

關(guān)于函數(shù)重載:

int Add(int& a, int& b)
{int c = a + b;
    return c;
}

int Add(int a, int b)
{int c = a + b;
    return c;
}

上述函數(shù)構(gòu)不構(gòu)成重載看編譯器的識(shí)別或者名字修飾規(guī)則,但是不能這么寫程序會(huì)出錯(cuò),因?yàn)檎{(diào)用時(shí)存在二義性,編譯器識(shí)別不出。
傳值、傳引用效率比較:

#include#includeusing namespace std;

struct A 
{int a[10000]; 
};
void TestFunc1(A a) 
{}
void TestFunc2(A& a) 
{}
void TestRefAndValue()
{A a;
	// 以值作為函數(shù)參數(shù)
	size_t begin1 = clock();
	for (size_t i = 0; i< 100000; ++i)
		TestFunc1(a);
	size_t end1 = clock();
	// 以引用作為函數(shù)參數(shù)
	size_t begin2 = clock();
	for (size_t i = 0; i< 100000; ++i)
		TestFunc2(a);
	size_t end2 = clock();
	// 分別計(jì)算兩個(gè)函數(shù)運(yùn)行結(jié)束后的時(shí)間
	cout<< "TestFunc1(A)-time:"<< end1 - begin1<< endl;
	cout<< "TestFunc2(A&)-time:"<< end2 - begin2<< endl;
}

int main()
{TestRefAndValue();
	return 0;
}

在這里插入圖片描述
可以看到,數(shù)據(jù)量很大的時(shí)候引用做參數(shù)的效率更快。

4.2 做返回值

傳值返回:

我們知道在函數(shù)調(diào)用時(shí),編譯器會(huì)為函數(shù)在內(nèi)存中開辟一個(gè)函數(shù)棧幀;在函數(shù)調(diào)用返回時(shí)函數(shù)棧幀銷毀之前,返回值會(huì)先傳給一個(gè)臨時(shí)變量(小則存放在寄存器中,大則在主函數(shù)棧幀開辟的空間)返回。

引用返回:

引用是什么?引用是一個(gè)變量的別名,和引用的實(shí)體是共用一塊空間的;那么在函數(shù)棧幀銷毀時(shí),函數(shù)返回的是實(shí)體變量在這個(gè)過程中就不會(huì)再產(chǎn)生一個(gè)臨時(shí)變量。
注意:函數(shù)棧幀銷毀,該函數(shù)中的局部變量也銷毀了,這時(shí)就不能再用引用返回了;如果這個(gè)變量是定義在函數(shù)棧幀上的,函數(shù)棧幀銷毀變量也跟著銷毀,出了函數(shù)作用域返回變量不存在了,不能使用引用返回,因?yàn)榇藭r(shí)引用返回的結(jié)果是未定義的;出了函數(shù)作用域,返回變量存在,才能使用引用返回。

int& Count()
{static int n = 0;
   n++;
   // ...
   return n;
}

//下面代碼輸出什么結(jié)果?為什么?
int& Add(int a, int b)
{int c = a + b;
    return c;
}
int main()
{int& ret = Add(1, 2);
    Add(3, 4);
    cout<< "Add(1, 2) is :"<< ret<

打印一次:
在這里插入圖片描述
打印兩次:
在這里插入圖片描述
說明:

  • 打印一次的時(shí)候,add函數(shù)棧幀銷毀時(shí)函數(shù)棧幀中存放c變量的空間并沒有被銷毀改變,此時(shí)去訪問這塊空間的值還是7。
  • 當(dāng)?shù)诙未蛴纱蔚臅r(shí)候,我們第二次非法訪問同樣一塊空間發(fā)現(xiàn)值已經(jīng)被改變,這是因?yàn)橄热≈翟俅蛴∷缘谝淮芜€是7但是此時(shí)cout函數(shù)調(diào)用開辟了棧幀覆蓋了那片空間,從而導(dǎo)致了值的改變。
  • 上述的那一段程序是錯(cuò)誤,屬于非法訪問,這說明:出了函數(shù)作用域變量就不存在了是不能使用傳引用返回的。

引用返回的優(yōu)點(diǎn):

  1. 減少拷貝,提高效率;
  2. 修改返回值。

值和引用的作為返回值類型的性能比較:

#include#includeusing namespace std;

struct A 
{int a[10000]; 
};
A a;
// 傳值返回
A TestFunc1() 
{return a; 
}
// 引用返回
A& TestFunc2() 
{return a; 
}

void TestReturnByRefOrValue()
{// 以值作為函數(shù)的返回值類型
	size_t begin1 = clock();
	for (size_t i = 0; i< 100000; ++i)
		TestFunc1();
	size_t end1 = clock();
	// 以引用作為函數(shù)的返回值類型
	size_t begin2 = clock();
	for (size_t i = 0; i< 100000; ++i)
		TestFunc2();
	size_t end2 = clock();
	// 計(jì)算兩個(gè)函數(shù)運(yùn)算完成之后的時(shí)間
	cout<< "TestFunc1 time:"<< end1 - begin1<< endl;
	cout<< "TestFunc2 time:"<< end2 - begin2<< endl;
}

int main()
{TestReturnByRefOrValue();
	return 0;
}

在這里插入圖片描述
通過上述代碼的比較,發(fā)現(xiàn)傳值和傳引用在作為傳參以及返回值類型上效率相差很大。

五、引用和指針的區(qū)別

在語(yǔ)法概念上引用就是一個(gè)別名,沒有獨(dú)立空間,和其引用實(shí)體共用同一塊空間;但在底層實(shí)現(xiàn)上實(shí)際是有空間的,因?yàn)橐檬前凑罩羔樂绞絹韺?shí)現(xiàn)的。

int main()
{int a = 10;
	int& ra = a;
	ra = 20;
	int* pa = &a;
	*pa = 20;
	return 0;
}

上述引用和指針的匯編代碼如下:
在這里插入圖片描述
通過對(duì)比不難發(fā)現(xiàn),引用的底層是使用指針實(shí)現(xiàn)的。

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

  1. 引用概念上定義一個(gè)變量的別名,指針存儲(chǔ)一個(gè)變量地址;
  2. 引用在定義時(shí)必須初始化,指針沒有要求;
  3. 引用在初始化時(shí)引用一個(gè)實(shí)體后,就不能再引用其他實(shí)體,而指針可以在任何時(shí)候指向任何一個(gè)同類型實(shí)體;
  4. 沒有NULL引用,但有NULL指針;
  5. 在sizeof中含義不同:引用結(jié)果為引用類型的大小,但指針始終是地址空間所占字節(jié)個(gè)數(shù)(32位平臺(tái)下占4個(gè)字節(jié));
  6. 引用自加即引用的實(shí)體增加1,指針自加即指針向后偏移一個(gè)類型的大小;
  7. 有多級(jí)指針,但是沒有多級(jí)引用;
  8. 訪問實(shí)體方式不同,指針需要顯式解引用,引用編譯器自己處理;
  9. 引用比指針使用起來相對(duì)更安全。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

文章標(biāo)題:[C++]C++入門--引用-創(chuàng)新互聯(lián)
分享網(wǎng)址:http://chinadenli.net/article16/dgpddg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)網(wǎng)站策劃靜態(tài)網(wǎng)站商城網(wǎng)站Google軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)