C 二維陣列作引數時和二維指標的異同

2021-08-28 15:21:01 字數 2720 閱讀 3099

二維陣列不同於一位陣列,一維陣列傳引數時只需要傳指標即可,無需指定大小。二維做引數時必須指定第二維的大小,否則編譯不過。

void lalala(int a,int m, int n)  //編譯報錯
void lalala(int a[10],int m, int n)   //編譯通過
因為對於表示式a[i][j]來說,編譯器認為它的含義是*(*(a+i)+j)。

而c++中的二維陣列的實質是一維陣列實現的,對於陣列array[m][n]來說,*(array+i)實質上是(*array + i * n),也就是說a[i][j]的位址是(a+i*n+j)如果不指定第二維的大小,編譯器便無法識別*(a+i)的運算方式,就無法定址。

void lalala(int **a,int m, int n) 

cout << "\n";

}}

這樣是能夠編譯通過的,但是當呼叫函式時,我們需要對陣列進行強制型別轉換(必須轉換為int **,因為int **與int*[10]型別不同)。

int m = 10;

int n = 10;

int array[10][10];

lalala((int **)array,m,n);

你一定覺得會執行得很完美,但事實上這樣雖然能編譯通過,但在執行得時候會出錯。

0xc0000005: 寫入位置 0xcccccccc 時發生訪問衝突!

原因仍然是,當二維陣列經過強制型別轉換後,array[i][j] 中的 *(array+i) 不知道如何計算,最後無法定址。

顯然,一定要指定二維陣列的第二維大小十分苛求,這樣的函式我們肯定不能容忍,那有什麼解決辦法呢?

void lalala(int *a,int m, int n) 

cout << "\n"; }}

int main()

我們知道,二維陣列本質是一維陣列實現的,其後申請的記憶體空間是連續的,所以可以將二維陣列強制轉換成一維指標,然後手動計算位址 (a + i*n+j) 來解決問題,因為 a[i*n+j] 和 *(a + i*n+j) 在語義上實際是一樣的。

如果非要二維指標做引數,則有兩種做法。

利用a[i][j]的語義,在函式實現中將a[i][j]手動轉換成*((int*)a + i * n + j),注意要先將二維指標**a強制轉換成(int*)a,如果只使用*a的話,在某些編譯器下,仍然會出現前面的執行時定址錯誤,記憶體無法讀取。

我們在函式裡引數寫int **a,在函式實現中依舊使用表示式a[i][j]。

void printaddress(int **a,int m, int n) 

cout << "\n";

}}

int m = 10;

int n = 10;

int **array = new int *[m]; //動態生成一組一維指標

這樣的確能夠解決問題。但是

我們看到生成的二維陣列位址並不一定連續,array[i][j]的實際定址方式是*(*(a+i)+j)

並不是我們c++自帶的二維陣列那樣*((int*)array + i * n + j)

也就是說,我們這樣動態生成的二維陣列,遇到解決方法1中的printvalue那樣的函式內部實現的手動定址方式就要gg啦。

int m = 10;

int n = 10;

int **array = new int *[m]; //動態生成一組一維指標

array[0] = new int[m*n]; //申請一段連續的二維陣列記憶體

可以看出,這樣動態生成的二維陣列,在構造上與c++自帶的二維陣列完全一致,可以看做由乙個一維陣列改造而來。只不過,它顯式地規定了每一行的行指標(在c++原生的二維陣列中並沒有這些指標),這樣array[i][j] 中(*array + i)部分的計算就不存在任何問題了。

這樣就可以在不管函式怎麼實現的情況下,對二維陣列以二維指標的形式進行動態傳參。

二維指標和二維陣列

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

二維陣列 二維陣列和指標

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

C 二維陣列作函式引數

變數在作用域裡面被宣告的是什麼型別,就當作什麼型別來用。1 引數是二維陣列,但是要指定第二維的維數。int array 10 10 函式宣告 void fuc int a 10 函式呼叫 fuc array 在函式fuc中,a是二維陣列。使用a i j 形式來訪問陣列中元素。2 引數使用一維指標陣列...