指針與引用的區別


最近在看C++Primer第五版,以前雖然競賽一直用的C++,但是感覺自己學的不太深入,而且對於很多東西不求甚解,所以這次沉下心來好好看看這本C++經典,做一些相關的筆記。

引用

我們通過在變量名前添加&來定義一個引用類型。例如:

int val = 10;
int &refVal = val;

引用與它所指向的對象綁定到一起,引用並不是一個對象,所以其實引用就可以看作是一個變量的別名。我們對引用所進行的一些操作,其實都是作用在其綁定的對象身上的。引用在絕大部分情況下都必須與相同類型的對象進行綁定,而且引用不能與字面值或者是某個表達式的計算結果進行綁定。

int val = 10;
int &refVal = val;
refVal = 20; //其實這個賦值操作真正的作用對象是val,val=20
double &refVal2 = val; //錯誤,類型不匹配
int &ref = 10; //錯誤,不能與字面值進行綁定

有一個重要的點是,引用一旦與對象綁定,那么我們就不能再改變它,使其與其他對象綁定。正是因為這個規定,所以我們在定義引用的時候必須將其初始化,使其與某個對象進行綁定。

指針

指針一直都是學C/C++人士的一個噩夢,因為它極高的靈活性和復雜的操作,所以一不小心就會掉進自己挖的坑里。但是這個知識又是大家都繞不過的,所以我們還是得好好了解下,至少當其他的代碼里面出現這些相關內容之后,我們應該能夠看懂。

通過它的名字“指針”我們可以知道,這個東西是用來指向某個對象的。至少這點和引用有點類似,指針同樣實現了對所指向對象的間接訪問。

我們通過在變量名前添加*來定義一個指針類型。例如:

int *p1;
double *p2;

指針所做的操作是將所指向對象的地址保存,這樣就實現了“指向”的功能。所以我們在給指針變量賦值的時候一定要將對象的地址賦給它。這個時候需要用到“取地址符”&,注意此時的&是取地址的意思,但是上面它也有引用的意思,我們要結合上下文來理解符號的具體意思。

int val = 10;
int *p;
p = &val; //將val變量的地址放在p指針中

如果我們要對它所指向的對象進行操作的時候,我們需要用到*(解引用符)。

int val = 10;
int *p;
p = &val;
*p = 20; //此時是將val的值賦為20

指針可以在定義的時候不進行初始化,而在之后進行初始化,並且指針可以更換自己指定的對象。與引用類似,在絕大多數情況下,我們指針所指向的對象的類型必須要與指針的類型保持一致。

double v = 2.5;
int val1 = 10, val2 = 20;
int *p; //在定義的時候不必要進行初始化
p = &val1; 
p = &val2; //指針指向另外一個對象
int *ptr = &v; //錯誤,類型不匹配

因為指針本身也是一個對象,它也有自己的地址,所以我們可以定義出指向指針的指針,同樣還有指針的指針的指針...

int val = 10;
int *p = &val;
int **pp = &p; //指向指針的指針,注意聲明符的寫法
int ***ppp = &pp; //指向指針的指針的指針

我們還需要注意空指針的一些相關操作:

int *p1 = 0; //定義一個空指針
int *p2 = nullptr; //等價於上面的語句

//首先在代碼中加入#include <cstdlib>
int *p3 = NULL; //同樣是定義一個空指針

//但是我們需要注意,不能直接將變量的值賦給一個指針,哪怕該變量的值等於0也不可以
int val = 0;
int *p4 = val; //錯誤

引用與指針之間的主要區別

通過上面的講解我們可以發現,雖然引用與指針同樣都可以對某對象實現間接訪問,但是還是有很多不同的。

  1. 一個最大的不同點就是:引用不是一個對象,所以它沒有實際的地址。指針是一個對象,它有實際的地址,所以我們可以定義指向指針的指針,但是絕對不能定義指向引用的指針。
  2. 引用在其生命周期中不能改變所綁定的對象,但是指針可以在其生命周期內先后指向不同的對象。
  3. 引用在定義的時候必須進行初始化,而指針可以不必進行初始化(不推薦這種做法)。

References:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM