?
🥁作者: 華丞臧
📕????專欄:【C++】
博主Gitee
各位讀者老爺如果覺得博主寫的不錯,請諸位多多支持(點贊+收藏+關注)。如果有錯誤的地方,歡迎>在評論區(qū)指出。
推薦一款刷題網(wǎng)站 👉LeetCode
引用不是新定義一個變量,而是給已經(jīng)存在的變量取了一個別名,編譯器不會為引用變量開辟內(nèi)存空間,它們引用的變量共用同一塊空間。
//類型& 引用變量名 = 引用實體;
如下:
int a = 10;
int& ra = a; //定義引用類型,必須初始化
二、引用特性void TestRef()
{int a = 10;
// int& ra; // 該條語句編譯時會出錯
int& ra = a;
int& rra = a;
printf("%p %p %p\n", &a, &ra, &rra);
}
可以看到a,ra,rra三個變量地址一致,從這里可以看出引用其實就是變量實體的別名,與實體共用同一塊空間。
void TestConstRef()
{const int a = 10;
//int& ra = a; // 該語句編譯時會出錯,a為常量
const int& ra = a;
// int& b = 10; // 該語句編譯時會出錯,b為常量
const int& b = 10;
double d = 12.34;
//int& rd = d; // 該語句編譯時會出錯,類型不同;
const int& rd = d;
}
指針和引用賦值中,變量的權(quán)限可以縮小,但不可以放大。
類型轉(zhuǎn)換、整型提升、截斷這些的過程中都會產(chǎn)生一個臨時變量,語法規(guī)定臨時變量具有常性即不能修改。
四、使用場景 4.1 做參數(shù)在C語言當中,調(diào)用一個函數(shù)傳參分為兩種:一是傳值二是傳地址,在這兩種方式中只有傳地址才能通過函數(shù)中的形參改變實參;而現(xiàn)在C++當中使用引用做形參同樣能達到相同的效果。
//這是一個例子
void Swap(int& left, int& right)
{int temp = left;
left = right;
right = temp;
}
引用做參數(shù)的優(yōu)點:
關于函數(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)成重載看編譯器的識別或者名字修飾規(guī)則,但是不能這么寫程序會出錯,因為調(diào)用時存在二義性,編譯器識別不出。
傳值、傳引用效率比較:
#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();
// 分別計算兩個函數(shù)運行結(jié)束后的時間
cout<< "TestFunc1(A)-time:"<< end1 - begin1<< endl;
cout<< "TestFunc2(A&)-time:"<< end2 - begin2<< endl;
}
int main()
{TestRefAndValue();
return 0;
}
可以看到,數(shù)據(jù)量很大的時候引用做參數(shù)的效率更快。
傳值返回:
我們知道在函數(shù)調(diào)用時,編譯器會為函數(shù)在內(nèi)存中開辟一個函數(shù)棧幀;在函數(shù)調(diào)用返回時函數(shù)棧幀銷毀之前,返回值會先傳給一個臨時變量(小則存放在寄存器中,大則在主函數(shù)棧幀開辟的空間)返回。
引用返回:
引用是什么?引用是一個變量的別名,和引用的實體是共用一塊空間的;那么在函數(shù)棧幀銷毀時,函數(shù)返回的是實體變量在這個過程中就不會再產(chǎn)生一個臨時變量。
注意:函數(shù)棧幀銷毀,該函數(shù)中的局部變量也銷毀了,這時就不能再用引用返回了;如果這個變量是定義在函數(shù)棧幀上的,函數(shù)棧幀銷毀變量也跟著銷毀,出了函數(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<
打印一次:
打印兩次:
說明:
- 打印一次的時候,add函數(shù)棧幀銷毀時函數(shù)棧幀中存放c變量的空間并沒有被銷毀改變,此時去訪問這塊空間的值還是7。
- 當?shù)诙未蛴纱蔚臅r候,我們第二次非法訪問同樣一塊空間發(fā)現(xiàn)值已經(jīng)被改變,這是因為先取值再打印所以第一次還是7但是此時
cout
函數(shù)調(diào)用開辟了棧幀覆蓋了那片空間,從而導致了值的改變。- 上述的那一段程序是錯誤,屬于非法訪問,這說明:出了函數(shù)作用域變量就不存在了是不能使用傳引用返回的。
引用返回的優(yōu)點:
值和引用的作為返回值類型的性能比較:
#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();
// 計算兩個函數(shù)運算完成之后的時間
cout<< "TestFunc1 time:"<< end1 - begin1<< endl;
cout<< "TestFunc2 time:"<< end2 - begin2<< endl;
}
int main()
{TestReturnByRefOrValue();
return 0;
}
通過上述代碼的比較,發(fā)現(xiàn)傳值和傳引用在作為傳參以及返回值類型上效率相差很大。
在語法概念上引用就是一個別名,沒有獨立空間,和其引用實體共用同一塊空間;但在底層實現(xiàn)上實際是有空間的,因為引用是按照指針方式來實現(xiàn)的。
int main()
{int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}
上述引用和指針的匯編代碼如下:
通過對比不難發(fā)現(xiàn),引用的底層是使用指針實現(xiàn)的。
引用和指針的不同點
:
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
文章標題:[C++]C++入門--引用-創(chuàng)新互聯(lián)
分享網(wǎng)址:http://chinadenli.net/article16/dgpddg.html
成都網(wǎng)站建設公司_創(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)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)