如何声明一个可以接受任何大小的二维向量参数?
Posted
技术标签:
【中文标题】如何声明一个可以接受任何大小的二维向量参数?【英文标题】:How to declare a 2D vector parameter which will accept any size? 【发布时间】:2019-08-04 13:43:55 【问题描述】:我刚刚开始学习 C++。
我必须声明一个可以接受像这样的变量的方法:
int grid1[200][200];
int grid2[20][25];
int grid3[53][40];
如何在方法中声明该参数?
我找到了这个声明,但我不知道它是否有用或如何使用它:
int** a = new int*[rowCount];
我会将该参数复制到一个动态的成员变量中(我认为它会在堆中,所以这就是为什么它是动态的)。
【问题讨论】:
具有复杂性。为什么需要传递二维 C 数组?你最好不要... 不要使用原始的 C 样式数组。你想要的是std::vector
。
@VansFannel 找到问题了! Stack Overflow 不能很好地用于教授语言的基础知识,或者这就是我们所做的一切。开始here。玩得开心!
@JeJo 我知道,这就是为什么我试图将其剔除:P
int** a = new int*[rowCount];
是 1990 年代的遗物
【参考方案1】:
对于静态大小的数组,请使用std::array。对于动态大小的数组,请使用std::vector。除非某些奇怪的情况迫使您使用原始 C 数组,否则不要使用原始 C 数组。
如果需要多维数组,当然可以使用std::vector<std::vector<int>>
或类似的std::array
。这既简单又方便,因为您可以使用myarray[row][column]
(并且可能足够好)。但更好的选择通常是声明一个大小为“维度 1 * 维度 2”的一维 std::vector<int>
,然后在索引到它时执行 myvector[row_number * size_of_row + column]
。将 1D 数组视为 2D 数组就这么简单,而且它的性能可能会更好,因为它对您的 CPU 预取器和缓存层次结构更友好。
至于声明一个函数来接受这样的数组 - 它是直截了当的。例如:
void f(const std::array<int, 666>& myarray);
void f(const std::array<std::array<int, 42>, 666>& myarray);
void f(const std::vector<int>& myarray);
void f(const std::vector<std::vector<int>>& myarray);
【讨论】:
【参考方案2】:使用std::vector 并忘记与普通数组相关的所有内容。
void foo(vector<vector<int>>& v)
...
// now you have a 100x50 double array
vector<vector<int>> x;
x.resize(100);
for(auto& xx : x)
xx.resize(50);
foo(v);
如果您关心caching 如评论所述,您可以创建一个单维向量并将其转换为多维数组,我之前曾询问过here 用于动态数组。或者,如果您的尺寸是静态的,您可以简单地:
vector<int> x(100);
int(*yy)[3] = (int(*)[3])x.data(); // Creates a 2D array inside x
yy[0][1] = 5;
yy[1][2] = 4;
yy[2][2] = 10;
使用像x*col + row
这样的行和列进行内部计算以手动将一维数组转换为二维是不好的并且容易出错。
【讨论】:
不要使用向量的向量。它们是你缓存的毒药。此外,这并不能回答问题。 @LightnessRacesinOrbit,那么拥有多维数组的方法是什么? @LightnessRacesinOrbit 我没有问原因,我问的是解决方案。 @MichaelChourdakis 您可以轻松地拥有一个一维数组并将其视为具有二维。 @LightnessRacesinOrbit 1. 成功。 2 让它发挥作用。 3. 让它快速运行。以该顺序。对于刚开始学习的人来说,直接跳到 3 会适得其反。以上是关于如何声明一个可以接受任何大小的二维向量参数?的主要内容,如果未能解决你的问题,请参考以下文章