[英]Pointer-to-pointer dynamic two-dimensional array
這個網站上的第一個計時器,所以這里..
我是 C++ 的新手,我目前正在閱讀“使用 DS Malik 的 C++ 第 2 版的數據結構”一書。
在書中 Malik 提供了兩種創建動態二維數組的方法。 在第一種方法中,您將變量聲明為指針數組,其中每個指針的類型為 integer。 前任。
int *board[4];
..然后使用 for 循環創建“列”,同時將指針數組用作“行”。
第二種方法,你使用一個指針指向一個指針。
int **board;
board = new int* [10];
等等
我的問題是:哪種方法更好? ** 方法對我來說更容易可視化,但第一種方法可以以幾乎相同的方式使用。 這兩種方法都可以用來制作動態二維 arrays。
編輯:上面的帖子不夠清楚。 這是我嘗試過的一些代碼:
int row, col;
cout << "Enter row size:";
cin >> row;
cout << "\ncol:";
cin >> col;
int *p_board[row];
for (int i=0; i < row; i++)
p_board[i] = new int[col];
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
p_board[i][j] = j;
cout << p_board[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
int **p_p_board;
p_p_board = new int* [row];
for (int i=0; i < row; i++)
p_p_board[i] = new int[col];
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
p_p_board[i][j] = j;
cout << p_p_board[i][j] << " ";
}
cout << endl;
}
第一種方法不能用於創建動態 2D數組,因為通過執行以下操作:
int *board[4];
你基本上在堆棧上分配了一個4個指向int
的數組。 因此,如果現在使用動態數組填充這4個指針中的每一個:
for (int i = 0; i < 4; ++i) {
board[i] = new int[10];
}
你最終得到的是具有靜態行數(在這種情況下為4)和動態列數(在這種情況下為10)的2D數組。 因此它不是完全動態的,因為當您在堆棧上分配數組時,您應該指定一個常量大小 ,即在編譯時已知。 動態數組被稱為動態的 ,因為它的大小是沒有必要在編譯時是已知的,而是可以通過在運行時一些變量來確定。
當你這樣做時:
int *board[4];
要么:
const int x = 4; // <--- `const` qualifier is absolutely needed in this case!
int *board[x];
你提供一個在編譯時已知的常量(在這種情況下是4或x
),這樣編譯器現在可以為你的數組預先分配這個內存,當你的程序被加載到內存中時,它已經擁有了這個內存量。 board
數組,這就是為什么它被稱為靜態 ,即因為大小是硬編碼的並且不能動態地改變 (在運行時)。
另一方面,當你這樣做時:
int **board;
board = new int*[10];
要么:
int x = 10; // <--- Notice that it does not have to be `const` anymore!
int **board;
board = new int*[x];
編譯器不知道內存board
陣列需要多少,因此它不預先分配任何東西。 但是當你啟動你的程序時,數組的大小將由x
變量的值決定(在運行時),並且board
數組的相應空間將分配在所謂的堆上 - 所有程序在你的所有程序上運行的內存區域計算機可以預先分配未知 (在編譯時)數量的內存供個人使用。
因此,要真正創建動態2D陣列,您必須使用第二種方法:
int **board;
board = new int*[10]; // dynamic array (size 10) of pointers to int
for (int i = 0; i < 10; ++i) {
board[i] = new int[10];
// each i-th pointer is now pointing to dynamic array (size 10) of actual int values
}
我們剛剛創建了一個10×10維的方形2D數組。 要遍歷它並使用實際值填充它,例如1,我們可以使用嵌套循環:
for (int i = 0; i < 10; ++i) { // for each row
for (int j = 0; j < 10; ++j) { // for each column
board[i][j] = 1;
}
}
您為第二種方法描述的內容僅為您提供一維數組:
int *board = new int[10];
這只是分配一個包含10個元素的數組。 也許你的意思是這樣的:
int **board = new int*[4];
for (int i = 0; i < 4; i++) {
board[i] = new int[10];
}
在這種情況下,我們分配4個int*
s然后使每個指向動態分配的10個int
的數組。
所以現在我們將它與int* board[4];
進行比較int* board[4];
。 主要區別在於,當您使用這樣的數組時,必須在編譯時知道“行”的數量。 那是因為數組必須具有編譯時固定大小。 如果您想要返回這個int*
s數組,也可能會遇到問題,因為數組將在其范圍的末尾被銷毀。
行和列都是動態分配的方法需要更復雜的措施來避免內存泄漏。 你必須像這樣釋放內存:
for (int i = 0; i < 4; i++) {
delete[] board[i];
}
delete[] board;
我必須建議使用標准容器。 您可能希望使用std::array<int, std::array<int, 10> 4>
或者std::vector<std::vector<int>>
,您可以將其初始化為適當的大小。
在這兩種情況下,您的內部維度可以動態指定(即從變量中獲取),但差異在外部維度中。
這個問題基本上等同於以下內容:
是
int* x = new int[4];
比int x[4]
“更好”?
答案是:“ 不 ,除非你需要動態選擇那個數組維度。”
這段代碼適用於外部庫的很少要求,並顯示了int **array
的基本用法。
這個答案表明每個數組都是動態調整大小的,以及如何將動態大小的葉子數組分配到動態大小的分支數組中。
該程序以下列格式從STDIN獲取參數:
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
下面的程序代碼......
#include <iostream>
int main()
{
int **array_of_arrays;
int num_arrays, num_queries;
num_arrays = num_queries = 0;
std::cin >> num_arrays >> num_queries;
//std::cout << num_arrays << " " << num_queries;
//Process the Arrays
array_of_arrays = new int*[num_arrays];
int size_current_array = 0;
for (int i = 0; i < num_arrays; i++)
{
std::cin >> size_current_array;
int *tmp_array = new int[size_current_array];
for (int j = 0; j < size_current_array; j++)
{
int tmp = 0;
std::cin >> tmp;
tmp_array[j] = tmp;
}
array_of_arrays[i] = tmp_array;
}
//Process the Queries
int x, y;
x = y = 0;
for (int q = 0; q < num_queries; q++)
{
std::cin >> x >> y;
//std::cout << "Current x & y: " << x << ", " << y << "\n";
std::cout << array_of_arrays[x][y] << "\n";
}
return 0;
}
這是一個非常簡單的int main
實現,僅依賴於std::cin
和std::cout
。 Barebones,但足以說明如何使用簡單的多維數組。
這可以通過這種方式完成
重載的復制構造函數
/* * Soumil Nitin SHah * Github: https://github.com/soumilshah1995 */ #include <iostream> using namespace std; class Matrix{ public: /* * Declare the Row and Column * */ int r_size; int c_size; int **arr; public: /* * Constructor and Destructor */ Matrix(int r_size, int c_size):r_size{r_size},c_size{c_size} { arr = new int*[r_size]; // This Creates a 2-D Pointers for (int i=0;i < r_size; i++) { arr[i] = new int[c_size]; } // Initialize all the Vector to 0 initially for (int row=0; row<r_size; row ++) { for (int column=0; column < c_size; column ++) { arr[row][column] = 0; } } std::cout << "Constructor -- creating Array Size::" << r_size << " " << c_size << endl; } ~Matrix() { std::cout << "Destructpr -- Deleting Array Size::" << r_size <<" " << c_size << endl; } Matrix(const Matrix &source):Matrix(source.r_size, source.c_size) { for (int row=0; row<source.r_size; row ++) { for (int column=0; column < source.c_size; column ++) { arr[row][column] = source.arr[row][column]; } } cout << "Copy Constructor " << endl; } public: /* * Operator Overloading */ friend std::ostream &operator<<(std::ostream &os, Matrix & rhs) { int rowCounter = 0; int columnCOUNTER = 0; int globalCounter = 0; for (int row =0; row < rhs.r_size; row ++) { for (int column=0; column < rhs.c_size; column++) { globalCounter = globalCounter + 1; } rowCounter = rowCounter + 1; } os << "Total There are " << globalCounter << " Elements" << endl; os << "Array Elements are as follow -------" << endl; os << "\n"; for (int row =0; row < rhs.r_size; row ++) { for (int column=0; column < rhs.c_size; column++) { os << rhs.arr[row][column] << " "; } os <<"\n"; } return os; } void operator()(int row, int column, int Data) { arr[row][column] = Data; } int &operator()(int row, int column) { return arr[row][column]; } Matrix &operator=(Matrix &rhs) { cout << "Assingment Operator called " << endl;cout <<"\n"; if(this == &rhs) { return *this; } else { delete [] arr; arr = new int*[r_size]; // This Creates a 2-D Pointers for (int i=0;i < r_size; i++) { arr[i] = new int[c_size]; } // Initialize all the Vector to 0 initially for (int row=0; row<r_size; row ++) { for (int column=0; column < c_size; column ++) { arr[row][column] = rhs.arr[row][column]; } } return *this; } } }; int main() { Matrix m1(3,3); // Initialize Matrix 3x3 cout << m1;cout << "\n"; m1(0,0,1); m1(0,1,2); m1(0,2,3); m1(1,0,4); m1(1,1,5); m1(1,2,6); m1(2,0,7); m1(2,1,8); m1(2,2,9); cout << m1;cout <<"\n"; // print Matrix cout << "Element at Position (1,2): " << m1(1,2) << endl; Matrix m2(3,3); m2 = m1; cout << m2;cout <<"\n"; print(m2); return 0; }
int row, col;
cout << "Enter row size:";
cin >> row;
cout << "\ncol:";
cin >> col;
int *p_board[row];
for (int i=0; i < row; i++)
p_board[i] = new int[col];
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
p_board[i][j] = j;
cout << p_board[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
//在這個使用new聲明二維數組的方法中。首先你在本地創建了一個指針數組,而不是使用new,所以它將在堆棧而不是堆上創建,然后你在p_board的每個索引上使用new創建了一個數組,這些all arrays are created on heap but due to locally created p_board will make these array of no use becoz when you will use this method in any function and will try to return the p_board pointer from that function..at that time p_board will be vanished from堆棧,因為它是在堆棧上創建的......但第二種方法更適合使用/
int **p_p_board;
p_p_board = new int* [row];
for (int i=0; i < row; i++)
p_p_board[i] = new int[col];
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
p_p_board[i][j] = j;
cout << p_p_board[i][j] << " ";
}
cout << endl;
}
//在這個方法中,兩個數組都將在堆上創建
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.