如何声明用户给出的大小为n的二维数组?
例如,为什么这会起作用:
int n;
cin >> n;
int *array = new int[n];
//no errors
但这不会:
int n;
cin >> n;
int *array = new int[n][n];
// these errors:
//error: array size in new-expression must be constant
//error: the value of 'n' is not usable in a constant expression
//note: 'int n' is not const
是否可以使用行和列大小为n的二维数组,或者您是否必须使用向量? 谢谢!
答案 0 :(得分:2)
使用矢量执行此操作:
int n;
cin >> n;
auto matrix = std::vector<std::vector<int>>(n, std::vector<int>(n));
https://wandbox.org/permlink/zsOiUTvCbxAGmK6d
<小时/> 还有std::valarray
template与std::vector
具有相似的功能,但具有有趣的额外功能,在矩阵的情况下非常有用。
答案 1 :(得分:1)
要创建多维数组,您必须编写:
int n;
cin >> n;
int **array = new int*[n];
for (int i = 0; i < n; i++) {
array[i] = new int[n];
}
别忘了删除它:
for (int i = 0; i < n; i++) {
delete[] array[i];
}
delete[] array;
但是当前的c ++最佳实践是永远不要在应用程序代码中分配或释放内存,这意味着你应该使用std::vector
或其他一些容器类。
答案 2 :(得分:1)
这个答案在大多数其他答案中有两点不同:
一种常见的方法是使用单个线性内存块并在列(Row- or column-major order)之后的行或列之后逐行存储元素。让我们概括一下,并说你想要一个带有范围T
和N0
的{{1}}类型的2D数量。然后你可以通过
N1
使用向量而不是原始指针有几个优点。例如,您不能忘记释放内存,因为解构器会自动关注内存(RAII idiom)。另一个优点是上面调用的构造函数使用默认构造的std::vector<T> my_memory(N0*N1, T{});
的副本填充向量(而不是将内存保留为未初始化)。
接下来,您可以使用T
的{{3}}(或member operator[]
来访问线性内存,如果您想要绑定检查)。您可能希望在[vector
,n0
)和[n1
,0
)中使用两个索引N0
和0
,但内存是线性的,需要一个索引。因此,您可以引入辅助函数N1
以访问您的2D数量,例如
index
想象一下这是如何工作的,考虑一个3乘2的矩阵。在给定的线性内存块中,您可以像这样排列元素:
0 1 2 3 4 5 index(0, 0) index(0, 1) index(1, 0) index(1, 1) index(2, 0) index(2, 1)
在这种情况下你会写
my_memory[index(n0, n1)] = T(42);
一般来说,int index(int n0, int n1) {
return n0 * N1 + n1;// (note that `n0` is multiplied by `N1`).
}
尺寸(伪代码)
d
括号中的表达式也称为音高。
如果将所有逻辑放在一个类中,使用起来就变得非常简单。以下是灵感的示例(member function at
):
int index(int(&n)[d]) {
return n[0] * (N[1]*N[2]*...*N[d-1])
+ n[1] * (N[2]*N[3]*...*N[d-1])
+ ...
+ n[d-2] * (N[d-1])
+ n[d-1] * (1);
}
答案 3 :(得分:0)
可以在不使用如下矢量的情况下创建二维数组。这适用于所有类型。
template <typename T>
T **Alloc2D( int nRows, int nCols)
{
T **array2D;
array2D = new T*[nRows];
for( int i = 0 ; i < nRows ; i++ )
array2D[i] = new T [nCols];
return array2D;
}
template <typename T>
void Free2D(T** dArray)
{
delete [] *dArray;
delete [] dArray;
}
但问题是内存管理,因为它是一种原始方法。
相反,我们可以使用像
这样可管理的向量typedef vector<vector<int>> ARRAY2D;
答案 4 :(得分:-1)
有可能:
int **marray = new int[n][n];