數組與指針


C++/C 程序中,指針和數組在不少地方可以相互替換着用,讓人產生一種錯覺,以爲兩者是等價的。
數組要麼在靜態存儲區被創建(如全局數組),要麼在棧上被創建。數組名對應着(而不是指向)一塊內存,其地址與容量在生命期內保持不變,只有數組的內容可以改變。
指針可以隨時指向任意類型的內存塊,它的特徵是“可變”,所以我們常用指針來操作動態內存。指針遠比數組靈活,但也更危險。
下面以字符串爲例比較指針與數組的特性。
修改內容

示例中,字符數組a 的容量是6 個字符,其內容爲hello\0。a 的內容可以改變,如a[0]= ‘X’。指針p 指向常量字符串“world”(位於靜態存儲區,內容爲world\0),常量字符串的內容是不可以被修改的。從語法上看,編譯器並不覺得語句p[0]= ‘X’有什麼不妥,但是該語句企圖修改常量字符串的內容而導致運行錯誤。

  1. char a[] = “hello”;  
  2. a[0] = ‘X’;  
  3. cout << a << endl;  
  4. char *p = “world”; // 注意p 指向常量字符串  
  5. p[0] = ‘X’; // 編譯器不能發現該錯誤  
  6. cout << p << endl;  
char a[] = “hello”;
a[0] = ‘X’;
cout << a << endl;
char *p = “world”; // 注意p 指向常量字符串
p[0] = ‘X’; // 編譯器不能發現該錯誤
cout << p << endl;

內容複製與比較

不能對數組名進行直接複製與比較。示例中,若想把數組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 來比較
  1. // 數組…  
  2. char a[] = "hello";  
  3. char b[10];  
  4. strcpy(b, a); // 不能用 b = a;  
  5. if(strcmp(b, a) == 0) // 不能用 if (b == a)  
  6. …  
  7. // 指針…  
  8. int len = strlen(a);  
  9. char *p = (char *)malloc(sizeof(char)*(len+1));  
  10. strcpy(p,a); // 不要用 p = a;  
  11. if(strcmp(p, a) == 0) // 不要用 if (p == a)  
// 數組…
char a[] = "hello";
char b[10];
strcpy(b, a); // 不能用 b = a;
if(strcmp(b, a) == 0) // 不能用 if (b == a)
…
// 指針…
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)

計算內存容量
用運算符sizeof 可以計算出數組的容量(字節數)。示例7-3-3(a)中,sizeof(a)的值是12(注意別忘了’\0’)。指針p 指向a,但是sizeof(p)的值卻是4。這是因爲sizeof(p)得到的是一個指針變量的字節數,相當於sizeof(char*),而不是p 所指的內存容量。C++/C 語言沒有辦法知道指針所指的內存容量,除非在申請內存時記住它。
注意當數組作爲函數的參數進行傳遞時,該數組自動退化爲同類型的指針。示例中,不論數組a 的容量是多少,sizeof(a)始終等於sizeof(char *)。
  1. char a[] = "hello world";  
  2. char *p = a;  
  3. cout<< sizeof(a) << endl; // 12 字節  
  4. cout<< sizeof(p) << endl; // 4 字節  
  5. 示例 計算數組和指針的內存容量  
  6. void Func(char a[100])  
  7. {  
  8. cout<< sizeof(a) << endl; // 4 字節而不是100 字節  
  9. }  
char a[] = "hello world";
char *p = a;
cout<< sizeof(a) << endl; // 12 字節
cout<< sizeof(p) << endl; // 4 字節
示例 計算數組和指針的內存容量
void Func(char a[100])
{
cout<< sizeof(a) << endl; // 4 字節而不是100 字節
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章