繁体   English   中英

指针对指针的动态二维数组

[英]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::cinstd::cout Barebones,但足以说明如何使用简单的多维数组。

这可以通过这种方式完成

  1. 我使用过运算符重载
  2. 重载分配
  3. 重载的复制构造函数

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM