日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

想和高手侃侃而谈C++引用?看这一篇就够了【C++引用】

發布時間:2025/3/20 c/c++ 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 想和高手侃侃而谈C++引用?看这一篇就够了【C++引用】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  • 定義
  • 應用
  • 存在對指針取引用
  • 不存在對引用取地址
  • 存在指針的指針,不存在引用的引用
  • 存在指針數組,不存在引用數組
  • 數組的引用
  • 常引用
  • 常引用的特性
  • 臨時對象的常引用
    • 類型不同的變量常引用本質剖析
  • 在能夠使用 const 的地方就使用 cosnt
  • 引用的本質
    • 引用的大小
    • 引用的類型
    • 結論
    • 反匯編比對指針和引用
      • 源代碼
      • 匯編代碼比對結果
      • 結論

定義

變量名本身是一段內存的引用,也就是別名。
引用是為已有變量起別名。

int a; int &ra = a;

引用是聲明關系,不分配內存空間(宏觀)。
引用必須初始化,不能獨立存在。
與被別名的變量具有相同數據類型。

代碼演示:

#include <iostream>using namespace std;int main() {int a = 100;int& ra = a;cout << "a = " << a << endl;cout << "ra = " << ra << endl;cout << "&a = " << &a << endl;cout << "&ra = " << &ra << endl;cout << "sizeof(a)= " << sizeof(a) << endl;cout << "sizeof(ra) = " << sizeof(ra) << endl;return 0; }

運行結果:

值相等,地址相等,大小相等,證明了引用在內存中的別名關系。

可以對引用再次取引用,對一個變量建立多個引用,多個引用之間是等價關系。
代碼演示:

#include <iostream>using namespace std;int main() {int a = 100;int& ra = a;int& rb = a;int& rc = rb;int& rd = rc;cout << "a = " << a << endl;cout << "ra = " << ra << endl;cout << "rb = " << rb << endl;cout << "rc = " << rc << endl;cout << "rd = " << rd << endl;cout << "&a = " << &a << endl;cout << "&ra = " << &ra << endl;cout << "&rb = " << &rb << endl;cout << "&rc = " << &rc << endl;cout << "&rd = " << &rd << endl;cout << "sizeof(a) = " << sizeof(a) << endl;cout << "sizeof(ra) = " << sizeof(ra) << endl;cout << "sizeof(rb) = " << sizeof(rb) << endl;cout << "sizeof(rc) = " << sizeof(rc) << endl;cout << "sizeof(rd) = " << sizeof(rd) << endl;return 0; }

運行結果:

應用

取代指針傳參。
C++可以用引用解決的問題,避免用指針來解決。

代碼演示;

#include <iostream>using namespace std;void swapByValue(int a, int b) {int tmp;tmp = a;a = b;b = tmp; }void swapByPtr(int* a, int* b) {int tmp;tmp = *a;*a = *b;*b = tmp; }void swapByRef(int& a, int& b) {int tmp;tmp = a;a = b;b = tmp; }int main() {int a = 3, b = 5;cout << "a = " << a << " b = " << b << endl;swapByRef(a, b);cout << "a = " << a << " b = " << b << endl;return 0; }

運行結果:

引用的從宏觀上可以理解為:擴展了變量的作用域,傳參后,就像在本地解決問題一樣。
把一個變量以引用的方式傳到另一個作用域,等價于擴展了該變量的作用域。
避免了傳 n 級指針,解決 n-1 級指針的問題,即平級內解決問題。

存在對指針取引用

代碼演示:

#include <iostream> using namespace std;void swapByRef(char * & a, char * & b) {char * tmp;tmp = a;a = b;b = tmp; }int main() {char* p = "hello";char* q = "world";cout << "p = " << p << " q = " << q << endl;swapByRef(p, q);cout << "p = " << p << " q = " << q << endl;return 0; }

運行結果:

不存在對引用取地址

引用的本質:對指針的包裝,避免使用裸露的指針。
設計思想:C++避免對引用再次拆封。
代碼演示:

#include <iostream> using namespace std;int main() {int a;int* p = &a;int* & pr = p;int& ra = a;int& * rpa = &ra;return 0; }

編譯器報錯:不允許使用指向引用的指針。

存在指針的指針,不存在引用的引用

指針的指針,即二級指針。
C++為了避免 C 語言設計指針的"失誤",避免了引用的引用這種情況,也避免了引用的引用的引用的…的引用的情況。
這種可窮遞歸的設計本身就是有問題的。

代碼演示:存在指針的指針

#include <iostream> using namespace std;int main() {int a;int* p = &a;int** pp = &p;int*** ppp = &pp;int**** pppp = &ppp;//無窮無盡return 0; }

代碼演示:不存在引用的引用

#include <iostream> using namespace std;int main() {int a;int & p = a;int&& pp = p; //剎車return 0; }

存在指針數組,不存在引用數組

數組名,本身是首元素的地址,若首元素是引用的話,數組名就成了引用的指針,與上面說過的不符,即不存在引用的指針。
代碼演示:存在指針數組

#include <iostream> using namespace std;int main() {int a, b, c;int* pArr[] = {&a, &b ,&c};return 0; }

pArr 代表首元素地址,首元素是 &a 指針,則 pArr 是二級指針。

代碼演示:不存在引用數組

#include <iostream> using namespace std;int main() {int a, b, c;int & pArr[] = {a, b ,c};return 0; }

