1. 程式人生 > >陣列(一維、二維、多維)與指標的關係與區別總結

陣列(一維、二維、多維)與指標的關係與區別總結

陣列用於同種資料型別的儲存,常規的陣列選取的是一塊連續記憶體空間來儲存同種型別的資料。

1、  靜態陣列

靜態陣列是在宣告時已經確定子陣列大小的陣列,即陣列元素的個數固定不變。在編譯期間在棧中分配好記憶體的陣列,在執行期間不能改變儲存空間,執行後由系統自動釋放

陣列的宣告

int a[10]; float b[5]={};double c[]={1,2,3};

尤其注意下面這種陣列宣告是錯誤的,int num; char a[num]; 即使在前面是int num=5也是錯的,無法明確陣列的大小,導致編譯失敗,num必須是常量或常量表達式。

例如const int num=5;或者在前面對num進行巨集定義。

修改後:

2、  動態陣列

動態陣列是指在宣告時沒有確定陣列大小的陣列,即忽略圓括號中的下標;當要用它時,可隨時用ReDim語句重新指出陣列的大小。使用動態陣列的優點是可以根據使用者需要,有效利用儲存空間。最大的特點是在程式執行後才分配記憶體的陣列需要人工手動去建立和釋放。

(1)一維陣列

C語言:利用malloc()函式來宣告陣列空間 利用free()函式來釋放宣告空間

C++語言:利用new()函式來宣告陣列空間 利用delete()函式來釋放宣告空間


(2)二維陣列

在c中 


在c++中:

3、  陣列與指標

(1)一維陣列 int a[10]={};

我們需要知道的一點就是一維陣列名錶示的是儲存的首地址其次a[i]=*(a+i),a+i代表的是第i個元素的地址,等於第一個元素的地址+i*sizeof(陣列型別)。

(2)二維陣列

二維陣列可以理解為是一個特殊的一維陣列,它的每一個元素也都是一維陣列。

例:

二維陣列a[3][2]可以理解為一個特殊的一維陣列,其中每一個元素都是一個一維陣列,如a[0][2]實際包含兩個元素a[0][0]和a[0][1]。

如圖可得到以下結論:

(1)a+i指向a[i][2]: a為陣列a[3][2]的首地址,特殊的一維陣列包含3個元素a[0][2],a[1][2],a[2][2]。由一維陣列的性質“首地址+i”得到的是第i個元素的地址,所以a+i指向特殊一維陣列的第i個元素。

(2)a[i]指向a[i][0]: 特殊的一維陣列的每個元素又都是一個數組,如a[0][2]實際包含兩個元素a[0][0]和a[0][1]。a[0]相當於一維陣列名,指向首元素 a[0][0],所以a[i]指向a[i][0],a[i]+j指向a[i][j]。

從圖中看似a+i和a[i]指向的都是a[i][0],其實不然。a+i指向的是a[i],因為a[i]=*(a+i),這個比較難理解的。

a[i]的確指向的是a[i][0],但a+1取值後仍然是一個地址指向a[i][0]。

可以這樣理解,a+i指向的是特殊一維陣列的第i個元素,第i個元素還是一個一維陣列。*(a+i)直面的意思是想取出第i個元素的內容,但a+i所指空間還是個陣列,難道*(a+i)直接就能將整個陣列取出來?要知道陣列都是通過下標一個個進行訪問的,不能整體獲得。所以*(a+i)只是獲得這個陣列空間首元素的地址,這樣就可以通過下標對內容進行訪問。

最後總結一下:

對於二維陣列a[3][2],若看成3行2列的形式。

(1)a+i指向第i行,此時還沒有獲得第i行元素首地址,沒有辦法訪問其中的元素

(2)*(a+i)或a[i]指向第i行首元素,獲得第i行元素的首地址。

(3)a[i]+j指向第i行第j個元素,可以通過a[i]第i行元素的首地址訪問各個元素。關鍵是要記住a[i]=*(a+i),   a[i][j]=*(*(a+i)+j)。

同理針對三維陣列,我們同理可以得到a[i][j][k]=*( (*(*(a+i)+j))+k),甚至可以推廣到多維。

(3)一維陣列名arr與普通指標ptr的區別

1、  陣列名取地址得到的是陣列名所指元素的地址,而對指標取地址得到的是指標變數自身的地址。即對於陣列名arr而言,arr==&arr==arr[0],對於普通指標ptr,一般ptr!=&ptr;

2、  陣列名是常量指標,指標是變數指標。即陣列名不能為左值,普通指標則可以。

3、  Sizeof(arr)此時的大小不是4而是4*陣列元素的個數

Sizeof(ptr)的結果為4

同時我們需要注意一點就是,指標偏移問題

通過例子我們可以發現&arr+1實際上偏移了16個位元組,而&ptr+1只是偏移了4個位元組。

(4)二維陣列名a與指標

  雖然在數值上表現的相同,但是二維陣列名的型別是陣列陣列,即int (* arr)[3]=a;

故用int * ptr=a則會報錯,而int *ptr=a[0]=&a[0]則正確。

參考連結: