【C++】引用變量詳解

📢博客主頁:https://blog.csdn.net/2301_779549673
📢歡迎點贊 👍 收藏 ?留言 📝 如有錯誤敬請指正!
📢本文由 JohnKi 原創,首發于 CSDN🙉
📢未來很長,值得我們全力奔赴更美好的生活?

在這里插入圖片描述

在這里插入圖片描述

文章目錄

  • 📢前言
  • 🏳??🌈引用的概念和定義
    • ??引用的特性
    • 🧡引用的屬性和特別之處
  • 👥總結


📢前言

C++新增了一種復合類型–引用變量。引用是已定義的變量的別名(另一個名稱)。例如,如果將twain作為clement變量的引用,則可以交替使用twain 和clement來表示該變量。那么,這種別名有何作用呢?是否能幫助那些不知道如何選擇變量名的人呢?有可能,但引用變量的主要用途是用作函數的形參。通過將引用變量用作參數,函數將使用原始數據,而不是其副本。這樣除指針之外,引用也為函數處理大型結構提供了一種非常方便的途徑,同時對于設計類來說,引用也是必不可少的。然面,介紹如何將引用用于函數之前,先介紹一下定義和使用引用的基本知識。請記住,下述討論旨在說明引用是如何工作的,而不是其典型用法。

先說說左右值的概念

C++中所有值必然屬于左值或者右值,
在C++11中可以取地址的、有名字的就是左值
反之,不能取地址的、沒有名字的就是右值


🏳??🌈引用的概念和定義

引用不是新定義一個變量,而是給已存在變量取了一個別名,編譯器不會為引用變量開辟內存空間它和它引用的變量共用同一塊內存空間。比如:水壺傳中李逵,宋江叫"鐵牛",江湖上人稱"黑旋風";林沖,外號豹子頭;

類型& 引用別名=引用對象;

#include<iostream>
using namespace std;
int main()
{
int a = 0;
// 引?:b和c是a的別名
int& b = a;
int& c = a;
// 也可以給別名b取別名,d相當于還是a的別名
int& d = b;
++d;
// 這?取地址我們看到是?樣的
cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
cout << &d << endl << endl;cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
return 0;
}

在這里插入圖片描述

(1)可見,引用的定義方式類似于指針,只是用&取代了*。你可以這樣理解:忽略&這個符號本身的意義,這里提出了一個新的概念"引用”,指針表示某個變量的地址,引用表示這個變量本身。

(2)引用必須在定義的同時初始化,并且以后也要從一而終,不能再引用其它數據,有點類似于 const 變量,

??引用的特性

  • 引用在定義時必須初始化
  • 一個變量可以有多個引用
  • 引用一旦引用一個實體,再不能引用其他實體
#include<iostream>
using namespace std;
int main()
{int a = 10;// 編譯報錯:“ra”: 必須初始化引?//int& ra;int& b = a;int c = 20;// 這?并?讓b引?c,因為C++引?不能改變指向,// 這?是?個賦值b = c;cout << &a << endl;cout << &b << endl;cout << &c << endl;return 0;
}

引用更接近 const 指針,必須再創建時進行初始化,一旦與某個變量聯系起來,就將一直效忠于它,也就是說

int& rondents = rats;

實際上就是下述代碼的偽裝

int* const pr = &rats;

其中,引用rondents扮演的角色與表達式*pr相同

🧡引用的屬性和特別之處

我們有意編寫一個奇怪的立方計算代碼

double cube(double a);
double refcube(double& ra);
int main() {using namespace std;double x = 3.0;cout << cube(x);cout << " = cube of " << x << endl;cout << refcube(x);cout << " = refcube of " << x << endl; return 0;
}
double cube(double a)
{a *= a * a;return a;
}double refcube(double& ra)
{ra *= ra * ra;return ra;
}

下面是該程序的輸出結果

在這里插入圖片描述

refcube()函數修改了 main( )中的x值,而 cube()沒有,這提醒我們為何通常按值傳遞。變量a位于cube()中,它被初始化為x的值,但修改a并不會影響x。但由于refcube()使用了引用參數,因此修改ra實際上就是修改x。如果程序員的意圖是讓函數使用傳遞給它的信息,而不對這些信息進行修改,同時又想使用引用,則應使用常量引用。

例如,在這個例子中,應在函數原型和函數頭中使用const:
double refcube(const double &ra);

如果這樣做,當編譯器發現代碼修改了ra的值時,將生成錯誤消息。

順便說一句,如果要編寫類似于上述示例的函數(即使用基本數值類型),應采用按值傳遞的方式,而不要采用按引用傳遞的方式。當數據比較大(如結構和類)時,引用參數將很有用。

按值傳遞的函數,可使用多種類型的實參,例如,下面的調用都是合法的

double z = cube(x + 2.0); 
z = cube(8.0); 
int k = 10; 
z = cube(k); 
double yo[3] = (2.2, 3.3, 4.4, 5.5);
z = cube(yo[2])

