程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ 對引用的深入理解,引用深入理解

C++ 對引用的深入理解,引用深入理解

編輯:C++入門知識

C++ 對引用的深入理解,引用深入理解


觀看了唐老師講解的一節《第5課 - 引用的本質分析》感覺非常不錯,有深度不廢話,我喜歡~~~

再此總結下,並且奉上視頻下載地址~~~

360網盤下載地址: https://yunpan.cn/cxXynI6sGbHJs      密碼(4b1b)

//----------------------------------------------正文----------------------------------------------

 

在C裡並沒引用這個語法,而在C++裡具有這個語法。為什麼C++要添加引用這個語法?

我的理解就是引用就是對指針的封裝!

首先,指針變量有多種種形態:p *p &p;

1)p:  代表指針變量中存放的地址值,這個地址值一般就是某個變量的內存地址。

2)*p: 對應的是,p裡存放的內存地址中的值。

3)&p: 存放指針變量的內存地址。

使用指針就意味著隨時,形態的轉變,如取地址,解引用。有時候理解稍微偏差,忘記取地址或者是解引用,就會出現莫名其妙的問題。

為了簡化指針的使用,並且和指針擁有一樣的強大功能,引用就出現了。

先看一段程序:

int main(int argc, char *argv[])
{    
    
    //普通變量 
    int a0 = 8;
     int b0 = a0;
     b0 = 88;
      cout << a0 << endl;
    
    //指針變量 
    int a1 = 8;
     int* b1 = &a1;
     cout << *b1 << endl;
     *b1 = 88;
      cout << a1 << endl;
      
      //引用 
    int a2 = 8;
     int& b2 = a2;
     b2 = 88;
      cout << a2 << endl;    
    
    return 0;
}

 

 

1、b0為普通變量,int b0 = a0;僅僅是簡單的賦值,所以改變b0的值無法改變

a0的值,它們關聯不同的內存空間。

2、b1為指針變量,int* b1 = &a1;這一句將a1的地址給b1這個指針變量。

3、b2為a2的引用,int& b2 = a2;就表示b2和a2關聯上了。從此它們同氣連枝不分彼此。引用這段程序和普通變量那段程序相比解決多了一個&而已,但是卻達到了指針的效果。省去了指針解引用取地址這樣的過程。看上去就給同一塊內存空間取了兩個名字,這兩個名字任意一個都可以對這篇內存進行操作。

知道了引用的好處,再來分析他的原理,之前說過我的理解引用就是對指針的封裝,其實在引用的背後,其實就是指針,只是編譯器隱藏了這個細節。如何證明呢?

首先新建一個結構體:

struct TRef

{

char& r;

};

然後測試這個結構體的大小:

cout << sizeof(TRef) << endl;

發現大小為4,正好是一個指針的大小!(去掉&測試大小是1).進一步分析就得看匯編

Char& b = a; 反匯編之後變成了兩句:

wps33D2.tmp

第一句將a的地址放大eax寄存器,然後將eax的值及a的地址放到了b所在的地址空間,所以b裡裝的是a的地址值。這就是指針的實現過程!

所以一旦編譯器,識別到這個變量是個引用,那麼當給這個引用關聯一個變量時,編譯器自動給被關聯的變量取地址,當給引用賦值常量的時候,編譯器自動給該變量解引用。

正因為,編譯器幫你自動完成了取地址和解引用,你才可以不用作這些容易出錯的事情,而且完成指針的工作。

這裡補充說明一點:

如果你直接去測試cout << sizeof(char&) << endl;的值大小是1,而不是4.這是因為,如果直接訪問引用,編譯器就會幫你完成解引用這個過程,那麼你檢測的就是char而不是指針了。而放到結構體裡面   就是為了不去直接操作引用 而得到引用的特性。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved