天天看點

C++ 指針、數組和引用辨析

一、指針:内容是訓示一個記憶體位址的變量;類型是訓示編譯器怎麼解釋指針内容指向位址中的内容,以及該記憶體區域有多大;

例子:

int i = 0;
int * pi = &i;
printf(“pi = %x  \n”, pi);     // 列印pi的内容: 0x2000
printf(“*pi= %d  \n” , *pi);   // 列印pi指向位址中的值: 5
printf(“&pi= %x  \n”, &pi);    // 列印pi的位址: 0x100
           
C++ 指針、數組和引用辨析

從彙編的角度來看,指針是這樣的:

int i = 0;

010E139E  mov         dword ptr [i],0  

int * pi = &i;

010E13A5  lea         eax,[i]  

010E13A8  mov         dword ptr [pi],eax

二、數組:是一個單一資料類型對象的集合。其中單個對象沒有被命名,通過索引通路。

數組名和指針的差別:數組名的内涵在于其指代實體是一種資料結構,這種資料結構就是數組。數組名的外延在于其可以轉換為指向其指代實體的指針,而且是一個指針常量。指向數組的指針則是另外一種變量類型,僅僅意味着數組的存放位址

注意:雖然數組名可以轉換為指向其指代實體的指針,但是它隻能被看作一個指針常量,不能被修改,如下:

int intArray[10];
   intArray++; // 錯誤
           

“指針和數組等價”說的是什麼?索引操作相同,例如: p[2];  a[2];

C++ 指針、數組和引用辨析

三、 引用 ( reference )是一個對象的别名。用對象初始化引用後,對象的名字和引用都指向該對象;

引用是如何實作的? 從彙編語言的角度來看,指針和引用是一樣的:

int i = 0;
00E9139E  mov         dword ptr [i],0  
	int & ref = i;
00E913A5  lea         eax,[i]  
00E913A8  mov         dword ptr [ref],eax  
	int * pi = &i;
00E913AB  lea         eax,[i]  
00E913AE  mov         dword ptr [pi],eax 
           

指針和引用的差別(從C++ 使用角度來看):

  • 不存在空引用
  • 引用要初始化
  • 引用初始化後,不能指向另一個對象

這是由編譯階段保證的。

備注 : 1、一個指向非常量的引用不能用字面值或者臨時值初始化;但是一個指向常量的引用可以。 例子:

double& d = 12.3;  // error!
const double& d = 12.3;
           

2、由于引用必須初始化,是以使用引用之前不需要測試其有效性,是以使用引用可能會比使用指針效率高。 3、當你實作一個操作符而其文法需求無法由指針完成時,應該選擇引用,例如operator[]。operator[]能夠出現在一個指派操作符的左右兩邊,為了能在左邊出現,它的傳回值必須是左值,再考慮到使用的友善性,通常把其傳回值指定為一個引用類型。 例子:

#include <cassert>

char& String::operator[](int elem) const
{
    assert(elem >= 0 && elem <= length());
    return _string[elem];
}
           

4、當你需要考慮不指向任何對象的可能性,或考慮在不同時候指向不同對象的能力時,應該使用指針。 5、引用的所有操作實際上都是應用在它所指的對象上,包括取位址操作符。 6、一些有些特殊的引用舉例:

int  val = 10;
int* pval = &val;
int*& rpval = pval; // 指針引用
           
const int i = 10;
const int * const & ref = &i; // 指向常量對象位址的引用
           
c++

繼續閱讀