本网站上的第一个计时器,所以这里......
我是C ++的新手,我目前正在阅读“使用C ++第二版,D.S.Malik的数据结构”一书。
在书中,Malik提供了两种创建动态二维数组的方法。 在第一种方法中,将变量声明为指针数组,其中每个指针都是整数类型。离。
int *board[4];
..然后使用for循环创建'columns',同时将指针数组用作'rows'。
第二种方法是使用指向指针的指针。
int **board;
board = new int* [10];
等
我的问题是:哪种方法更好? **方法对我来说更容易可视化,但第一种方法可以大致相同的方式使用。两种方式都可用于制作动态二维数组。
编辑:上述帖子不够清楚。这是我尝试的一些代码:
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;
}
答案 0 :(得分:40)
第一种方法不能用于创建动态 2D数组,因为这样做:
int *board[4];
你实际上已经在堆栈上分配了一个包含int
的4个指针的数组。因此,如果您现在使用动态数组填充这4个指针中的每一个:
for (int i = 0; i < 4; ++i) {
board[i] = new int[10];
}
你最终得到的是一个2D阵列,其中静态行数(在本例中为4)和动态列数(在本例中为10)。所以它不是完全动态,因为当您在堆栈上分配数组时,应指定常量,即编译 - 时间即可。 动态数组称为动态,因为其大小无需在编译时中获知,但可以由<中的某个变量确定强>运行时强>
再一次,当你这样做时:
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;
}
}
答案 1 :(得分:6)
您为第二种方法描述的内容仅为您提供一维数组:
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*
,然后使每个指向动态分配的10 int
个数组。
所以现在我们将其与int* board[4];
进行比较。主要区别在于,当您使用这样的数组时,必须在编译时知道“行”的数量。那是因为数组必须具有编译时固定大小。如果您想要返回此int*
数组,也可能会出现问题,因为数组将在其范围的末尾被销毁。
动态分配行和列的方法确实需要更复杂的措施来避免内存泄漏。你必须像这样解除内存:
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>>
。
答案 2 :(得分:1)
在这两种情况下,您的内部维度可以动态指定(即从变量中获取),但差异在外部维度。
这个问题基本上等同于以下内容:
int* x = new int[4];
“比int x[4]
更好”吗?
答案是:“否,除非您需要动态选择该数组维度。”
答案 3 :(得分:0)
此代码适用于外部库的极少要求,并显示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
。准系统,但足以说明如何使用简单的多维数组。
答案 4 :(得分:0)
这可以通过这种方式完成
重载的副本构造方法
/*
* 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;
}