這是另一個經常被問到的主題。
- 如何建立二維/三維陣列?
當我開始處理多維陣列時,發現很難找到我想要的答案。所以我將釋出一些資訊,希望能幫助到其他人。我將介紹兩種主要的方法(Vector vs 指標)。
基於 Vector 的多維陣列 Vector 是一個 STL 容器,允許您在其中儲存幾乎任何東西。正確使用時,它們是非常強大的容器。
它們提供了一個額外的優勢,那就是當它們離開作用域時,它們會自動釋放所佔用的記憶體。這意味著儲存在 vector 中的物件不需要被釋放(但指向物件的指標需要)。
您還可以使用 vector 來處理動態多維陣列。例如,如果您只分配了第一維,然後使用 .push_back() 向第二維新增記錄,那麼它就不再是網格,而是一個具有動態大小的第二維的陣列(就像一條街道,每棟建築有不同的樓層數)。使用指標也可以實現這種功能,但難度要大得多。
使用 vector 的簡單二維陣列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
#include <vector>
using std::vector;
#define HEIGHT 5
#define WIDTH 3
int main() {
vector<vector<double> > array2D;
// Set up sizes. (HEIGHT x WIDTH)
array2D.resize(HEIGHT);
for (int i = 0; i < HEIGHT; ++i)
array2D<i>.resize(WIDTH);
// Put some values in
array2D[1][2] = 6.0;
array2D[3][1] = 5.5;
return 0;
}
|
使用 vector 的三維陣列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
#include <vector>
using std::vector;
#define HEIGHT 5
#define WIDTH 3
#define DEPTH 7
int main() {
vector<vector<vector<double> > > array3D;
// Set up sizes. (HEIGHT x WIDTH)
array3D.resize(HEIGHT);
for (int i = 0; i < HEIGHT; ++i) {
array3D<i>.resize(WIDTH);
for (int j = 0; j < WIDTH; ++j)
array3D<i>[j].resize(DEPTH);
}
// Put some values in
array3D[1][2][5] = 6.0;
array3D[3][1][4] = 5.5;
return 0;
}
|
基於指標的多維陣列 基於指標的多維陣列為您提供了更底層的物件訪問許可權。其好處是可以提高速度,並且您可以對其應用自定義最佳化。
注意:您可以透過將兩個維度組合成一個維度(HEIGHTxWIDTH)來最佳化這一點。我將省略這方面的討論,因為這是一個更高階的話題,適合已經熟悉該主題的人。
一個簡單的二維陣列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
#define HEIGHT 5
#define WIDTH 3
int main() {
double **p2DArray;
// Allocate memory
p2DArray = new double*[HEIGHT];
for (int i = 0; i < HEIGHT; ++i)
p2DArray<i> = new double[WIDTH];
// Assign values
p2DArray[0][0] = 3.6;
p2DArray[1][2] = 4.0;
// De-Allocate memory to prevent memory leak
for (int i = 0; i < HEIGHT; ++i)
delete [] p2DArray<i>;
delete [] p2DArray;
return 0;
}
|
一個三維陣列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
#define HEIGHT 5
#define WIDTH 3
#define DEPTH 7
int main() {
double ***p2DArray;
// Allocate memory
p2DArray = new double**[HEIGHT];
for (int i = 0; i < HEIGHT; ++i) {
p2DArray<i> = new double*[WIDTH];
for (int j = 0; j < WIDTH; ++j)
p2DArray<i>[j] = new double[DEPTH];
}
// Assign values
p2DArray[0][0][0] = 3.6;
p2DArray[1][2][4] = 4.0;
// De-Allocate memory to prevent memory leak
for (int i = 0; i < HEIGHT; ++i) {
for (int j = 0; j < WIDTH; ++j)
delete [] p2DArray<i>[j];
delete [] p2DArray<i>;
}
delete [] p2DArray;
return 0;
}
|
最後一點需要注意。當使用自定義物件型別建立動態陣列時,您不能過載建構函式。ISO 標準禁止這樣做,您必須稍後初始化物件的值。分配到陣列中的所有物件都必須使用預設建構函式。
上面的程式碼片段在 Windows 和 Linux 上都可以毫無問題地編譯。
建議 除非您的應用程式有極端的需求來進行高度最佳化,並且您對 C++ 記憶體管理非常精通,否則您應該使用基於 vector 的方法。這種方法更容易管理,尤其是當您剛開始學習 C++ 時。
您可以透過指標傳遞它們。
例如
void doSomethingWith2D(double **Array);
或
void doSomethingWith2D(vector<vector<double> > &Array);