有兩種直觀的方式來定義二維陣列,可以理解成直接定義和間接定義:
直接定義 :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 等三個元...