2

我放弃了尝试将二维数组传递给函数,其中在编译时维度未知。经过一些研究,二维向量似乎是一个很好的替代品。我只是想确认这是声明维度为 totalRows X totalColumns 的二维向量的正确方法,初始化每个单元格以包含空格字符:

vector<vector<char> > world(totalRows, vector<char>(totalColumns, ' '));
4

2 回答 2

9

这条线本身应该可以工作并且看起来很好。但让我提供更多信息。

尝试使用标准库是个好主意。话虽如此,您需要了解您脑海中的二维数组图像必须线性存在于内存中。您可以轻松地创建一个 m*n 字符的元素向量(在您的示例中)并将其按行主要索引为 (i*n + j) (感谢从零开始的计数)。

事实上,这就是“二维”数组的工作方式。例如,当你做一个规则的元素数组 -T[][]时,如果你尝试将它衰减为一个指针,它将是一个简单的T*. 在引擎盖下,内存是连续线性排列的,没有形状,只有一条长街(如计算机所见)。它只是通过使用第一段中的表达式(或类似的表达式)来推断人类所看到的行和列的概念。电脑不在乎。

vector是标准库的一个很好的部分,它以签名 C++(而不仅仅是臃肿的 C)的方式封装数组。它的设计使内部数组数据结构的大小调整变得容易,并且随着 C++11 的出现,移动语义可以使调整大小的操作变得更便宜。此外,RAII 的概念也适用于此,在构造函数中仔细初始化数据成员并在析构函数中释放它们的想法使您能够规避作为用户的动态内存分配问题,并简单地在堆栈上传播新对象,并在需要时传递引用“退出”他们的范围。

需要注意的一点是vectors 创建了一个内部内存块,该数组有时可能会超过实际数组的大小,因为弹出和推送新元素。此外,您不必一开始就定义它的大小,但可以通过 push_back、push_front 等轻松扩展它。这意味着其他事情可以即时更改,并且扩展可能会花费您很多,即使使用移动语义.

偏离矢量的唯一原因是,当您进行一些面向数据的繁重 3D 渲染或模拟,并期望数据以一些非常自定义、特定的方式打包并手动打乱时,整洁vector可能不容易允许. 但这会将您推向更底层的裸数组领域(您应该为此做好准备)。您应该从中得到的关键是您可以简单地将“心理二维数组”向量(实际上,数据没有真正的几何形状,这就是我们这些微不足道的人类看待它的方式)作为向量并以不同的方式对它们进行索引。确保您按顺序逐一输入所有行数据,您将获得一个非常简单的布局,可以用 (i*n + j) 简单地探测/索引,其中 [i,j] 是经典的 2D 矩阵下标/索引。

然后,它可能很简单:

vector<char> world(totalRows*totalColumns, ' ');

然后你只需通过引用传递它需要去的地方,在你正确推送数据后将其索引为 (i*n + j) 。

您的代码应该可以工作,但是在尝试操作数据、移动数据和编写不必要的东西时,不必要的膨胀可能会引入不必要的心理开销,这比实际使用 i*n+j “手动索引”方法来保持您的心理图景要少得多二维数组/字符矩阵。如果您愿意,您甚至可以重写功能以添加语法糖。

于 2012-06-24T19:33:11.483 回答
4

您的代码有效。正如评论中所注意到的,vector<vector<T>>它并不是真正的二维数组。

这里重要的是(totalRows, vector<char>(totalColumns, ' '))(totalColumns, vector<char>(totalRows, ' '))是等价的,只要您始终遵循用于创建向量的规则:(line x columncolumn x line

于 2012-06-24T18:46:18.043 回答