最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++引用的使用與const修飾符

 更新時(shí)間:2021年11月16日 11:25:31   作者:梁唐  
這篇文章介紹了C++引用使用與const修飾符,引用是給已經(jīng)定義的變量一個(gè)別名,可以簡(jiǎn)單理解成同一個(gè)變量的昵稱(chēng),既然是昵稱(chēng)或者是別名,顯然它和原本的變量名有著同樣的效力,所以我們對(duì)別名進(jìn)行修改,原本的變量值也一樣會(huì)發(fā)生變化,下面來(lái)看看詳細(xì)內(nèi)容,需要的朋友可以參考下

1、引用

引用是給已經(jīng)定義的變量一個(gè)別名,可以簡(jiǎn)單理解成同一個(gè)變量的昵稱(chēng)。既然是昵稱(chēng)或者是別名,顯然它和原本的變量名有著同樣的效力。所以我們對(duì)別名進(jìn)行修改,原本的變量值也一樣會(huì)發(fā)生變化。

我們通過(guò)符號(hào)&來(lái)表明引用,

比如下面這個(gè)例子,我們創(chuàng)建了a變量的一個(gè)引用b

int a = 3;
int &b = a;
b++;
cout << a << endl;

由于b是a的一個(gè)引用,本質(zhì)上來(lái)說(shuō)它們是同一個(gè)變量,只不過(guò)名稱(chēng)不同。所以我們對(duì)b修改,等價(jià)于對(duì)a進(jìn)行同樣的修改。所以輸出的結(jié)果是4。

也就是說(shuō)我們需要把引用變量和原變量當(dāng)成是同樣的變量,只不過(guò)名稱(chēng)不同,其中一個(gè)發(fā)生變化,另外一個(gè)一樣會(huì)生效。

看上去有些像是指針,因?yàn)閯?chuàng)建指針也能有類(lèi)似的效果:

int a = 3;
int *p = &a;

*p++;
cout << a << endl;

但是引用和指針還是有些區(qū)別,這個(gè)問(wèn)題在C++相關(guān)的面試當(dāng)中經(jīng)常會(huì)問(wèn)到,也是作為基本功的考察之一。

首先一個(gè)區(qū)別是,引用必須在聲明的時(shí)候就進(jìn)行初始化,沒(méi)辦法先聲明再賦值:

int *pt;  // 合法
int &b;  // 非法


從這個(gè)角度來(lái)說(shuō),引用更接近c(diǎn)onst指針,一旦與某個(gè)變量關(guān)聯(lián)就不能再指向其他變量:

int &b = a;
// 等價(jià)于
int *const pt = &a;


在這個(gè)例子當(dāng)中,b等價(jià)于*pt。

如果我們輸出引用和原變量的地址,會(huì)得到同樣的結(jié)果:

int a = 3;
int &b = a;

cout << &a << " " << &b << endl;

2、函數(shù)引用傳遞

其實(shí)到這里有一個(gè)問(wèn)題,既然引用只是別名,我們已經(jīng)有了原本的變量名可以用了,又何必多此一舉創(chuàng)建變量的引用呢?

所以引用不是為了順序執(zhí)行的邏輯創(chuàng)建的,一個(gè)最常見(jiàn)的使用場(chǎng)景就是函數(shù)參數(shù)傳遞的時(shí)候,可以設(shè)置函數(shù)接收的變量類(lèi)型為引用。

如:

void swap1(int& a, int& b) {
    int temp = b;
    b = a;
    a = temp;
}

void swap2(int a, int b) {
    int temp = b;
    b = a;
    a = temp;
}

我們創(chuàng)建了兩個(gè)swap函數(shù),其中一個(gè)傳遞的參數(shù)是引用,另外一個(gè)就是普通的值傳遞。如果大家去分別調(diào)用這兩個(gè)函數(shù)進(jìn)行嘗試,會(huì)發(fā)現(xiàn)swap2函數(shù)沒(méi)有生效。

因?yàn)橹祩鬟f的時(shí)候,會(huì)發(fā)生拷貝,也就是說(shuō)函數(shù)內(nèi)部接受的其實(shí)是變量的拷貝。我們對(duì)于拷貝無(wú)論如何修改也不會(huì)影響原值,而傳引用就不一樣了。前面說(shuō)過(guò),引用和原變量是等價(jià)的。我們對(duì)引用進(jìn)行修改等價(jià)于對(duì)原變量進(jìn)行修改。

這樣的話(huà),我們就可以實(shí)現(xiàn)在函數(shù)體內(nèi)部對(duì)外部傳入的參數(shù)進(jìn)行修改。在一些特殊的場(chǎng)景當(dāng)中,非常方便。比如一些復(fù)雜的樹(shù)形數(shù)據(jù)結(jié)構(gòu),通過(guò)使用引用可以大大降低代碼的編寫(xiě)難度。

