二維陣列來個了斷

2021-04-22 00:39:51 字數 2994 閱讀 5884

持續面臨二維陣列的問題, 每次都怕怕的. 那些指標實在讓人煩惱, 那些記憶體更讓人煩惱.

今日總結: 以供日後參考.

只寫出最常用的幾個

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...