一、類型 T 的指針和類型 T 的數組並非同種類型。
常常聽說 char c[] 和 char *c 是一樣的。然而實際上並非如此。數組定義 char c[10] 請求預留 10 個字符的位置, 並用名稱 “c” 表示。也就是說, 有一個稱爲 “c” 的位置, 可以放入 10 個字符。而指針申明 char *p, 請求一個位置放置一個指針, 用名稱 “p” 表示。這個指針幾乎可以指向任何位置: 任何字符和任何連續的字符, 或者哪裏也不指。
#include<iostream>
using namespace std;
int main(){
char c[10]="licongqi";
char *p = "licongqi";
char a;
a = c[0];
a = c[3];
a = p[3];
cout<<c<<endl<<*p<<endl;
return 0;
}
根據 X 是數組還是指針, 類似 X[3] 這樣的引用會生成不同的代碼。以上面的聲明爲例, 當編譯器看到表達式 c[3] 的時候, 它生成代碼從 c 的位置開始跳過 3 個, 然後取出那個字符. 如果它看到 p[3], 它生成代碼找到“p” 的位置, 取出其中的指針值, 在指針上加
3 然後取出指向的字符。換言之, c[3]是名爲 c 的對象 (的起始位置) 之後 3 個位置的值, 而p[3] 是 p 指向的對象的 3 個位置之後的值. 在上例中, c[3] 和 p[3] , 編譯器到達那裏的途徑不盡相同。本質的區別在於類似 c 的數組和類似 p 的指針一旦在表達式中出現就會按照不同的方法計算, 不論它們是否有下標。
8: a = c[0];
004011AE mov cl,byte ptr [ebp-0Ch]
004011B1 mov byte ptr [ebp-14h],cl
9: a = c[3];
004011B4 mov dl,byte ptr [ebp-9]
004011B7 mov byte ptr [ebp-14h],dl
10: a = p[3];
004011BA mov eax,dword ptr [ebp-10h]
004011BD mov cl,byte ptr [eax+3]
004011C0 mov byte ptr [ebp-14h],cl
數組和指針的區別是什麼?
數組自動分配空間, 但是不能重分配或改變大小。指針必須明確賦值以指向分配的空間 (可能使用 malloc), 但是可以隨意重新賦值 (指向不同的對象), 同時除了表示一個內存塊的基址之外, 還有許多其它的用途。由於數組和指針所謂的等價性, 數組和指針經常看起來可以互換, 而事實上指向 malloc 分配的內存塊的指針通常被看作一個真正的數組(也可以用[]引用)。但是, 要小心 sizeof。
二、指針數組和數組指針大不相同
指針數組,按字面意思理解,就是一個數組,其中的元素是指針。
例如 int *arr[10];聲明瞭一個數組,數組大小爲10,數組中元素的類型爲int *,若要操作數組中的元素,需要取下標。
而數組指針,則是一個指針,它指向的是一個數組。
例如int (*p)[10];聲明瞭一個指針,該指針指向一個大小爲10,元素類型爲int的指針。 在使用下標或增量時, 會跳過整個數組, 通常只在操作數組的數組時有用。
#include<iostream>
using namespace std;
int main(){
int *arr[10];
cout<<"size of arr:"<<sizeof(arr)<<endl;
int (*p)[10];
cout<<"size of p:"<<sizeof(p)<<endl;
return 0;
}
從程序的運行結果可以證明上述說明。我們只需要按照數組和指針的用法進行操作就好,使用之前記得初始化。