C 二維陣列及其指標

2021-10-11 21:09:33 字數 4284 閱讀 9574

用指標的形式傳遞二維陣列

後記假設我打算建立乙個二維陣列,並建立乙個指標用於儲存這個二維陣列的位址,對於如下兩種方法,

int arr[2]

[3]=

;int

**ptr = arr;

int arr[2]

[3]=

;int

(*ptr)[3

]= arr;

使用第一種方法時,編譯器會報錯如下:int (*)[3] 型指標不能賦給 int ** 型指標,這是因為對於建立的二維陣列arr[2][3],當編譯器去編譯int arr[2][3]指令的時候,記憶體中實際的分配情況如下:

由於arr是int型陣列,每個記憶體塊的大小為 4個位元組

假設arr[0][0]的位址為1000,那麼對於arr[0][i],當i加1時,位址也會相應增加 4個位元組,也就是1004

由此類推:

陣列下標

實際位址

陣列下標

實際位址

陣列下標

實際位址

arr[0][0]

1000

arr[0][1]

1004

arr[0][2]

1008

arr[1][0]

1012

arr[1][1]

1016

arr[1][2]

1020

同時,對於arr[2][3],可以理解為含有兩個各包含了三個int元素的一維陣列的陣列, 這樣看來:

arr[0]實際上代表著這個二維陣列中所儲存的第乙個一維陣列;

arr[1]實際上代表著這個二維陣列中所儲存的第二個一維陣列。

若是按著這個思路繼續理解下去,arr[0]代表著乙個一維陣列,而arr[0][i]又可以從這個陣列中取值,那麼是不是可以這樣理解:arr[0]為乙個指向這個一維陣列的指標呢?如下的**可以對這個猜想進行驗證:

#include

intmain()

;int

*ptr_0 = arr[0]

;//建立乙個指向第乙個一維陣列的指標

//測試輸出

for(

int i =

0; i <

3; i++

)return0;

}

可以看到輸出的內容為

即第乙個陣列內的三個元素均被正確地輸出了,至此,我們可以得知arr[i]實際上是乙個int型指標,它的每次步進都會使其在記憶體中的位置移動 4個位元組。

那麼,進一步地思考,如果arr[i]是乙個指向arr[i][0]位置的int型指標,而arr[i]又是存放在arr這個陣列中的值,於是可以推測arr即是指向arr[0]位置的指標。

把上面的猜想聯絡起來可以得到arr是乙個指向指標的指標,於是我們自然而然地就會想到arr應該是int **型的值,但回到開頭的**示例,這個想法顯然是錯誤的,這是不妨思考乙個問題,如果arrint **型值,那麼當我對arr進行一次自增運算之後,它應該指向**呢?

顯然,我們並不能知道它該指向**,因為我們只是定義了arr,而沒有告知每一次步進所需要移動的記憶體長度

而事實上,每一次步進需要移動的記憶體長度為3 * sizeof(int),即整乙個一維陣列的記憶體長度,於是我們可以這樣告訴編譯器:

int arr[2]

[3]=

;int

(*ptr)[3

]= arr;

在這樣的操作下,我們就用int (*ptr)[3] = arr這個式子告訴了編譯器,ptr是乙個指標,它指向的是含有三個int型元素的一維陣列。

#include

#include

intmain()

//刪除動態二維陣列

for(

int i =

0; i < line; i++

)free

(arr)

;return0;

}

這裡就出現了和上文不一樣的現象:arr變成了int **型,為什麼呢?這要從**中的記憶體分配步驟來看:

首先,定義了int **arr用malloc函式開闢了儲存兩個int *型值的記憶體,並將這個記憶體的位址以int **型值賦給arr用malloc函式開闢儲存三個int型值的記憶體,重複兩次,分別將記憶體的位址以int *型值賦給arr[0]arr[1]

也就是說,arr[0]arr[1]是連續的,它們都是儲存int *型別的值的記憶體,而指標arr又被定義為int **型, 因此對於arr來說,arr + 1可以正確地指向arr[1]

同時,又因為每個一維陣列都是通過呼叫一次malloc函式來分配的,因此它們的記憶體同樣也是連續的,通過*arr得到arr[0][0]的位址,對*arr進行步進,同樣也能得到預期值。

簡略地介紹如何通過指標的形式傳遞固定長度陣列和動態陣列

對於固定長度陣列,通過前文的介紹,需要告訴被調函式它所接收指標的步進長度(即一維陣列的長度),**例項如下:

#include

intsum

(int(*

)[2]

,int);

intmain()

;printf

("%d"

,sum

(arr,3)

);return0;

}int

sum(

int(

*arr)[2

],int line)

}return sum;

}

這是乙個簡單地將陣列內所有元素加和的函式,我們可以看到,在主調函式內傳遞時不需要宣告指標的型別,而在被調函式接收時則需要具體表明arrint (*)[2]型別。

下面,同樣用這個例子來展示動態陣列的呼叫:

#include

#include

intsum

(int**

,int

,int);

intmain()

printf

("%d"

,sum

(arr, line, column));

//刪除動態二維陣列

for(

int i =

0; i < line; i++

)free

(arr)

;return0;

}int

sum(

int*

* arr,

int line,

int column)

}return sum;

}

與固定長度陣列不同的是,由於被調函式無法得知陣列的列數,因此還需要多傳遞乙個列數的引數。

第一次寫csdn的部落格,希望有錯誤的話能幫忙指正一下哈!

三連給乙個好嗎xdm

二維陣列的指標及其指標變數

1 二維陣列的指標 有定義語句 int a 3 4 從二維陣列角度看,陣列名a 代表陣列的起始位址,是乙個以行為單位進行控制的行指標,由一維陣列構成的一維陣列就是二維陣列,a i 是行指標值,指向二維陣列的第i 行。a i 是列指標值,指向第i 行第0 列。a i 陣列元素a i 0 的值。用a 作...

c 二維陣列指標

定義指標指向二維陣列 為了方便根據使用者輸入動態定義二維陣列的行和列,引入變數rowsnum 行 colsnum 列 以定義 行 列的二維陣列為例,int rowsnum 4 int colsnum 5 float a new float rowsnum for int i 0 i rowsnum ...

C 二維陣列指標

概括的說,指標其實就是可變陣列的首位址,說是可變陣列,是 指其包含內容的數量的可變的,並且是可動態申請和釋放的,從而充 分節約寶貴的記憶體資源。我一向喜歡一維陣列,除非萬不得已,我一 般是不用二維陣列的,多維的則更是很少涉足了。因為一維簡單,容 易理解,而用指標指向的多維陣列就具有相當的複雜性了,也...