如果將與上面類似的參數傳遞給接受引用參數的函數,將會發現,傳遞引用的限制更嚴格。畢竟,如果ra是一個變量的別名,則實參應是該變量

例如,下面的代碼不合理,因為表達式x+3.0并不是變量
double z=refcube(x+3,0):

所以如果實參與引用參數不匹配,C++將生成臨時變量。當前,僅當參數為const引用時,C++才允許樣做,但以前不是這樣。下面來看看何種情況下,C++將生成臨時變量,以及為何對const 引用的限制合理的。

首先,什么時候將創建臨時變量呢?如果引用參數是const,則編譯器將在下面兩種情況下生成變量:

  • 實參的類型正確,但不是左值;
  • 實參的類型不正確,但可以轉換為正確的類型。

在C語言中,左值最初指的是可出現在賦值語句左邊的實體,但這是引入關鍵字const之前觸況。現在,常規變量和const變量都可視為左值,因為可通過地址訪問它們。但常規變量屬于可修改的值,而const 變量屬于不可修改的左值。

回到前面的示例。假設重新定義了refcube(),使其接受一個常量引用參數:

double refcube(const double& ra);
int main() {using namespace std;double x = 3.0;double side = 3.0; double* pd = &side; double& rd = side; long edge = 5L; double lens[4] = { 2.0, 5.0, 10.0, 12.0 };double c1 = refcube(side); double c2 = refcube(lens[2]);double c3 = refcube(rd);double c4 = refcube(*pd);double c5 = refcube(edge); double c6 = refcube(7.0); double c7 = refcube(side + 10.0);return 0;
}
double refcube(const double &ra)
{return ra * ra * ra;
}

下面是該程序的輸出結果

在這里插入圖片描述


👥總結


本篇博文對 引用變量 做了一個較為詳細的介紹,不知道對你有沒有幫助呢

覺得博主寫得還不錯的三連支持下吧!會繼續努力的~

請添加圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/44298.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/44298.shtml
英文地址,請注明出處:http://en.pswp.cn/web/44298.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

文檔去重(TF-IDF,MinHash, SimHash)

2個doc有些相似有些不相似&#xff0c;如何衡量這個相似度&#xff1b; 直接用Jaccard距離&#xff0c;計算量太大 TF-IDF: TF*IDF TF&#xff1a;該詞在該文檔中的出現次數&#xff0c; IDF&#xff1a;該詞在所有文檔中的多少個文檔出現是DF&#xff0c;lg(N/(1DF)) MinHash …

數據分析_計劃

我做大數據的有6年了&#xff0c;以前都是用sql&#xff0c;或者spark&#xff0c;java&#xff0c;scala&#xff0c;python去做。現在這些平臺搭建、維護、大多數都是搭建一次就完了&#xff0c;而且維護大多是大廠直接用云平臺去做。ETL也是就做一次就夠了&#xff0c;我們公…

基于JAVA+SpringBoot+Vue+Uni-app前后端分離的校園好物小紅書分享平臺小程序

?全網粉絲20W,csdn特邀作者、博客專家、CSDN新星計劃導師、java領域優質創作者,博客之星、掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域和畢業項目實戰? &#x1f345;文末獲取項目下載方式&#x1f345; 一、項目背景介紹&#xff1a; 在快速數字化的時代背…

同三維T80004EA編解碼器視頻使用操作說明書:高清HDMI編解碼器,高清SDI編解碼器,4K超清HDMI編解碼器,雙路4K超高清編解碼器

同三維T80004EA編解碼器視頻使用操作說明書&#xff1a;高清HDMI編解碼器&#xff0c;高清SDI編解碼器&#xff0c;4K超清HDMI編解碼器&#xff0c;雙路4K超高清編解碼器 同三維T80004EA編解碼器視頻使用操作說明書&#xff1a;高清HDMI編解碼器&#xff0c;高清SDI編解碼器&am…

UniVue@v1.3.0版本發布

GitHub倉庫 發布版本倉庫&#xff1a;https://github.com/Avalon712/UniVue 開發版本倉庫&#xff1a;https://github.com/Avalon712/UniVue-Develop UniVue拓展框架UniVue源生成器倉庫&#xff1a;https://github.com/Avalon712/UniVue-SourceGenerator v1.3.0版本新增功能…

DangerWind-RPC-framework---四、SPI

SPI 即 Service Provider Interface &#xff0c;可以理解為專門提供給服務提供者或者擴展框架功能的開發者去使用的一個接口。SPI 將服務接口和具體的服務實現分離開來&#xff0c;將服務調用方和服務實現者解耦&#xff0c;能夠提升程序的擴展性、可維護性。修改或者替換服務…

etcd 實現分布式鎖

10 基于 Etcd 的分布式鎖實現原理及方案

如何通過兔子和窩窩的故事理解“在機器人學習和研究中的獲得成本與維護成本”(節選)

