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

新手上路,请多包涵

这个网站上的第一个计时器,所以这里..

我是 C++ 的新手,我目前正在阅读“DS Malik 的使用 C++ 2nd ed 的数据结构”一书。

在书中 Malik 提供了两种创建动态二维数组的方法。在第一种方法中,您将变量声明为指针数组,其中每个指针都是整数类型。前任。

 int *board[4];

..然后使用 for 循环创建“列”,同时将指针数组用作“行”。

第二种方法,你使用一个指针指向一个指针。

 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;
}

原文由 user2280041 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 437
2 个回答

第一种方法不能用于创建 动态 二维数组,因为这样做:

 int *board[4];

您实际上 在堆栈 上分配了一个由 4 个指针组成的数组,指向 int 。因此,如果您现在用动态数组填充这 4 个指针中的每一个:

 for (int i = 0; i < 4; ++i) {
  board[i] = new int[10];
}

你最终得到的是一个具有 静态 行数(在本例中为 4)和 动态 列数(在本例中为 10)的二维数组。所以它不是 完全 动态的,因为当您在堆栈上分配一个数组时,您 应该 指定一个 常量大小,即在 编译时 已知。 动态 数组之所以称为 动态 数组,是因为它的大小不必在 编译时 知道,而是可以在 运行时 由某个变量确定。

再一次,当你这样做时:

 int *board[4];

或者:

 const int x = 4; // <--- `const` qualifier is absolutely needed in this case!
int *board[x];

您提供一个在 编译时 已知的常量(在本例中为 4 或 x ),以便编译器现在可以为您的数组 预分配 此内存,并且当您的程序加载到内存中时它已经拥有 board 数组的这个内存量,这就是为什么它被称为 static ,即因为大小是 硬编码的 并且 不能动态更改(在运行时)。

另一方面,当你这样做时:

 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 数组的相应空间将在所谓的 - 计算机上运行的所有程序可以 预先(在编译时)分配未知 数量的内存区域供个人使用。

因此,要真正创建动态二维数组,您必须使用第二种方法:

 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 x 10 维度的方形二维数组。要遍历它并用实际值填充它,例如 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;
  }
}

原文由 Alexander Shukaev 发布,翻译遵循 CC BY-SA 3.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创建了一个数组,这些所有数组都是在堆上创建的,但是由于本地创建的 p_board 将使这些数组无用,因为当您在任何函数中使用此方法并尝试从该函数返回 p_board 指针时,pboard 将从中消失堆栈,因为它是在堆栈上创建的……但第二种方法更适合使用/

  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;
    }

//在这个方法中,两个数组都将在堆上创建

原文由 Gaurav Kumar 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题