1. 程式人生 > >C++總結1——指標和引用/陣列的區別【轉】

C++總結1——指標和引用/陣列的區別【轉】

1.指標和引有什麼區別?(從反彙編角度回答) 

a.其實引用和指標本質上是一樣的,他們的彙編指令都是兩行。 

int a = 10;  int *p = &a;  //lea eax,[a]                          將a的地址放在eax暫存器中  //mov dword ptr [p], eax     將eax暫存器中的值給p

int &q = q;  //lea eax,[a]                           將a的地址放在eax暫存器中  //mov dword ptr [q],eax       將eax暫存器中的值給q

可以通過引用或指標解引用改變變數的值,這兩種操作產生的彙編指令也是一樣的。  *p = 20;  //mov eax, dword ptr[p]        將p的值(即變數a的地址)放在eax暫存器中  //mov dword ptr[eax], 14h    將14h賦值給eax暫存器中儲存的變數  q = 20;

//mov eax,dword ptr[q]           將q的值(即變數a的地址)放在eax暫存器中  //mov  dword ptr[eax],14h      將14h賦值給eax暫存器中儲存的變數

b.定義引用變數必須初始化,指標變數可以初始化。引用其實就是C++中的常量指標。表示式int &p = a;實則會被編譯器編譯為int *const p = &a;所以,引用變數必須初始化是因為const型別變數必須初始化。

c.引用變數定義時引用誰,永遠引用誰。一經引用,不能改變。指標可以更改其指向,指向別的變數。原因也是因為引用就是C++中的常量指標,常量指標的指向不能修改。

d.使用引用變數會自動解引用。在X86體系,32位平臺linux平臺上,指標佔4個位元組,如果對引用變數求sizeof,是該引用變數引用的變數所佔的位元組數。這是因為引用是一種會被編譯器自動解引用的指標。

e.C99標準中,引用只能有一級引用,指標可以有多級指標。C11標準中支援多級引用

擴充套件部分: 

你有沒有疑問:上面剛說引用變數佔用記憶體,但現在列印引用變數的地址和普通變數的地址卻是一樣的!

回顧剛才說的,引用其實就是C++中的常量指標。把上段程式碼中的引用變數都用常量指標替換,程式碼如下:    這段程式碼才是編譯器真正編譯的程式碼!

從反彙編程式碼看: 

cout<<&a;  //lea  eax,[a]     將a的地址放在eax暫存器中  //push  eax       將eax暫存器壓棧

cout<<&p;  //mov  eax,dword ptr[p]  將p的值(p裡儲存的是a的地址)放在eax暫存器中  //push  eax                       將eax暫存器壓棧

我要指出的是,C++標準並沒有解釋編譯器如何實現引用的行為。所以其實現取決於編譯器,而大多數情況下就是將其實現為一個 const 指標。

看到這兒,你應該對指標和引用的區別有了比較全面的理解了。

2.指標和陣列有什麼區別? 

a.在X86體系,32位平臺上,指標佔4個位元組。陣列所佔的位元組大小與陣列型別有關。sizeof(陣列型別)*size

b.指標儲存的資料的地址,陣列儲存的是資料的值

c.使用指標是間接獲取資料,首先取得指標的內容。然後把它作為地址,從這個地址取資料。使用陣列是直接獲取資料

e.指標和陣列之間的表示可以互換

int arr[10] = {0,1,2,3,4,5,6,7,8,9}; int *p = arr;

int i = 3; p[i] = *(p+i); *(arr+i) = arr[i];