指針與數組的對比
C++/C程序中,指針和數組在很多地方能夠相互替換着用,讓人產生一種錯覺,覺得二者是等價的。
數組要麼在靜態存儲區被建立(如全局數組),要麼在棧上被建立。數組名對應着(而不是指向)一塊內存,其地址與容量在生命期內保持不變,只有數組的內容能夠改變。
指針能夠隨時指向任意類型的內存塊,它的特徵是「可變」,因此咱們經常使用指針來操做動態內存。指針遠比數組靈活,但也更危險。數組
下面以字符串爲例比較指針與數組的特性。函數
1 修改內容
下面示例中,字符數組a的容量是6個字符,其內容爲hello。a的內容能夠改變,如a[0]= ‘X’。指針p指向常量字符串「world」(位於靜態存儲區,內容爲world),常量字符串的內容是不能夠被修改的。從語法上看,編譯器並不
以爲語句 p[0]= ‘X’有什麼不妥,可是該語句企圖修改常量字符串的內容而致使運行錯誤。指針
char a[] = "hello";內存
a[0] = 'X';
cout << a << endl;
char *p = "world"; // 注意p指向常量字符串
// p[0] = 'X'; // 編譯器不能發現該錯誤
cout << p << endl;
system("pause");字符串
2 內容複製與比較編譯器
不能對數組名進行直接複製與比較。若想把數組a的內容複製給數組b,不能用語句 b = a ,不然將產生編譯錯誤。應該用標準庫函數strcpy進行復制。同理,比較b和a的內容是否相同,不能用if(b==a) 來判斷,應該用標準庫函數strcmp進行比較。語句p = a 並不能把a的內容複製指針p,而是把a的地址賦給了p。要想複製a的內容,能夠先用庫函數malloc爲p申請一塊容量爲strlen(a)+1個字符的 內存,再用strcpy進行字符串複製。同理,語句if(p==a) 比較的不是內容而是地址,應該用庫函數strcmp來比較。編譯
// 數組
char a[] = "hello";
char b[10];
strcpy(b, a); // 不能用 b = a;
if(strcmp(b, a) == 0) // 不能用 if (b == a)
{
cout << b << endl;
}
//指針
int len = strlen(a);
char *p = (char *)malloc(sizeof(char)*(len+1));
strcpy(p,a); // 不要用 p = a;
if(strcmp(p, a) == 0) // 不要用 if (p == a)
{
cout << p << endl;
}
system("pause");變量
3 計算內存容量
用運算符sizeof能夠計算出數組的容量(字節數)。以下示例中,sizeof(a)的值是12(注意別忘了’’)。指針p指向a,可是sizeof (p)的值倒是4。這是由於sizeof(p)獲得的是一個指針變量的字節數,至關於sizeof(char*),而不是p所指的內存容量。C++/C語言沒有辦法知道指針所指的內存容量,除非在申請內存時記住它。
char a[] = "hello world";
char *p = a;
cout<< sizeof(a) << endl; // 12字節
cout<< sizeof(p) << endl; // 4字節
注意當數組做爲函數的參數進行傳遞時,該數組自動退化爲同類型的指針。
以下示例中,不論數組a的容量是多少,sizeof(a)始終等於sizeof(char *)。
void Func(char a[100])
{
cout<< sizeof(a) << endl; // 4字節而不是100字節
}語法