除此之外,使用引用還有一個(gè)好處,既然我們傳遞的引用和原值是等價(jià)的。那么也就免去了拷貝變量的開(kāi)銷(xiāo),如果我們傳遞的是int,double這樣的變量還好,如果是一個(gè)包含大量元素的容器,如vector,set,map等,使用引用傳遞可以帶來(lái)明顯的效率提升,也會(huì)降低內(nèi)存開(kāi)銷(xiāo)。

3、引用與const

前文當(dāng)中說(shuō)過(guò),我們可以讓函數(shù)接收一個(gè)引用變量,從而免去變量拷貝的開(kāi)銷(xiāo),達(dá)到提升程序運(yùn)行效率的目的。

如果我們想要傳遞引用,但又不希望在函數(shù)內(nèi)部對(duì)引用的變量進(jìn)行修改,以免影響外部變量。我們可以使用常量引用,也就是加上const修飾符。

double sqrt(const double &x);


由于我們加上了const修飾符,當(dāng)我們?cè)诤瘮?shù)內(nèi)部對(duì)引用進(jìn)行修改的時(shí)候,會(huì)觸發(fā)編譯器的報(bào)錯(cuò)。一般來(lái)說(shuō),如果傳遞的只是基本類(lèi)型的變量,我們其實(shí)沒(méi)有必要這么操作,直接值傳遞即可。這種做法一般用在傳遞一些大型結(jié)構(gòu)體或者是大型容器的時(shí)候。

這里有一個(gè)小細(xì)節(jié)需要當(dāng)心,由于我們傳遞的是引用,需要保證傳遞的參數(shù)是一個(gè)實(shí)參,而不是表達(dá)式。如這樣的代碼編譯時(shí)會(huì)報(bào)錯(cuò):

double distance(double &x, double &y) {
    return sqrt(x * x + y * y);
}

int main() {
 double x = 3.0, y = 4.0;
 cout << distance(x + 3.0, y + 4.0);
}  

報(bào)錯(cuò)的原因在于,函數(shù)distance接收的是一個(gè)double類(lèi)型的引用,而我們傳遞的卻是x+3這樣的表達(dá)式。顯然表達(dá)式?jīng)]有對(duì)應(yīng)的引用。所以編譯器會(huì)報(bào)錯(cuò),告訴我們參數(shù)類(lèi)型不匹配:

但神奇的是,如果我們把函數(shù)簽名稍微改一下,加上const修飾符,會(huì)發(fā)現(xiàn)報(bào)錯(cuò)消失了:

double distance(const double &x, const double &y) {
    return sqrt(x * x + y * y);
}

這并不是編譯器的bug,而是編譯器針對(duì)const引用做了特殊處理。當(dāng)編譯器發(fā)現(xiàn)傳入的不是double類(lèi)型的變量的時(shí)候,它會(huì)創(chuàng)建一個(gè)臨時(shí)的無(wú)名變量,將這個(gè)臨時(shí)變量初始化成x+3.0 ,然后再傳入這個(gè)臨時(shí)變量的引用。C++只會(huì)對(duì)const引用參數(shù)執(zhí)行這個(gè)操作。

除了表達(dá)式之外,如果變量的類(lèi)型不匹配也一樣會(huì)創(chuàng)建臨時(shí)變量。這些臨時(shí)變量只會(huì)在函數(shù)調(diào)用期間存在,函數(shù)運(yùn)行結(jié)束之后,編譯器會(huì)將其刪除。

為什么會(huì)有這樣的設(shè)計(jì)呢?C++ Primer當(dāng)中提供了這樣一個(gè)例子:

void swapr(int &a, int &b) {
    int temp = b;
 b = a;
    a = temp;
}

long a = 3, b = 5;
swapr(a, b);

在早期C++沒(méi)有嚴(yán)格限制的情況下,這段代碼會(huì)發(fā)生什么呢?

由于類(lèi)型不匹配,所以編譯器會(huì)創(chuàng)建兩個(gè)臨時(shí)的int變量,但它們初始化成3和5,再傳入函數(shù)當(dāng)中。然后執(zhí)行函數(shù)當(dāng)中交換變量的邏輯,但問(wèn)題是,我們交換的是兩個(gè)臨時(shí)變量,原變量并不會(huì)生效。

所以后來(lái)版本的C++優(yōu)化了這個(gè)問(wèn)題,禁止了傳遞引用時(shí)創(chuàng)建臨時(shí)變量。而當(dāng)引用有const修飾時(shí)并不會(huì)對(duì)原值進(jìn)行修改,并不會(huì)影響邏輯和結(jié)果,所以豁免了這個(gè)禁令。