編譯器報錯:

pArr 代表首元素地址,首元素是變量名a(可以將a理解為對內存的引用),上面說過不允許對引用取地址。

數組的引用

代碼演示:

#include <iostream> using namespace std;int main() {//數組名的兩重性://1:代表整個數組。//2:代表首元素地址。int array[5] = {1,2,3,4,5};int* const & pr = array; //int* const &cout << pr << endl;cout << array << endl;cout << "sizeof(pr) = " << sizeof(pr) << endl;cout << "sizeof(array) = " << sizeof(array) << endl;for (int i = 0; i < 5; i++){cout << pr[i];}cout << endl;int(&ra)[5] = array;cout << ra << endl;cout << array << endl;cout << "sizeof(ra) = " << sizeof(ra) << endl;cout << "sizeof(array) = " << sizeof(array) << endl;for (int i = 0; i < 5; i++){cout << ra[i];}cout << endl;return 0; }

運行結果:

常引用

C++中 const 定義的變量稱為常變量。
const 修飾的變量,有著變量的形式,常量的作用,用作常量,常用于取代#define 定義的宏常量。
#define 宏定義在預處理階段替換,const 常量在匯編階段替換。

常引用的特性

const 的本意,即不可修改。所以,const 對象,只能聲明為 const 引用,使其語義保持一致性。

no-const 對象,既可以聲明為 const 引用,也可以聲明為 no-const 引用。
聲明為 const 引用,則不可以通過 const 引用修改數據。

代碼演示:

#include <iostream> using namespace std; int main() {const int val = 10;//int& rv = val; //err類型不等價const int &rv2 = val;//類型等價int data = 666;int& rd = data;const int& rd2 = data;//非const 對象生命為 const 引用//rd2 = 333; 不可修改cout << "data = " << data << " rd = " << rd << " rd2 = " << rd2 << endl;data = 999; cout << "data = " << data << " rd = " << rd << " rd2 = " << rd2 << endl;return 0; }

運行結果:

臨時對象的常引用

臨時對象:不可以取地址的對象。

臨時對象:

  • CPU中計算產生的中間變量。
  • 常量。
  • 表達式。
  • 函數返回值。
  • 類型不同的變量。
  • 代碼演示:臨時對象的常引用

    #include <iostream>using namespace std;//臨時變量 即不可取地址的對象int foo() {int a = 66;return a; }int main() {//常量const int& cc = 55;cout << "cc = " << cc << endl;//表達式int a = 3;int b = 5;const int& ret = a + b;cout << "ret = " << ret << endl;//函數返回值const int& ra = foo();cout << "ra = " << ra << endl;//類型不同的變量double d = 100.12;const int& rd = d;cout << "d = " << d << endl;cout << "rd = " << rd << endl;return 0; }

    運行結果:

    臨時對象的常引用本質:產生中間變量。

    類型不同的變量常引用本質剖析

    代碼演示:

    #include <iostream>using namespace std;int main() {double d = 3.14;//int & t = d; err 類型不等價const int& rd = d; //產生中間變量cout << "d = " << d << endl;cout << "rd = " << rd << endl;d = 4.14;cout << "d = " << d << endl;cout << "rd = " << rd << endl;return 0; }

    運行結果:

    本質上 const 引用,引用了一個不可改變的臨時變量,

    const int tmp = data; const int & rd = tmp;

    此時,我們改變了 data 的值,臨時變量 tmp 的值并沒有發生改變。

    在能夠使用 const 的地方就使用 cosnt

    好處:

  • 避免無意修改數據的編程錯誤。
  • 使用 const 處理 const 和 非cosnt 。否則將只接受 非const數據。
  • 使用 cosnt引用,可使函數能夠正確的生成并使用臨時變量。(實參與引用參數不匹配,就會產生臨時變量。)
  • 引用的本質

    引用的本質:C++對指針的包裝,引用即指針。

    引用的大小

    代碼演示;

    #include <iostream>using namespace std;struct TypeP {char* p; };struct TypeC {char c; };struct TypeR {char& r; };int main() {cout << "sizeof(TypeP) = " << sizeof(TypeP) << endl;cout << "sizeof(TypeC) = " << sizeof(TypeC) << endl;cout << "sizeof(TypeR) = " << sizeof(TypeR) << endl;return 0; }

    運行結果:

    引用的類型

    C++中只有 const 類型的數據,要求必須初始化。
    引用也必須要初始化,所以引用是 const 修飾的指針,一經聲明,不可修改。引用的內容可以修改。所以是:type* const p

    結論

    引用的本質是 const 類型的指針,即 type* const p。
    引用是對指針的封裝。
    從微觀角度來說,引用至少需要分配一個指針類型大小的內存空間。

    反匯編比對指針和引用

    源代碼

    代碼演示:

    #include <iostream>using namespace std;void swapPtr(int* p, int* q) {int t = *p;*p = *q;*q = t; } void swapRef(int& p, int& q) {int t = p;p = q;q = t; } int main() {int a = 3; int b = 5;swapRef(a, b);swapPtr(&a, &b);return 0; }

    匯編代碼比對結果

    結論

    對同一個功能相同的程序,分別采用了指針和引用的兩種方式來進行編寫,匯編得到的結果一致。
    證明:引用的本質是對指針的封裝。

    總結

    以上是生活随笔為你收集整理的想和高手侃侃而谈C++引用?看这一篇就够了【C++引用】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。