舉例剖析C++中引用的本質(zhì)及引用作函數(shù)參數(shù)的使用
引用的意義與本質(zhì)
1)引用作為其它變量的別名而存在,因此在一些場合可以代替指針
2)引用相對于指針來說具有更好的可讀性和實用性

引用本質(zhì)思考:
思考、C++編譯器背后做了什么工作?
#include <iostream>
using namespace std;
int main()
{
int a = 10;
// 單獨定義的引用時,必須初始化;說明很像一個常量
int &b = a;
// b是a的別名
b = 11;
cout << "b--->" << a << endl;
printf("a:%d\n", a);
printf("b:%d\n", b);
printf("&a:%d\n", &a);
printf("&b:%d\n", &b);
system("pause");
return 0;
}
引用是一個有地址,引用是常量。
char *const p
引用的本質(zhì):
1)引用在C++中的內(nèi)部實現(xiàn)是一個常指針
Type& name <--> Type*const name
2)C++編譯器在編譯過程中使用常指針作為引用的內(nèi)部實現(xiàn),因此引用所占用的空間大小與指針相同。
3)從使用的角度,引用會讓人誤會其只是一個別名,沒有自己的存儲空間。這是C++為了實用性而做出的細節(jié)隱藏
間接賦值成立的三個條件:
1定義兩個變量(一個實參一個形參)
2建立關(guān)聯(lián)實參取地址傳給形參
3*p形參去間接的修改實參的值
引用在實現(xiàn)上,只不過是把:間接賦值成立的三個條件的后兩步和二為一。
當實參傳給形參引用的時候,只不過是c++編譯器幫我們程序員手工取了一個實參地址,傳給了形參引用(常量指針)。
引用做函數(shù)參數(shù)
普通引用在聲明時必須用其它的變量進行初始化,
引用作為函數(shù)參數(shù)聲明時不進行初始化
//復(fù)雜數(shù)據(jù)類型的引用
#include <iostream>
using namespace std;
struct Teacher
{
char name[64];
int age;
};
void printfT(Teacher *pT)
{
cout << pT->age << endl;
}
//pT是t1的別名 ,相當于修改了t1
void printfT2(Teacher &pT)
{
//cout<<pT.age<<endl;
pT.age = 33;
}
//pT和t1的是兩個不同的變量
void printfT3(Teacher pT)
{
cout << pT.age << endl;
pT.age = 45; //只會修改pT變量 ,不會修改t1變量
}
void main()
{
Teacher t1;
t1.age = 35;
printfT(&t1);
printfT2(t1); //pT是t1的別名
printf("t1.age:%d \n", t1.age); //33
printfT3(t1);// pT是形參 ,t1 copy一份數(shù)據(jù) 給pT //---> pT = t1
printf("t1.age:%d \n", t1.age); //35
cout << "hello..." << endl;
system("pause");
return;
}
引用的難點:函數(shù)返回值是引用(引用當左值)
當函數(shù)返回值為引用時,若返回棧變量,不能成為其它引用的初始值,不能作為左值使用;
若返回靜態(tài)變量或全局變量,可以成為其他引用的初始值,即可作為右值使用,也可作為左值使用。
C++鏈式編程中,經(jīng)常用到引用。
#include <iostream>
using namespace std;
//返回值是基礎(chǔ)類型,當引用
int getAA1()
{
int a;
a = 10;
return a;
}
//基礎(chǔ)類型a返回的時候,也會有一個副本
int& getAA2()
{
int a; // 如果返回棧上的引用,有可能會有問題
a = 10;
return a;
}
int* getAA3()
{
int a;
a = 10;
return &a;
}
int main()
{
int a1 = 0;
int a2 = 0;
a1 = getAA1();
a2 = getAA2(); // a是10
int &a3 = getAA2(); // 若返回棧變量,不能成為其他引用的初始值
cout << a1 << endl;
cout << a2 << endl;
cout << a3 << endl; // a3是亂碼,這里出現(xiàn)了問題
// 編譯器看到a3是個引用,自動進行對a3的地址進行取值
// 但是函數(shù)getAA2退出的時候已經(jīng)釋放了這個地址的內(nèi)存,所以這里是亂碼
return 0;
}
返回值是static變量,當引用
//static修飾變量的時候,變量是一個狀態(tài)變量
int j()
{
static int a = 10;
a++;
printf("a:%d \n", a);
return a;
}
int& j1()
{
static int a = 10;
a++;
printf("a:%d \n", a);
return a;
}
int *j2()
{
static int a = 10;
a++;
printf("a:%d \n", a);
return &a;
}
void main()
{
// j()的運算結(jié)果是一個數(shù)值,沒有內(nèi)存地址,不能當左值
//11 = 100;
//*(a>b?&a:&b) = 111;
//當被調(diào)用的函數(shù)當左值的時候,必須返回一個引用
j1() = 100; //編譯器幫我們打造了環(huán)境
j1();
*(j2()) = 200; //相當于手工的打造,做左值的條件
j2();
system("pause");
}
返回值是形參,當引用
int g1(int *p)
{
*p = 100;
return *p;
}
int& g2(int *p) //
{
*p = 100;
return *p;
}
//當使用引用語法的時候 ,不去關(guān)心編譯器引用是怎么做的
//當分析亂碼這種現(xiàn)象的時候,才去考慮c++編譯器是怎么做的。。。。
void main()
{
int a1 = 10;
a1 = g2(&a1);
int &a2 = g2(&a1); //用引用去接受函數(shù)的返回值,是不是亂碼,關(guān)鍵是看返回的內(nèi)存空間是不是被編譯器回收了。。。。
printf("a1:%d \n", a1);
printf("a2:%d \n", a2);
system("pause");
}
相關(guān)文章
基于OpenCV自定義色條實現(xiàn)灰度圖上色功能代碼
今天通過本文給大家分享基于OpenCV自定義色條實現(xiàn)灰度圖上色功能代碼,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-11-11
C++基于reactor的服務(wù)器百萬并發(fā)實現(xiàn)與講解
這篇文章主要介紹了C++基于reactor的服務(wù)器百萬并發(fā)實現(xiàn)與講解,本文通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07
簡單談?wù)勱P(guān)于C++中大隨機數(shù)的問題
這篇文章主要介紹了關(guān)于C++中大隨機數(shù)的問題,文中給出了詳細的示例代碼,相信對大家的學習或者工作具有一定的參考借鑒價值,有需要的朋友可以一起來學習學習。2017-01-01
C語言詳細分析結(jié)構(gòu)體的內(nèi)存對齊規(guī)則
C 數(shù)組允許定義可存儲相同類型數(shù)據(jù)項的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許你存儲不同類型的數(shù)據(jù)項,本篇讓我們來了解C 的結(jié)構(gòu)體內(nèi)存對齊2022-07-07

