函式中的二維陣列和二級指標

2021-10-10 01:48:18 字數 2194 閱讀 8805

#include

using

namespace std;

void

func

(int

**a)

intmain()

;func((

int*

*)a)

;//強制型別轉換

cout <<

"傳遞之前a: "

<< a<

cout <<

"傳遞之前a+1:"

<< a +

1<

}

c++對函式形參實參之間匹配要求很嚴格,必須做到一一對應,如果不強制型別轉換(int **)a,編譯器就會報錯,這也證明二維陣列和二級指標存在著很明顯的區別

輸出結果為

在16進製制運算下傳遞之後的a之間相差8,而傳遞之前的a之間相差了12

筆者的機器中,指標佔8個位元組,這就說明傳遞之後的a是個普通指標

而int型別佔4個位元組,12除以4為3,正好是二維陣列a[3][3]中列的個數,說明a依舊和陣列有關係(也是個指標,因為陣列名就是個指標)

這裡說個自己總結的指標和數字相加的理解方式

c和c++中不同資料之間要想進行運算(加減乘除)必須先進行型別轉換,而在上面每乙個的加法運算中,都有一次「隱式」型別轉換,把字面常量1轉換成了表示式中a的型別,傳遞之前的a是陣列型別的指標,所以1換成對應的型別(佔12個位元組),同理傳遞之後的a為普通指標,1就換成對應的型別(佔8個位元組),這樣子就好理解為什麼同樣是指標+1,為何差值就不相同呢

那麼問題來了,函式引數傳遞成功之後,我能在函式中用a訪問陣列中的元素嗎

肯定不能,因為傳遞之後a的本質已經變了,從上面來看,常量1都被換成不同的型別了,a肯定也變了,他已經和陣列沒直接關係了

那要想訪問a中的元素也不是不可以,只要搞明白指標就行了,反正資料都存在記憶體裡,也跑不了

#include

using

namespace std;

void

func

(int

**a)

intmain()

;func((

int*

*)a)

;}

結果為:

在函式中又進行了一次強制型別轉換把a轉換成了int*型別,你可以這樣理解,我們為了把陣列傳入函式中進行了強制型別轉換轉成了(int **),那我們要在函式中使用這個陣列就要把它的型別再轉回來,而二維陣列可以用int (*a)來表示,所以我們把它強制轉換為(int *)的型別,這樣我們就可以把他當成二維指標使用了(型別轉換不改變指標所指的位址)

但使用上還是要有所注意的,拿cout << *(int*)(a+1) << endl;舉例子:括號中的a+1,因為a是普通指標(和陣列無關了),所以加1時,指標加了8個位元組,而不是12,所以不能完成一次跨行的行為,這就導致輸出為2(int為4佔位元組,8個位元組相當於2個int,從0跨越到2),而不是第二行開頭的3

可以借助理解(圖中每列的位址相同)0,1,2,3,4,5之間位址相差4個位元組,函式中的int**a的位址和第一列相同

這樣就好理解了,如果我們想一一訪問陣列裡的元素的話只需讓a先進行強制轉注意轉換成int*,(這個int*可以看成乙個int(*)[1]所以它+1只會跳過4個位元組,變成下乙個int)然後再和常量相加,再執行解引用操作

#include

using

namespace std;

void

func

(int

**a)

intmain()

;func((

int*

*)a)

;}

輸出結果為

二維陣列和二級指標

前兩天寫個程式,傳引數的時候想傳個二維陣列進去,結果悲劇了,函式寫成fun int p 原來沒有這麼寫過,以為這麼寫也是對的,結果錯了,查了些資料,做個總結。fun int p 這裡面的int p 這裡的p不是二維陣列的指標,而是指向指標的指標,即二級指標。正確的二維陣列的指標應該是 int a 2...

二級指標和二維陣列詳解

乙個函式形如 void f float p float p 其實這裡的p並不是乙個二位陣列的指標,只不過是乙個指向指標的指標 像你這樣訪問肯定是會出問題的。例如 float a 2 2 float p float a 強制將二維陣列指標轉為指向指標的指標 則此時p 0 0 p 1 1 p 2 2 p...

二維陣列 指標陣列 陣列指標 二級指標

include 指標陣列 array of pointers,即用於儲存指標的陣列,也就是陣列元素都是指標 陣列指標 a pointer to an array,即指向陣列的指標 int a 4 指標陣列 表示 陣列a中的元素都為int型指標 優先順序高於 元素表示 a i int a 4 陣列指標...