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

從彙編的角度來看,指針是這樣的:
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];
三、 引用 ( 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; // 指向常量對象位址的引用