為什麼不能用二級指標直接指向二維陣列

2021-08-13 09:51:44 字數 2192 閱讀 6859

先上**:

int a[2][3]=;//2行3列的int型陣列

int **pp=a;//編譯出錯,不能用二級指標直接指向二維陣列

int (*p)[3]=a;//對,p是指向一維陣列的指標,可以指向二維陣列

int *p1=a[0];//可以,p1也是一維指標,可以指向二維陣列

可以將上述的**自己上機試試。

按理說一維陣列對應一維指標,即類似於int a[3]; int *p=a;

二維陣列應該也對應於二級指標才對啊,但是其實不然。

要想解釋清楚,先想想二級指標的定義, 

要回答題目的答案,我覺得可以有兩個解釋。

我們想想,對二維陣列應該取多少次位址呢,答案是一次。 

為什麼呢,有人會問二維陣列不是對應著兩次嗎? 

給出原因: 

因為二維陣列是連續存放的。取了一次位址之後,所有元素的位址就全部知道了,只需要指標的移動就可以遍歷所有的元素了,不需要再取一次位址了。

像上面**中的二維陣列a,你只要知道了a,就可以知道a[0]的位址,(因為a=&a[0]),通過指標的移動也就是知道a[i][j]的位址了。 

舉個栗子,也就是上面的指向一維陣列的指標p,

int a[2][3]=;

int (*p)[3]=a;

//p指向了a,就是指向了a[0]為陣列名的一維陣列,陣列元素

//為1、2、3,p的移動,實現了a[0]、a[1]、a[2]這三個一維陣列之間移動。

for(int i=0;i<2;i++)

for(int

j=0;j<3;j++)

栗子2:二維陣列實際上可以看出兩個一維陣列合併成乙個一維陣列, 

所以像一開始的指標p1,int *p1=a[0];

指標p1=a[0]就是p1=&a[0][0],因為這六個元素都是連續存放的,所以p1的移動也就是實現了對這個長度為6的「一維陣列」,即對二維陣列a[2][3]的遍歷。

解釋a說明了不需要用二級指標來指向二維陣列,那是不是說明需要的時候是可以這麼用的?

不是。根本就不可以這麼用。

先說說上面的**二級指標pp的出錯的問題: 

int **pp=a;//編譯出錯,不能用二級指標直接指向二維陣列

之所以會編譯出錯,是因為

int **pp=a;//

//等價於

int **pp=&a[0];//因為a=&a[0],所以變數pp裡面放著的內容就是a[0]的位址

//又進一步等價於

int **pp=&a[0][0];//因為&a[0][0]的值和&a[0]的值一樣,都是數字1的位址

//所以最終推得 pp裝的就是a[0][0]的位址。

所以pp=&a[0][0],即*pp=1;

那麼你想想還可以對*pp再取一次位址嗎,現在*pp裡面放的是數字1,再加乙個*號的話,**pp訪問的就是實體地址為1的內容了。這是不允許的。所以會出錯。 

這裡所用的知識也還是解釋a裡面的東西。

還有一點,二級指標是指向一級指標的,那麼二級指標pp每次移動的大小就是sizeof(int *)也就是4個位元組,所以pp+1不是像二維陣列a+1那樣移動到下一行首位址,而是移動四個位元組。關於指標移動的差別也進一步說明了不可以用二級指標指向二維陣列。

那有人會提問了,int **pp=a;不行,那int **pp=&a;總可以了吧。 

答案還是不行。 

原因也還是上文講的移動的大小不一致導致的。

char *str[2]=;

char **pp;

pp=str;//這種情況是可以的。

本質原因是str[2]為一維陣列,但是它的兩個元素都是char*型的,都是位址。所以,*pp=str[0],str[0]不是像上面的那樣是個定值1,這裡的str[0]是乙個位址,是字串「hello」的首位址,所以還要再取一次位址才能訪問到字串「hello」的每個字元。這就是需要兩次取位址了。這時候用二級指標就沒有問題了。二級指標不就是取兩次位址嘛。 

況且這裡指標的移動也沒有問題,char*本來就是四個位元組的。

為什麼使用二級指標

設計乙個函式 void find1 char array,char search,char pa 要求 這個函式引數中的陣列array是以 0值為結束的字串,要求在字串array中查詢與引數search給出的字元相同的字元。如果找到,通過第三個引數 pa 返回array字串中首先碰到的字元的位址。如...

為什麼要用二級指標

在重新回顧c語言資料結構時,在實現順序表和煉表時關於指標使用的區別讓我覺得很有趣 像在順序表中實現 struct seqlist 而我們在使用順序表時,往往在main函式中直接定義 seqlist seqlist 在後面對順序表的使用中,直接傳參,比如 initlist seqlist 而在鍊錶中 ...

二級指標,指向指標的指標

test 函式的語句getmemory str,200 並沒有使str 獲得期望的記憶體,str 依舊是null,為什麼?指標傳遞 void getmemory char p,int num void test void 解釋 毛病出在函式getmemory 中,編譯器總是要為函式的每個引數製作臨時...