如何制作用户指定值的二维数组?

时间:2017-10-28 07:49:22

标签: c++ arrays multidimensional-array

如何声明用户给出的大小为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的二维数组,或者您是否必须使用向量? 谢谢!

5 个答案:

答案 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 templatestd::vector具有相似的功能,但具有有趣的额外功能,在矩阵的情况下非常有用。

https://wandbox.org/permlink/9Vq141QpEWcWoUxM

答案 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)之后的行或列之后逐行存储元素。让我们概括一下,并说你想要一个带有范围TN0的{​​{1}}类型的2D数量。然后你可以通过

获得所需的内存
N1

使用向量而不是原始指针有几个优点。例如,您不能忘记释放内存,因为解构器会自动关注内存(RAII idiom)。另一个优点是上面调用的构造函数使用默认构造的std::vector<T> my_memory(N0*N1, T{}); 的副本填充向量(而不是将内存保留为未初始化)。

接下来,您可以使用T的{​​{3}}(或member operator[]来访问线性内存,如果您想要绑定检查)。您可能希望在[vectorn0)和[n10)中使用两个索引N00,但内存是线性的,需要一个索引。因此,您可以引入辅助函数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];