淺挖二維陣列指標

2021-10-06 10:57:22 字數 3892 閱讀 1354

假設有陣列int a=, 我們可是通過一系列的方式訪問它

定義:int *p; p=a;

則p指向了a。此時我們姑且認為a與p等價。

需求使用 a

使用 p

訪問陣列第乙個元素

a[0]

*p同上

*ap[0]

訪問陣列第二個元素

a[1]

*(p+1)

同上*(a+1)

p[1]

將上述陣列轉化為圖,即下圖所示(這裡1是指int的單位大小):

所以對於使用指標來講,*(陣列元素位址) 即可訪問陣列對應元素。

可以清晰的看出a 是陣列a 的位址; 也是陣列a 第乙個元素的位址。所以該位址有雙重的身份,這雙重身份可以被計算機解讀,取決於陣列在c語言中的特殊結構設定。兩個身份並不矛盾,可以理解為同一身份。

為了更清楚的理解,我們寫了乙個小例項,定義了乙個陣列a,用指標 p 來指向 a 執行結果如下:

int

*p=a;

//runing...結果:

&a:6487376 a:

6487376

*a:1

&p:6487576 p:

6487376

*p:1

&a 取到的是陣列a 的陣列位址(第一重身份), a 是陣列第乙個元素位址(第二重身份),均為:6487376,兩個身份一致,至於不同的解析取決於 c 的陣列結構定義。

而指標 p 來講,p 有自己的位址(並且有自己的 大小 和 匯流排 有關),p指向的是(!!可能是!!)陣列的位址(不排除是第乙個元素的位址的可能),(當然這也不重要,就看官方是怎麼詮釋而已,不影響理解)。

故名思意,該形式首先是個陣列,但是陣列的每個元素都是指標。

設有陣列: int b[4][3] = ;

1.我們可以將它理解為兩個巢狀的陣列,首先第一陣列即是b[4], b[4]的每乙個元素都是乙個長度為[3]的陣列首位址。

2.首先**b[4],可以將b[4] 理解為一維陣列,類似上面所述。所以b 是該陣列的b[4] 的位址; 也是陣列b[4] 第乙個元素的位址,該元素可以通過兩種書寫方式取得:b[0]、*b 。12

343.在1.中我們假設了,b[4]的每乙個元素都是巢狀陣列中的子陣列首位址,設第乙個子陣列為b1[3], 一維陣列,首位址(第乙個元素位址)為b1, 那麼2.中我們取得的 b[0] (或*b),即是b1。(見下圖,僅展示前b[3])

4. 欲取得b1中的元素(設b1中第乙個元素),我們可以通過,b1[0]、*b1, 兩種寫法。同理代入b,完整的寫法可以推出:b[0][0] 、*(b[0])、(*b)[0] 、**b。

5. 經過驗證,4.中所述寫法完全可以編譯執行,完美取得b[4][3] 中的第乙個元素。所以基本驗證了我們的假設:b矩陣屬於乙個巢狀陣列。b是矩陣首位址、是矩陣第乙個子陣列首位址,但是矩陣首位址(矩陣第乙個元素位址)中存放的是 矩陣第乙個子陣列首位址(子陣列第乙個元素位址),只有矩陣的子陣列中,才存放著具體的元素。

6. 俄羅斯套娃。在b是[4][3], 矩陣的前提下,設b的位址(&b)為:6487424、b存放的位址是:6487424、取得b存放的位址中的元素(b)我們發現竟然是:6487424, 但是當在一次取b位址中的元素(**b)我們發現卻是 1 。

即是:&b == b ,b == *b , 但是 *(*b) != b 。乙個記憶體位置上 存放著 該位置的位址

首先從上一章節一維陣列中,我們知道 &b == b 是對陣列結構的特殊詮釋。但 b == *b ,就可能是 c 語言中 ,對二維陣列的不同的額外特殊詮釋。只有當對位址多次取值,才能真正取得位址上的元素 1 。

7. 我們甚至可以將二維陣列直接利用指標的方式轉化為一維陣列,p=&b[0][0];語句相當簡單,就是直接指向矩陣的第乙個元素。

8. 我們還可以講:指向二維陣列的指標的定義方式,是定義乙個指向第一層巢狀陣列(在例子中即是指向 b[4])的指標。陣列很重要的屬性是型別,陣列型別決定了為每個元素分配記憶體的大小,第一層巢狀陣列而言,矩陣b[4][3] 的列向量就顯得尤為重要,因為列數表明第一層巢狀陣列每個元素的大小(sizeof( type x ) * 列數)。

9. 那麼模擬一維陣列指標的定義:type * p = a;

10.  推出二維陣列指標的定義為:type (*q)[m] = b, 其中type b[m] ;

&b is:

6487424

b is:

6487424

*b is:

6487424

**b is:1|

6487424

|6487428

|6487432

|6487436

|6487440

|6487444

|6487448

|6487452

|6487456

|6487460

|6487464

|6487468

int(

*l)[3]

=b; l is:

:6487424

*l is:

6487424

*(l+1)

:6487436

*(l+2)

:6487448

*(l+2)

[1]:

10**l is:1*

*(l+1)

:4**

(l+2):

7*(*

(l+2)+

1):8

驗證其他寫法:

*(b[0]

):1(

*b)[0]

:1轉化為一維陣列:

p=&b[0]

[0];

p is:

6487424

*p is:1*

(p+1):

2*(p+2):

3*(p+5):

6------

----

----

----

----

----

----

--process exited after 128.5 seconds with return value 0

請按任意鍵繼續.

..

最後補充一下,大佬的

4.指向二維陣列的指標陣列:

type (*parray[num])[column];

其中column為二維陣列的維度。num為指標的個數,定義時如果直接賦值的話,可以不指定num的大小。

例如定義乙個指標arr1的指標陣列,陣列的大小為5:

int (*parr1[5])[2];

parr1[0]=arr1;

printf("%d",parr1[0][2][1]); // 輸出為:6

另外乙個例子:

static

const

char _keyboard_lower[4]

[10]=

,,,,

};static

const

char _keyboard_upper[4]

[10]=

,,,,

};static

const

char _keyboard_num[4]

[10]=

,,,,

};static

const

char

(*_keyboard_char)

[10]=

;

二維陣列 二維陣列和指標

include using namespace std int main 如上面這段程式所示,通過取位址符 指標 p 獲得了變數 a 的位址,那麼解引用符 就可以從 p 中得到變數 a 的值。也就是說,p a和 p a是等價的。p 是變數 a 的位址,從 p 中就可以取出 a 的值。反之,能從 p ...

二維陣列與二維指標

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

二維指標和二維陣列

二維指標和二維陣列有三種形式 1,type ptr 2,type ptr或者type prt 3,type prt 三種形式意思相近,也有區別。首先三種形式都能表示二維的資料結構。1,type ptr 表示乙個指向指標的指標 但是在一開始宣告的時候 type ptr ptr到底指向幾個指標是不知道的...