91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++中引用與const修飾符怎么用

發布時間:2021-11-16 13:27:24 來源:億速云 閱讀:144 作者:小新 欄目:開發技術

這篇文章主要介紹了C++中引用與const修飾符怎么用,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

1、引用

引用是給已經定義的變量一個別名,可以簡單理解成同一個變量的昵稱。既然是昵稱或者是別名,顯然它和原本的變量名有著同樣的效力。所以我們對別名進行修改,原本的變量值也一樣會發生變化。

我們通過符號&來表明引用,

比如下面這個例子,我們創建了a變量的一個引用b

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

由于b是a的一個引用,本質上來說它們是同一個變量,只不過名稱不同。所以我們對b修改,等價于對a進行同樣的修改。所以輸出的結果是4。

也就是說我們需要把引用變量和原變量當成是同樣的變量,只不過名稱不同,其中一個發生變化,另外一個一樣會生效。

看上去有些像是指針,因為創建指針也能有類似的效果:

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

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

但是引用和指針還是有些區別,這個問題在C++相關的面試當中經常會問到,也是作為基本功的考察之一。

首先一個區別是,引用必須在聲明的時候就進行初始化,沒辦法先聲明再賦值:

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

從這個角度來說,引用更接近const指針,一旦與某個變量關聯就不能再指向其他變量:

int &b = a;
// 等價于
int *const pt = &a;

在這個例子當中,b等價于*pt。

如果我們輸出引用和原變量的地址,會得到同樣的結果:

int a = 3;
int &b = a;

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

2、函數引用傳遞

其實到這里有一個問題,既然引用只是別名,我們已經有了原本的變量名可以用了,又何必多此一舉創建變量的引用呢?

所以引用不是為了順序執行的邏輯創建的,一個最常見的使用場景就是函數參數傳遞的時候,可以設置函數接收的變量類型為引用。

如:

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;
}

我們創建了兩個swap函數,其中一個傳遞的參數是引用,另外一個就是普通的值傳遞。如果大家去分別調用這兩個函數進行嘗試,會發現swap2函數沒有生效。

因為值傳遞的時候,會發生拷貝,也就是說函數內部接受的其實是變量的拷貝。我們對于拷貝無論如何修改也不會影響原值,而傳引用就不一樣了。前面說過,引用和原變量是等價的。我們對引用進行修改等價于對原變量進行修改。

這樣的話,我們就可以實現在函數體內部對外部傳入的參數進行修改。在一些特殊的場景當中,非常方便。比如一些復雜的樹形數據結構,通過使用引用可以大大降低代碼的編寫難度。

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

3、引用與const

前文當中說過,我們可以讓函數接收一個引用變量,從而免去變量拷貝的開銷,達到提升程序運行效率的目的。

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

double sqrt(const double &x);

由于我們加上了const修飾符,當我們在函數內部對引用進行修改的時候,會觸發編譯器的報錯。一般來說,如果傳遞的只是基本類型的變量,我們其實沒有必要這么操作,直接值傳遞即可。這種做法一般用在傳遞一些大型結構體或者是大型容器的時候。

這里有一個小細節需要當心,由于我們傳遞的是引用,需要保證傳遞的參數是一個實參,而不是表達式。如這樣的代碼編譯時會報錯:

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);
}

報錯的原因在于,函數distance接收的是一個double類型的引用,而我們傳遞的卻是x+3這樣的表達式。顯然表達式沒有對應的引用。所以編譯器會報錯,告訴我們參數類型不匹配:

C++中引用與const修飾符怎么用

但神奇的是,如果我們把函數簽名稍微改一下,加上const修飾符,會發現報錯消失了:

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

這并不是編譯器的bug,而是編譯器針對const引用做了特殊處理。當編譯器發現傳入的不是double類型的變量的時候,它會創建一個臨時的無名變量,將這個臨時變量初始化成x+3.0 ,然后再傳入這個臨時變量的引用。C++只會對const引用參數執行這個操作。

除了表達式之外,如果變量的類型不匹配也一樣會創建臨時變量。這些臨時變量只會在函數調用期間存在,函數運行結束之后,編譯器會將其刪除。

為什么會有這樣的設計呢?C++ Primer當中提供了這樣一個例子:

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

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

在早期C++沒有嚴格限制的情況下,這段代碼會發生什么呢?

由于類型不匹配,所以編譯器會創建兩個臨時的int變量,但它們初始化成3和5,再傳入函數當中。然后執行函數當中交換變量的邏輯,但問題是,我們交換的是兩個臨時變量,原變量并不會生效。

所以后來版本的C++優化了這個問題,禁止了傳遞引用時創建臨時變量。而當引用有const修飾時并不會對原值進行修改,并不會影響邏輯和結果,所以豁免了這個禁令。

4、const修飾符的優點

在函數簽名當中,如果要接收引用,我們要盡可能使用const,我們來看下這樣做的好處:

  • 可以避免無意中修改數據

  • 可以處理const和非const參數,否則,只能接受非const變量

  • 可以接受臨時變量

感謝你能夠認真閱讀完這篇文章,希望小編分享的“C++中引用與const修飾符怎么用”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巫溪县| 海淀区| 白城市| 田林县| 三门峡市| 舟曲县| 松潘县| 长垣县| 镇赉县| 大化| 将乐县| 嘉黎县| 遂昌县| 金塔县| 娱乐| 玉环县| 胶南市| 梧州市| 屯昌县| 宝坻区| 辽阳市| 阜城县| 达拉特旗| 淮阳县| 上杭县| 无锡市| 花莲市| 治多县| 灵山县| 台南县| 平阴县| 寻甸| 永新县| 怀安县| 常宁市| 汾西县| 来凤县| 石屏县| 镇江市| 花垣县| 延安市|