一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C++引用的使用與const修飾符

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

2022-02-23 14:13梁唐 C/C++

這篇文章介紹了C++引用使用與const修飾符,引用是給已經(jīng)定義的變量一個別名,可以簡單理解成同一個變量的昵稱,既然是昵稱或者是別名,顯然它和原本的變量名有著同樣的效力,所以我們對別名進行修改,原本的變量值也一樣會發(fā)生變化

1、引用

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

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

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

?
1
2
3
4
int a = 3;
int &b = a;
b++;
cout << a << endl;

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

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

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

?
1
2
3
4
5
int a = 3;
int *p = &a;
 
*p++;
cout << a << endl;

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

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

?
1
2
int *pt;  // 合法
int &b;  // 非法

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

?
1
2
3
int &b = a;
// 等價于
int *const pt = &a;

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

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

?
1
2
3
4
int a = 3;
int &b = a;
 
cout << &a << " " << &b << endl;

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

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

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

如:

?
1
2
3
4
5
6
7
8
9
10
11
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)建了兩個swap函數(shù),其中一個傳遞的參數(shù)是引用,另外一個就是普通的值傳遞。如果大家去分別調(diào)用這兩個函數(shù)進行嘗試,會發(fā)現(xiàn)swap2函數(shù)沒有生效。

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

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

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

3、引用與const

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

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

?
1
double sqrt(const double &x);

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

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

?
1
2
3
4
5
6
7
8
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);

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

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

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

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

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

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

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

?
1
2
3
4
5
6
7
8
void swapr(int &a, int &b) {
    int temp = b;
 b = a;
    a = temp;
}
 
long a = 3, b = 5;
swapr(a, b);

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

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

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

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

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

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

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

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

延伸 · 閱讀

精彩推薦
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內(nèi)存中的數(shù)據(jù)都是暫時的,當程序結(jié)束時,它們都將丟失,為了永久性的保存大量的數(shù)據(jù),C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++C語言實現(xiàn)電腦關機程序

    C語言實現(xiàn)電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++深入理解goto語句的替代實現(xiàn)方式分析

    深入理解goto語句的替代實現(xiàn)方式分析

    本篇文章是對goto語句的替代實現(xiàn)方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網(wǎng)7342020-12-03
  • C/C++c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    c++ 單線程實現(xiàn)同時監(jiān)聽多個端口

    這篇文章主要介紹了c++ 單線程實現(xiàn)同時監(jiān)聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++C/C++經(jīng)典實例之模擬計算器示例代碼

    C/C++經(jīng)典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經(jīng)典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    詳解c語言中的 strcpy和strncpy字符串函數(shù)使用

    strcpy 和strcnpy函數(shù)是字符串復制函數(shù)。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數(shù)使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
主站蜘蛛池模板: 扒开老师两片湿漉的肉 | 911香蕉视频 | 色花堂国产精品首页第一页 | 亚洲欧美日韩成人一区在线 | 十六以下岁女子毛片免费 | 福利视频一区二区牛牛 | 三级伦理影院 | 51精品 | 国产成人www| 茄子视频懂你更多apl | 大胸被c出奶水嗷嗷叫 | 咪咪爱网友自拍 | 猥琐对着美女飞机喷到脸上 | 国产成人精品s8sp视频 | 人人爱天天做夜夜爽88 | 韩国靠逼 | 蜜桃视频在线观看官网 | 亚洲视频一| 亚洲精品在线免费看 | 亚洲欧美专区精品伊人久久 | 美女厕所尿尿擦逼 | 男男playh片在线观看 | 99热er| 亚洲天堂一区二区在线观看 | 色在线影院 | 免费深夜福利 | 国产在线欧美日韩精品一区二区 | 精品福利一区二区免费视频 | 天天爱天天做天天爽天天躁 | 美女天天色 | 国内久久精品 | 精品国产自在现线拍400部 | 国产欧美日韩精品一区二 | 国产成人久视频免费 | 星空无限传媒视频在线观看视频 | 精品免费| 国产另类视频一区二区三区 | 男女肉粗暴进来下面好紧 | 日韩精品久久不卡中文字幕 | 精品国产成人a区在线观看 精品高潮呻吟99AV无码视频 | 欧美一级高清免费a |