本文將講述,C++中的引用& ?作者:迷茫的啟明星 ?歡迎關(guān)注:?點贊?收藏?留言 ?家人們,碼字不易,你的?點贊?收藏關(guān)注對我真的很重要,有問題可在評論區(qū)提出,感謝閱讀?。?! 持續(xù)更新中~ 引用& 引用的概念 引用并不是定義一個新的變量,而是給已經(jīng)存在的變量取一個別名,相當于外號,編譯器不會給它開辟內(nèi)存空間,它和它所引用的變量共用一塊空間。 比如說:宋江,江湖人稱“及時雨”,本質(zhì)都是宋江,不過是一個外號 引用的格式: 類型&引用變量名=引用實體; voidtest1 { inta=1; int&b=a;//定義引用的類型 cout<<> cout<<> } ``` 這里要注意的是,引用的類型必須和引用的實體是同種類型的。 引用的特性 引用在定義的時候必須初始化 也就是說它引用的是已經(jīng)存在的變量(空間) 一個變量可以有多個引用 也就是說給一個實體取多個“外號” 引用一旦引用一個實體,就不能再引用其他的實體了 也就是說不能再把這個“外號”給別人了 voidtest2{inta=1;intx=2;//int&b;//這個引用沒有初始化,編譯會報錯int&b=a;int&c=a;//多個引用(多個外號)//int&c=b//引用多個實體,不同實體有相同的外號,會報錯} 常引用 intmain{//權(quán)限放大不可以constinta=10;int&b=a;//權(quán)限不變可以constinta=10;constint&b=a;//權(quán)限的縮小可以intc=10;constint&d=c;return0;} 在引用時要注意,只能把自己有的給別人,自己都沒有權(quán)限怎么給呢? 引用的應用 在之前我們實現(xiàn)鏈表是使用指針來做參數(shù)的,現(xiàn)在我們就可以利用引用的性質(zhì)來實現(xiàn)它。 譬如:實現(xiàn)尾插 之前使用指針是這樣的(僅展現(xiàn)部分代碼,理解就好) voidSListPushBack(SLTNode**pphead,SLTDateTypex){SLTNode*newnode=BuyListNode(x);if(*pphead==NULL){*pphead=newnode;}else{//找到尾節(jié)點SLTNode*tail=*pphead;while(tail->next!=NULL){tail=tail->next;}tail->next=newnode;}}intmain{SLTNode*plist=NULL;SListPushBack(&plist,1);SListPushBack(&plist,2);SListPushBack(&plist,3);SListPushBack(&plist,4);return0;} 現(xiàn)在我們就可以這樣寫 voidSListPushBack(SLTNode*&pphead,SLTDateTypex){SLTNode*newnode=BuyListNode(x);if(pphead==NULL){pphead=newnode;}else{//找到尾節(jié)點SLTNode*tail=pphead;while(tail->next!=NULL){tail=tail->next;}tail->next=newnode;}}intmain{SLTNode*plist=NULL;SListPushBack(plist,1);SListPushBack(plist,2);SListPushBack(plist,3);SListPushBack(plist,4);return0;} pphead是plist的別名,改變pphead就是改變plist 做參數(shù) 使用引用的好處就在于,沒有指針那么復雜,還要使用二級指針,難以理解。再就是,定義函數(shù)時,要么就是傳值,要么就是傳址,現(xiàn)在就有了第三種情況傳引用。 voidswap(intr1,intr2)//傳值{inttmp=r1;r1=r2;r2=tmp;} voidswap(int*p1,int*p2)//傳地址 { inttmp=*p1; *p1=*p2; *p2=tmp; } voidswap(int&r1,int&r2)//傳引用 { inttmp=r1; r1=r2; r2=tmp; } 引用又有了另一個好處 它不需要開辟新的空間,是在原空間操作,這在數(shù)量級小的時候不起眼,可是在遞歸時就顯得尤為可貴了,雖說傳地址所需空間也少,但是在有時候,還是不如&方便。 #include 點擊加載圖片 這里還要注意一個點,如果使用引用傳參,函數(shù)中不改變參數(shù)的值,建議使用const& 做返回值 #include 點擊加載圖片 使用引用作返回值時,看上去是不是覺得效率提升了很多?但是這里有個大坑,雖說傳值返回會生成拷貝,但是它在結(jié)束時會產(chǎn)生一個臨時變量,臨時變量再給調(diào)用的地方,至少是安全的 這里提一下臨時變量存在哪里 如果比較?。?/8),一般是存在寄存器中 如果比較大,就會放在調(diào)用函數(shù)的棧幀中 接前面繼續(xù)講 引用做返回值,它引用的是什么呢? 是返回值,但是我們要知道,函數(shù)結(jié)束后,棧幀就銷毀了, 它這個時候就相當于非法訪問了,它訪問的就可能是隨機值(編譯器不同而不同), 那么我們應該怎么使用它呢? 需要記住這個規(guī)則:如果函數(shù)返回時,出了函數(shù)作用域,如果返回對象還在(還沒還給系統(tǒng)),則可以使用引用返回,如果已經(jīng)還給系統(tǒng)了,則必須使用傳值返回。 比如: int&count { staticintn;//靜態(tài) n++; retuernn; } 它就可以使用引用作返回值 引用和指針的區(qū)別 在語法概念上引用就是一個別名,沒有獨立空間,和其引用實體共用同一塊空間。 intmain{inta=10;int&ra=a;cout<<'&a='<<&a<<> 但是,在底層實現(xiàn)上實際是有空間的,因為引用是按照指針方式來實現(xiàn)的。 intmain{inta=10;int&ra=a;ra=20;int*pa=&a;*pa=20;return0;} 我們來看下引用和指針的匯編代碼對比 點擊加載圖片 引用和指針的不同點: 引用概念上定義一個變量的別名,指針存儲一個變量地址。 引用在定義時必須初始化,指針不是必須 引用在初始化時引用一個實體后,就不能再引用其他實體,而指針可以在任何時候指向任何一個同類型實體 沒有NULL引用,但有NULL指針 在sizeof中含義不同:引用結(jié)果為引用類型的大小,但指針始終是地址空間所占字節(jié)個數(shù)(32位平臺下占4個字節(jié)) 引用自加即引用的實體增加1,指針自加即指針向后偏移一個類型的大小 有多級指針,但是沒有多級引用 訪問實體方式不同,指針需要顯式解引用,引用編譯器自己處理 引用比指針使用起來相對更安全,因為不用像指針那樣要考慮野指針、空指針等問題。 總結(jié) 本文講述了,C++中的引用&,下一篇將講述C++初識下篇。 respect! 下篇見! |
|