📢博客主頁: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;
}
下面是該程序的輸出結果
👥總結
本篇博文對 引用變量 做了一個較為詳細的介紹,不知道對你有沒有幫助呢
覺得博主寫得還不錯的三連支持下吧!會繼續努力的~