[英]How to define a 2D array in C++ and STL without memory manipulation?
在 C++ 和 STL 中有几种方法可以在不进行内存操作的情况下定义二维数组,以下代码说明了两种不同的方法:
int main ()
{
/**************
1 2 3
4 5 6
***************/
// Method 1
const int ROW = 2;
const int COL = 3;
int array1[ROW][COL];
for(int i=0; i<ROW; i++)
for(int j=0; j<COL; j++)
array1[i][j] = i*COL+j+1;
// Method 2
typedef vector<vector<int> > ARRAY;
ARRAY array2;
vector<int> rowvector;
for(int i=0; i<ROW; i++)
{
rowvector.clear();
for(int j=0; j<COL; j++)
rowvector.push_back(i*COL+j+1);
array2.push_back(rowvector);
}
return 0;
}
我的问题是:还有其他方法可以定义二维数组吗? 哪一种是最有效的? 谢谢!
在 C++11 中使用std::array
:
std::array<std::array<int,3>,2> a {{
{{1,2,3}},
{{4,5,6}}
}};
一些用法:
a[0][2] = 13;
定义数组的一种非常有效的方法是动态分配,使用new
和delete
运算符。 下面是一个例子:
int **arr=new int*[ROW];
for( int i=0; i<ROW; ++i ) {
arr[i] = new int[COL];
for( int j=0; j<COL; ++j ) {
arr[i][j] = some_val;
}
}
这种方法的一大优点是,当您不再需要数组使用的内存时,您可以轻松地将其删除。 以下是删除二维数组的示例:
for( int i=0; i<ROW; ++i ) {
delete[] arr[i];
}
delete[] arr;
这里有很多权衡。
如果你声明一个 C 风格的二维数组int array[height][width]
,那么你真的得到了一个连续的内存块。 编译器将索引转换为它们的一维地址
array[row][col] == *(array + row * width + col)
如果您使用vector
的vectors
,则每一行都单独分配。 外部vector
存储指向内部vectors
指针。 索引变成一个间接加法:
array[row][col] == *(*(array + row) + col)
vector<vector>
进行了优化)。如果性能真的很重要,您需要对两者进行测试并找出哪个在您的数据上更快。
一种常见的模式是将二维数组封装在提供适当接口的类中。 在这种情况下,您可以使用其他内部表示,例如rows*cols
元素的单个向量。 接口(通常是operator()(int,int)
会将调用者的坐标映射到线性向量中的某个位置。
优点是它具有动态分配,但是是单个分配(与std::vector<std::vector<int>>
,其中每个向量必须获取自己的内存)并且在单个块中提供数据的局部性。
还有其他方法来定义二维数组吗?
没有显式操作内存(malloc/free)。 如果使用静态分配的数组(第一个示例),则在编译时分配空间,因此无法在运行时添加更多行或列。
第二个示例使用std::vector
向您隐藏动态内存分配。 通过这种方式,您最终可以在运行时添加更多行或列。
如果不需要动态修改数组维度,那么第一种方案是更简单更快的方案(即使我认为std::vector的实现速度足够快,可以媲美静态数组,更优雅,更面向对象) )。
如果您需要在运行时修改数组维度,请使用 std::vector,因为它可以避免您直接处理 malloc 和 free。
要使用std::vector
声明二维数组,您可以使用这种构造:
vector<vector<int> > matrix( n, vector<int>(m, -1) );
这将创建一个大小为n
x m
的二维数组matrix
,所有元素都初始化为-1
。
它基本上是“用n
个值val
项初始化”构造函数的嵌套:
vector (size_type n, const value_type& val,
const allocator_type& alloc = allocator_type());
(构造函数定义从这里复制)
如果你事先知道元素,那么你可以做
int arr[2][3] = {{1,2, 3}, {4, 5, 6}};
这应该比方法 1 和方法 2 更有效。 使用向量,您不会自己进行内存操作,但向量实现可能会使用动态分配的数组。
你可以像这样 vector> m_2DArray;
然后一旦知道行数(行)和列数(列),就可以调整二维数组的大小
m_2DArray.resize(rows);
for(auto& el:m_2DArray) el.resize(columns);
您可以使用 m_2DArray[i][j] 访问二维数组中的数据,就像任何其他二维数组一样
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.