二維陣列 記憶體布局與指標

2021-06-26 16:02:00 字數 1490 閱讀 4427

有兩種直觀的方式來定義二維陣列,可以理解成直接定義和間接定義:

直接定義 :char ch[2][3];

間接定義: typedef char p[3] ;  p ch[2];

間接定義首先把char [3]當成一種型別(一維陣列),並給這個型別起了個別名p,然後定義了乙個p的陣列,換言之,間接定義將二維陣列理解成了若干個一維陣列,通過這兩種方式定義的二維陣列(gcc 4.8.1)的記憶體布局是相同的,因此二維資料實際上就是由若干個一維陣列組成,下面通過乙個簡單的程式來觀察 ch 的記憶體布局:

char ch[2][3];

printf("%p\n%p\n%p\n%p\n",&ch[0][0],&ch[0][2],&ch[1][0],&ch[1][2]);

輸出結果如下:

addr of ch[0][0] : 0xbf9efb56

addr of ch[0][2] : 0xbf9efb58

addr of ch[1][0] : 0xbf9efb59

addr of ch[1][2] : 0xbf9efb5b

可以看到二維陣列的記憶體是線性布局的,ch的第乙個一維陣列占用的記憶體為0xbf9efb56~0xbf9efb58,第二個一維陣列占用緊隨其後的記憶體:0xbf9efb59~0xbf9efb5b。所以如果對第乙個子陣列發生了寫越界,越界的部分就會汙染第二個子陣列裡的內容,至於會不會對 ch 以外的內容造成汙染,那取決於越界的多少。現在我們來考慮第二個問題:既然p是乙個型別(大小為3的一維char陣列),那麼我們就可以建立乙個指向p的指標:p *p; 那麼p+1比p大多少呢:答案是:3 = 3*sizeof(char)。在現實生活中我們常常看到另外一種寫法:char (*p)[3],這個p其實就是前面提到的p,p指向了第乙個一維陣列,p+1就指向了第二個一維陣列,所以用p[i][j]就可以訪問陣列的第(i , j)個元素:(p[1] 等價於 p+1),我們可以看一下p和p[0]的型別:

char (*p)[3];

cout<

type of p  :  pa3_c

type of p[0]  :  a3_c

所以雖然p是指向一維陣列的指標,但是p[0]已經是乙個int陣列了,所以p[0][j]可以正確訪問陣列元素(p[0][j] 等價於p[0]+j),此時p[0][1]只比p[0][0]大1。下面我們看一下在傳遞二維陣列給函式時發生了什麼:

void fun(char ch[3])

輸出結果如下:

q 本質上還是個指標,是個變數,它自身位於棧區,但是它的內容是某個二維陣列的位址,換言之,它的內容與 ch 等價, 但是 q 不是 ch, 這就是編譯器對待指標形式的陣列與 直接形式的陣列的不同之處, q 作為乙個變數,自身也要存在記憶體的某個位置,而符號「q」就是這個位置的代號,而 ch 直接就是某塊記憶體的首位址的代號。

二維陣列與二維指標

1.二維陣列的儲存是線性的,可以通過一維指標的方式訪問。如一下 int map 5 5 int mapd map 0 0 則 map i j mapd i 5 j 而利用二維陣列線性儲存的特性,可以將二維陣列當作一維指標方便的在函式之間傳遞 如 將乙個二維陣列賦值給乙個動態二維陣列,引數設定為一維指...

二維陣列與二維指標

一.指標與二維陣列 以martix 3 4 為例 1.二維陣列的本質 int martix 3 4 int martix 3 4 int 4 martix 3 令int 4 為type,type martix 3 為含有三個元素的陣列,每乙個元素型別為int 4 int 4 是乙個擁有4個int型別...

二維陣列與指標

1 二維陣列和陣列元素的位址若有以下定義 int p,a 3 4 注意此處的int,定義為2位元組長度大小 1 二維陣列a由若干個一維陣列組成,在c語言 中定義的二維陣列實際上是乙個一維陣列,這個一維陣列的每乙個成員又是乙個一維陣列。如以上定義的a陣列,則可視a陣列由a 0 a 1 a 2 等三個元...