獲得成本 掌握一門課程&#xff0c;以最為簡單的學校成績過60為例&#xff0c;需要按要求提交材料&#xff0c;包括作業、報告、實驗和考試等&#xff0c;依據學分和考核要求的不同&#xff0c;需要對于花費時間和經歷進行完成。 維護成本 考完了&#xff0c;如果被動學習那…

docker拉取鏡像-配置阿里云鏡像加速

1、配置阿里云鏡像&#xff08;用于拉取鏡像加速&#xff09; sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo syst…

Docker 使用基礎(4)—存儲卷

&#x1f3ac;慕斯主頁&#xff1a;修仙—別有洞天 ??今日夜電波&#xff1a;秒針を噛む—ずっと真夜中でいいのに。 0:34━━━━━━?&#x1f49f;──────── 4:20 &#x1f504; ?? ? …

JVM堆內存的結構,YGC,FGC的原理

JVM堆內存結構&#xff1a; JVM堆內存可分為三個區域&#xff1a;新生代&#xff08;Young Generation&#xff09;、年老代&#xff08;Tenured Generation&#xff0c;也叫做Old Generation&#xff09;和永久代&#xff08;Permanent Generation&#xff0c;也叫做Method Ar…

linux 設置nginx開機自啟

1、關閉當前nginx運行 systemctl stop nginx 2、添加以下內容到nginx.service文件&#xff0c;注意nginx.pid文件的路徑&#xff0c;要替換哦&#xff01; vim /etc/systemd/system/nginx.service [Unit] DescriptionThe NGINX HTTP and reverse proxy server Afternetwork…

ArcGIS如何快速對齊兩個圖層

1、問題 如何讓兩個圖層快速對齊 2、使用捕捉工具 移動點或折點&#xff0c;使其與其他要素的折點、邊或端點精確重合。 可指定捕捉規則來控制是將輸入折點捕捉到指定距離范圍內的最近折點、邊還是端點。

MySQL數字相關數據處理函數

目錄 1. 隨機數生成 rand ( ) 2. 四舍五入 round&#xff08;&#xff09; 3. 舍去 truncate ( ) 4. 向上/下取整 5. 空處理 ifnull&#xff08; x , y &#xff09; 1. 隨機數生成 rand ( ) rand ( ) 生成 0 到 1 的隨機數&#xff1b; rand ( x ) 生成 0 到 1 的隨機數…

簡單理解Lua 協程(coroutine)

也許更好的閱讀體驗 協程簡單理解為可以暫停的線程&#xff0c;但是同一時刻只有一個協程可以處于運行狀態。 文章目錄 coroutine.create()coroutine.resume()coroutine.wrap()coroutine.yield()coroutine.resume()參數傳遞resume和yield之間互換數據 coroutine.create() lua…

403 禁止錯誤: 它是什么?如何修復?

您應該對403錯誤代碼很熟悉&#xff01;這種錯誤會導致流量損失&#xff0c;甚至錯失一些商業機會&#xff01; 什么&#xff1f;您在自己的網站上遇到了403錯誤&#xff1f;請立即修復它&#xff01;但是什么原因導致這種錯誤&#xff1f;該如何解決&#xff1f;這兩個問題都…

66種智能優化算法和改進優化算法優化BP神經網絡【開源代碼!】【文末福利IT學習資料】

前言 熟話說得好&#xff0c;創新點不夠&#xff0c;智能優化算法來湊&#xff0c;不要覺得羞恥&#xff0c;因為不僅我們這么干&#xff0c;很多外國人也這么干&#xff01;因為創新點實在太難想了&#xff0c;和優化算法結合下是最簡單的創新點了&#xff01; 之前給大家分享…

485通訊抗干擾,超時重發,不斷重連的程序架構

485通訊抗干擾,超時重發,不斷重連的編程思路 在工程中會遇到一種情況,當通信受到干擾之后,數據超時重發多次,無法被成功發出去,當恢復干擾后,之前發送的指令就被報錯清掉了,相當于串口掉線之后,即使短暫時間內通信連上,掉線之后發出的指令也不生效。 為了確保受到干…

OFDM符號周期

OFDM符號周期的確定 OFDM符號周期的確定是一個復雜的過程&#xff0c;需要考慮多個因素。以下是主要的考慮因素和確定步驟&#xff1a; 主要考慮因素 信道特性 多徑延遲擴展相干時間 系統要求 數據速率頻譜效率 硬件限制 采樣率計算復雜度 應用場景 移動性要求覆蓋范圍 …

spark shuffle寫操作——SortShuffleWriter

寫入的簡單流程&#xff1a; 1.生成ExternalSorter對象 2.將消息都是插入ExternalSorter對象中 3.獲取到mapOutputWriter&#xff0c;將中間產生的臨時文件合并到一個臨時文件 4.生成最后的data文件和index文件 可以看到寫入的重點類是ExternalSorter對象 ExternalSorter 基…