【问题标题】:2D array in C++ with variable dimentionsC ++中具有可变维度的二维数组
【发布时间】:2018-10-08 13:57:31
【问题描述】:

所以我正在自学 C++,但我对数组有疑问。我知道如果我声明一个二维数组,例如:

char board[8][8];

我创建了一个高度和宽度为 8 的二维数组。但是,我想知道是否有办法将这些维度设置为变量,以便用户可以输入他们想要的高度和宽度,我在 C++ 中尝试过视觉工作室很不高兴。

int rowSize = 0;  
int colSize = 0;
cin >> rowSize >> colSize;
char board[rowSize][colSize];

谁能帮帮我?

【问题讨论】:

  • 数组的大小必须是编译时常数。对动态大小的数组使用 std::vector。
  • 我想您的 C++ 书籍涵盖了这个主题?因为它相当普遍。值得一读!

标签: c++ arrays multidimensional-array


【解决方案1】:

由于这是用c++ 标记的,也许std::vector 是给你的。它很像一个数组,但更方便,更适合这个目的。您可以使用此初始化程序调用简单地初始化嵌套向量的 2D 数组(感谢 Bob__ 提供了这个更简单的解决方案):

int n = 5;
int m = 10;
std::vector<std::vector<char>> board (n, std::vector<char>(m, 'a'));

这将创建板并将所有字段初始化为'a',例如。您可以使用与 C 样式数组相同的语法访问和操作数据:

char x = board[4][2];
board[3][3] = 'o';

最后但并非最不重要的一点是,与使用 C 样式的数组相比,有许多方便的特性和函数可以让您更轻松地进行复制等操作。查看std::stringhere的文档。

【讨论】:

  • 向量的向量与C中的多维数组不一样。这需要更多的内存分配和更多的间接访问,因此它比C的解决方案慢得多。
  • 没错。在拥有数百万个单元的大型板上,这种放缓可能很快就会很明显。我不会在有数百万个单元的板上这样做,但我认为这不是 OP 的意图,那么为什么不利用合适的容器以一种简单易用的方式解决任务呢?
  • @MatthieuBrucher:你真的测量过开销吗?在现实世界的程序中很少可以观察到它。但是数据并没有连续存储在向量向量中(更像是指向数组的指针数组)。
  • @MatthieuBrucher 对于初学者来说,这是一个很好的起点(至少它引入了标准库并避免了供应商特定的非标准扩展),下一个学习步骤是编写一个合适的类。不过,我会使用构造函数:std::vector&lt;std::vector&lt;char&gt;&gt; board (n, std::vector&lt;char&gt;(m, 'a'));
  • 我没有提到任何非标准扩展。是的,我测量了速度差异,它在“大”矩阵上是巨大的。这就是为什么所有数学库都实现为一维数组的原因。
【解决方案2】:

如果您想分配这样的矩阵,请使用向量并使用i + j * rowSize 对其进行索引。

另一种构造不符合 c++,它是 C99(可变长度数组)的 gcc 扩展,它们的等价物(或多或少)是向量或指向数组的唯一指针。

【讨论】:

    【解决方案3】:

    如果你真的想这样做,你可以这样做:

    int* myPointer = nullptr;   // Pointer to int, initialize to nothing.
    int sizeOfArray;           // Size needed for array
    std::cin >> sizeOfArray;        // At runtime get the size of the array
    myPointer = new int[sizeOfArray];  // Allocate array of specified size and save ptr in a.
    for (int i = 0; i < sizeOfArray; i++) {
        myPointer[i] = 0;    // Initialize all elements to zero.
    }
    delete[] myPointer;  // When done, free memory pointed to by myPointer.
    myPointer = nullptr;     // Clear a to prevent using invalid memory reference.
    

    虽然我强烈建议您改用vector。

    【讨论】:

    • 用向量或唯一指针代替,那么我们更接近核心准则。
    【解决方案4】:

    不,你不能使用符合 C++ 的标准,因为标准没有定义可变长度数组 (*)。

    如果您不需要连续分配(真正的二维数组底层存储),您可以使用向量的向量。这通常是最简单和惯用的方式:

    std::vector<std::vector<char>>(8, std::vector<char>(8, '\0'));
    

    如果您可以接受函数类型访问,则可以使用大小为 64 (8*8) 的底层一维向量和返回引用的访问器方法构建自定义容器。

    如果你想用底层真正的 2D 数组来模拟 2D 容器,那么你就有麻烦了。我尝试构建一个通用的多维容器(代码在Code Review),并意识到您无法在非标准容器上正确实现随机访问迭代器...


    (*) 当然,gcc 很乐意接受 C++ 中的 VLA 作为该语言的文档扩展...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多