持續面臨二維陣列的問題, 每次都怕怕的. 那些指標實在讓人煩惱, 那些記憶體更讓人煩惱.
今日總結: 以供日後參考.
只寫出最常用的幾個
1: 在棧上 分配 int a[m][n].
缺點, m, n必須為已知
函式引數呼叫
fun( int a[n], int dims_i, int dims_j )
2: 動態分配-使用stl
極力推薦!!! 雖然, 這個方法會造成記憶體不連續, 但是, 比起**的優美, 呼叫的直觀, 也不用自己管理記憶體, 缺點可以忽略不計!!!
int m=3;
int n = 3;
vector< vector > myvec( m, vector(n) );
for ( int i=0; i
}vectorint> > a;
a.resize(m); //m行
for(int i = 1; i < n; i++) //
3: 動態分配, 自己管理記憶體
由於本質上, 動態實現2維陣列的話, 需要多申請點記憶體. 也就是存放一維陣列指標的記憶體.
下面的方法, 把 "存放一維陣列指標的記憶體" indexsize 和 存放資料的記憶體 h*rowsize 放在了一起. 實在巧妙. 這樣,
釋放記憶體時, 一句delete搞定.
void** malloc2d(int w, int h, int size)
引數w,h是所申請二維陣列的列數和行數,size是陣列單元的位元組數。比如,申請乙個4*5的int型的二維陣列,使用:
int **m = (int **) malloc2d(5, 5, sizeof(int));
直接使用m[x][y]即可以引用x行y列的值。
退回時,直接使用free(m)即可。
參考: http://blog.csdn.net/hanbf/archive/2007/08/31/1767645.aspx
下面對程式設計中常見的, 通過函式指標傳遞二維陣列位址後,
如何在函式內部訪問陣列元素. 這裡進行一下集中討論.
1)如果原始資料是 本質上一維的, 占用空間僅僅包含原始資料大小, 不含對行指標的儲存空間.
則, eg int a[2][2]; // :在棧上分配的記憶體. sizeof(a) == 2*2*sizeof(int)
只可以按照 一維的本質來訪問陣列元素.
void test3( int** a, int dim_i, int dim_j )
}return;
}
2: 如果申請的記憶體中不僅包含資料佔空間, 也包含了行指標佔的空間. 那麼, 是可以通過來訪問的.
見下面函式的 test4
void test2( int a[2], int dim_i, int dim_j )
// :適用於本質上不含行指標 的二維陣列.
// :eg 1 在棧上分類的二維陣列, 或不含行指標的 int a[2][2]
// :eg 2 int ** pa =(int**)malloc(sizeof(int)*2*2) . 兩行兩列
void test3( int** a, int dim_i, int dim_j )
}return;
}// :適用於 含有行指標資料的 二維陣列
// :eg malloc2d
void test4( int** a, int dim_i, int dim_j )
}return;
}void** malloc2d(int w, int h, int size)
int main()
, };
test3( (int**)a, 2, 2 );
// 第三種方式
int m=3;
int n = 3;
vector< vector > myvec( m, vector(n) );
for ( int i=0; i}}
**水木清華
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];
delete ga;
缺點:非連續儲存,程式煩瑣,ga為a**型別
優點:呼叫直觀,n可以不是已知
3. a* ga = new a[m*n];
...delete ga;
缺點:呼叫不夠直觀
優點:連續儲存,n可以不是已知
4. vector> ga;
ga.resize(m); //這三行可用可不用
for(int i = 1; i < n; i++) //
ga[i].resize(n); //
...缺點:非連續儲存,除錯不夠方便,編譯速度下降,程式膨脹(實際速度差別不大)
優點:呼叫直觀,自動析構與釋放記憶體,可以呼叫stl相關函式,動態增長
5. vectorga;
ga.resize(m*n);
方法3,4的結合
6. 2的改進版(penrose提供,在此感謝)
a** ga = new a*[m];
ga[0] = new a[m*n];
for(int i = 1; i < m; i++)
ga[i] = ga[i-1]+n;
...delete ga[0];
delete ga;
缺點:程式煩瑣,ga為a**型別
優點:連續儲存,呼叫直觀,n可以不是已知
二維陣列 二維陣列和指標
include using namespace std int main 如上面這段程式所示,通過取位址符 指標 p 獲得了變數 a 的位址,那麼解引用符 就可以從 p 中得到變數 a 的值。也就是說,p a和 p a是等價的。p 是變數 a 的位址,從 p 中就可以取出 a 的值。反之,能從 p ...
陣列 二維陣列
一組相同型別的資料組合,是一種引用型別。陣列名稱不是固定的,與其存放的資料的型別有關。如 存放int型別的資料,陣列名稱 int 存放字串資料,陣列名稱 string 存放scanner型別的資料,陣列名稱 scanner陣列中的每個資料,都是這個陣列的元素。1 宣告 元素型別 變數名 元素型別 變...
陣列 二維陣列
陣列,從名字很簡單看出就是數字組合,一堆數 一堆元素 在一起。然後看一下怎麼定義,怎麼初始化。陣列的動態初始化 初始化之後每個元素的儲存內容為其對應資料型別的預設值。資料型別 陣列名 new 陣列型別 大小 int arr new int 5 資料型別 陣列名 new 陣列型別 大小 int arr...