1. 程式人生 > 實用技巧 >詳解C++中指標和引用的區別

詳解C++中指標和引用的區別

一、指標和引用的本質

(1)指標是存放記憶體地址的一種變數,特殊的地方就在它存放的是記憶體地址。因此,指標的大小不會像其他變數一樣變化,
只跟當前平臺相關——不同平臺記憶體地址的範圍是不一樣的,32位平臺下,記憶體最大為4GB,因此只需要32bit就可以存下,
所以sizeof(pointer)的大小是4位元組。64位平臺下,32位就不夠用了,要想記憶體地址能夠都一一表示,
就需要64bit(但是目前應該沒有這麼大的記憶體吧?),因此sizeof(pointer)是8。
引用的本質是“變數的別名”,就是給變數又重新起了一個名字,既然是“別名”,那麼就一定要有本體。

(2)可以有const指標,但是沒有const引用;

const引用可以用不同型別的物件初始化(只要能從一種型別轉換到另一種型別即可),也可以是不可定址的值,如文字常量

doubledval=3.14159;

//下3行僅對const引用是合法的
constint&ir=1024;
constint&ir2=dval;
constdouble&dr=dval+1.0;

引用在內部存放的是一個物件的地址,它是該物件的別名。對於不可定址的值,如文字常量,以及不同型別的物件,
編譯器為了實現引用,必須生成一個臨時物件,引用實際上指向該物件,但使用者不能訪問它。

doubledval=23;
constint&ri=dval;

編譯器將其轉換為:
inttmp=dval;//double->int
constint&ri=tmp;

(3)指標可以有多級,但是引用只能是一級(int **p;合法 而 int &&a是不合法的)

(4)指標的值可以為空,但是引用的值不能為NULL,並且引用在定義的時候必須初始化;
根據宣告和初始化時二者的區別,指標在宣告週期內隨時可能會為Null,所以使用時一定要做檢查, 防止出現空指標、野指標的情況;
而引用只要初始化了,在哪裡都可以直接使用,再也不用擔心它會不會為空什麼的了。

(5)指標的值在初始化後可以改變,即指向其它的儲存單元,而引用在進行初始化後就不會再改變了。
指標因為自己存的是一個記憶體地址,既然可以存初始化(或者賦值)的地址,那麼在指標生命週期內就可以存其他的地址,
只要你是同一型別(不同型別這個對應的型別偏移不一樣)的變數,對於指標都OK。

引用作為一個變數AA的別名,在它的整個生命週期內,它只能“從一而終”,
始終是第一次初始化它的那個變數的別名,在這期間任何對它的操作,都等同於對變數AA的操作。

(6)"sizeof引用"得到的是所指向的變數(物件)的大小,而"sizeof指標"得到的是指標本身的大小;

(7)指標和引用的自增(++)運算意義不一樣;

二、指標和引用作為函式引數進行傳遞時的區別

  1. 指標作為引數進行傳遞:

用指標傳遞引數,可以實現對實參進行改變的目的,是因為傳遞過來的是實參的地址,
因此使用*a實際上是取儲存實參的記憶體單元裡的資料,即是對實參進行改變,因此可以達到目的

void swap(int *a,int *b)
{
  int temp=*a;
  *a=*b;
  *b=temp;
}

int main(void)
{
  int a=1,b=2;
  swap(&a,&b);
  cout<<a<<" "<<b<<endl;
  return 0;
}
  1. 將引用作為函式的引數進行傳遞
    引用作為函式引數進行傳遞時,實質上傳遞的是實參本身,即傳遞進來的不是實參的一個拷貝,
    因此對形參的修改其實是對實參的修改,所以在用引用進行引數傳遞時,不僅節約時間,而且可以節約空間。
void test(int &a)
{
  cout<< &a << " " << a << endl;
}

int main(void)
{
  int a=1;
  cout<< &a << " " << a << endl;
  test(a);
  return 0;
}

參考:
詳解C++中指標和引用的區別
c++中指標和引用的區別