4、const修飾符的優(yōu)點(diǎn)

在函數(shù)簽名當(dāng)中,如果要接收引用,我們要盡可能使用const,我們來(lái)看下這樣做的好處:

  • 可以避免無(wú)意中修改數(shù)據(jù)
  • 可以處理const和非const參數(shù),否則,只能接受非const變量
  • 可以接受臨時(shí)變量

到此這篇關(guān)于C++引用的使用與const修飾符的文章就介紹到這了,更多相關(guān)C++引用與const內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

這篇文章轉(zhuǎn)自公眾號(hào):Coder梁(ID:Coder_LT)

相關(guān)文章

  • Qt實(shí)現(xiàn)打地鼠游戲的方法詳解

    Qt實(shí)現(xiàn)打地鼠游戲的方法詳解

    這篇文章主要和大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)一個(gè)簡(jiǎn)單的打地鼠游戲,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2022-10-10
  • 解析C++編程中的#include和條件編譯

    解析C++編程中的#include和條件編譯

    這篇文章主要介紹了解析C++編程中的#include和條件編譯,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • 深入理解大數(shù)與高精度數(shù)的處理問(wèn)題

    深入理解大數(shù)與高精度數(shù)的處理問(wèn)題

    本篇文章是對(duì)大數(shù)與高精度數(shù)的處理進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 解析C++引用

    解析C++引用

    引用是C++引入的新語(yǔ)言特性,是C++常用的一個(gè)重要內(nèi)容之一。在工作中發(fā)現(xiàn),許多人使用它僅僅是想當(dāng)然,在某些微妙的場(chǎng)合,很容易出錯(cuò),究其原由,大多因?yàn)闆](méi)有搞清本源。在本篇中將對(duì)引用進(jìn)行詳細(xì)討論,希望對(duì)大家更好地理解和使用引用起到拋磚引玉的作用
    2021-06-06
  • 劍指offer之判斷鏈表是否包含環(huán)

    劍指offer之判斷鏈表是否包含環(huán)

    今天小編就為大家分享一篇關(guān)于劍指offer之判斷鏈表是否包含環(huán),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-02-02
  • C/C++中extern函數(shù)使用詳解

    C/C++中extern函數(shù)使用詳解

    extern可以置于變量或者函數(shù)前,以標(biāo)示變量或者函數(shù)的定義在別的文件中,提示編譯器遇到此變量和函數(shù)時(shí)在其他模塊中尋找其定義。此外extern也可用來(lái)進(jìn)行鏈接指定
    2022-09-09
  • C++類(lèi)模板以及保存數(shù)據(jù)到文件方式

    C++類(lèi)模板以及保存數(shù)據(jù)到文件方式

    這篇文章主要介紹了C++類(lèi)模板以及保存數(shù)據(jù)到文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C/C++位操作實(shí)例總結(jié)

    C/C++位操作實(shí)例總結(jié)

    這篇文章主要介紹了C/C++位操作實(shí)例總結(jié),是C/C++程序設(shè)計(jì)中很重要的概念,需要的朋友可以參考下
    2014-08-08
  • C語(yǔ)言實(shí)現(xiàn)文件內(nèi)容的加密與解密

    C語(yǔ)言實(shí)現(xiàn)文件內(nèi)容的加密與解密

    文件內(nèi)容需要加密與解密功能的原因主要有兩個(gè)方面:保護(hù)數(shù)據(jù)安全和確保數(shù)據(jù)完整性,所以接下來(lái)小編就給大家介紹一下如何通過(guò)C語(yǔ)言實(shí)現(xiàn)文件內(nèi)容加密與解密,需要的朋友可以參考下
    2023-08-08
  • C/C++指針小結(jié)

    C/C++指針小結(jié)

    要搞清一個(gè)指針需要搞清指針的四方面的內(nèi)容:指針的類(lèi)型,指針?biāo)赶虻念?lèi)型,指針的值或者叫指針?biāo)赶虻膬?nèi)存區(qū),還有指針本身所占據(jù)的內(nèi)存區(qū)
    2013-09-09

最新評(píng)論

南郑县| 枣庄市| 溆浦县| 河西区| 朝阳区| 江达县| 昌江| 仁怀市| 鹤庆县| SHOW| 乡城县| 南漳县| 于田县| 剑阁县| 宁安市| 壤塘县| 铜陵市| 六枝特区| 阜城县| 建阳市| 新平| 岱山县| 景洪市| 淄博市| 西充县| 永春县| 汽车| 繁昌县| 德兴市| 四川省| 平湖市| 南开区| 巴塘县| 焉耆| 兖州市| 岳阳市| 舟曲县| 文安县| 子洲县| 东台市| 高台县|