最近專案中用到二維陣列,沒想到用的時候出現了問題,找了好一會才發現原因。看來基本功還不紮實,有必要寫篇部落格好好理解下這二維陣列。
當你知道建立的是幾行幾列陣列時,在c++ 中你可以用new
一條語句就能建立成相應的二維陣列。
int **p = new int* [5];
但是在c語言中標準的庫只有 malloc free是分配記憶體的,怎麼分配呢?言歸正傳,下面介紹3中方法
1 利用二級指標申請乙個二維陣列
#include#includeint main()
printf("\n");
}free(arr); //釋放完成可以將指標指向null,即 a = null;
return 0;
}
該方法我個人覺得不推薦,其實就是一維陣列,只是你需要你自己計算下標,那塊記憶體代表幾行幾列。我用二維陣列,自然是希望方便的根據下標知道是第幾行幾列。
先談談我專案中碰到的問題
#include #include void display(int ** a,int n,int m){
int i,j;
for(i=0;i你能發現上面**的問題嗎? 當時大概我就是這麼用的,但是你執行後,就知道是會直接段錯誤的。
那麼問題出在**呢?
int arrys[3][2] 作為引數 其實是作為 int (*)[2] arrys 陣列指標傳入進去的。 但是你引數是 int ** 本質就是指標陣列
而 display((int **)arrys,3,2); 強轉 其實就是把3 * 2二維陣列的首位址指標傳進去了。
簡單的說 陣列指標 指標指向的是一塊元素為2的連續的位址,而強轉後其實就是把首位址帶進去了,指標指向了元素為3 * 2 的元素位址 。
最終函式中void display(int ** a,int n,int m) 其實二維 ** 已經失去了意義,你輸出下 a[0]~a[6] 的值其實就是 1 ~ 6 。
反而你想輸出a[0][0] 的值 壓根就找到不這塊位址的值
那麼怎麼解決呢
傳參方法 1
其實你知道 int ** 其實是對應的指標陣列,那麼方案一,引數換成指標陣列就行了。如下
#include #include void display(int ** a,int n,int m){
int i,j;
for(i=0;i結果如下
int * a[3] 就是乙個指標陣列 本質是陣列 陣列a中三個元素,分別儲存了三個指標,即指向每一行的首位址。
作業系統liunx 32位的 ,結合上圖結果列印你再分析下 可以發現a 到 a[0] 間 有12byte, 其實就是a[3] 陣列 中指標元素的位址,而元素的內容又儲存的是每一行的首位址。
傳參方法 2
再看方法2,其實你會發現把引數 int ** 換成了 陣列指標然後就行了
void display2(int a[2],int n,int m){
int i,j;
for(i=0;i列印結果如下
傳參方法 3
#include #include void display(int ** a,int n,int m){
int i,j;
for(i=0;i列印結果如下:
從列印結果你也可以發現,驗證了動態建立中提到每行之間的記憶體不是連續的。 3個int 按理說應該是12 byte 。 但是列印的行與行之間有16個位元組。
二維陣列引數傳參問題,其實你看了方案1到方案3,本質上傳參總結出一點,就是函式的引數是指標陣列你就給它傳入指標陣列,是陣列指標你就給它傳入陣列指標。 因此陣列指標和指標陣列的概念你一定要了解。
C 中二維陣列作為函式引數
變數在作用域裡面被宣告的是什麼型別,就當作什麼型別來用。1 引數是二維陣列,但是要指定第二維的維數。int array 10 10 函式宣告 void fuc int a 10 函式呼叫 fuc array 在函式fuc中,a是二維陣列。使用a i j 形式來訪問陣列中元素。2 引數使用一維指標陣列...
C 動態建立和刪除二維陣列
1.a ga n new a m n delete ga 缺點 n必須是已知 優點 呼叫直觀,連續儲存,程式簡潔 經過測試,析構函式能正確呼叫 2.a ga new a m for int i 0 i m i ga i new a n for int i 0 i m i delete ga i de...
動態建立和釋放二維陣列
c動態建立和釋放二維陣列 include include define row 5 define col 4 main int i int arr arr int malloc row sizeof int for i 0 i使用calloc申請記憶體時,記憶體會清0,而malloc並不進行這項工作...