【问题标题】:Multidimensional variable size array in C++C ++中的多维可变大小数组
【发布时间】:2009-12-22 14:50:13
【问题描述】:

嗨,我想做这样的事情:

int op(string s1, string s2){
    int x = s1.size();
    int y = s2.size();
    int matrix = new int[x][y]
    /* do stuff with matrix */
}

由于某种原因,我收到以下错误:

SuperString.cpp(69) : error C2540: non-constant expression as array bound
SuperString.cpp(69) : error C2440: 'initializing' : cannot convert from 'int (*)[1]' to 'int'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast
SuperString.cpp(71) : error C2109: subscript requires array or pointer type

谢谢!

【问题讨论】:

标签: c++ arrays


【解决方案1】:

这里总结了如何使用各种技术在 C++ 中构建二维数组。

静态二维矩阵:

const size_t N = 25; // the dimension of the matrix

int matrix[N][N]; // N must be known at compile-time.
// you can't change the size of N afterwards

for(size_t i = 0; i < N; ++i)
{
    for(size_t j = 0; j < N; ++j)
    {
        matrix[i][j] = /* random value! */;
    }
}

动态二维矩阵:

const size_t N = 25; // the dimension of the matrix
int** matrix = new int*[N]; // each element is a pointer to an array.

for(size_t i = 0; i < N; ++i)
    matrix[i] = new int[N]; // build rows

for(size_t i = 0; i < N; ++i)
{
    for(size_t j = 0; j < N; ++j)
    {
        matrix[i][j] = /* random value! */;
    }
}

// DON'T FORGET TO DELETE THE MATRIX!
for(size_t i = 0; i < N; ++i)
    delete matrix[i];

delete matrix;

使用 std::vector 的矩阵:

// Note: This has some additional overhead
// This overhead would be eliminated once C++0x becomes main-stream ;)
// I am talking about r-value references specifically.
typedef vector< vector<int> > Matrix;
typedef vector<int> Row;

const size_t N = 25; // the dimension of the matrix
Matrix matrix;

for(size_t i = 0; i < N; ++i)
{
    Row row(N);

    for(size_t j = 0; j < N; ++j)
    {
        row[j] = /* random value! */;
    }

    matrix.push_back(row); // push each row after you fill it
}

// Once you fill the matrix, you can use it like native arrays
for(size_t i = 0; i < N; ++i)
{
    for(size_t j = 0; j < N; ++j)
    {
        cout << matrix[i][j] << " ";
    }

    cout << endl;
}

3d 矩阵使用 boost::multi_array (taken from boost multi_array docs):

// Note that this is much more efficient than using std::vector!
int 
main () {
  // Create a 3D array that is 3 x 4 x 2
  typedef boost::multi_array<double, 3> array_type;
  typedef array_type::index index;
  array_type A(boost::extents[3][4][2]);

  // Assign values to the elements
  int values = 0;
  for(index i = 0; i != 3; ++i) 
    for(index j = 0; j != 4; ++j)
      for(index k = 0; k != 2; ++k)
        A[i][j][k] = values++;

  // Verify values
  int verify = 0;
  for(index i = 0; i != 3; ++i) 
    for(index j = 0; j != 4; ++j)
      for(index k = 0; k != 2; ++k)
        assert(A[i][j][k] == verify++);

  return 0;
}

【讨论】:

  • std::vector 示例看起来不对。在 Matrix matrix(N) 声明之后,matrix 有 25 个空行。然后再推 25 行非空行,最终得到 50 行。
  • @JWWalker 是的,你是完全正确的。我编辑了答案,谢谢:)
  • 我正在调查Dynamic 2d matrix 的情况... 不应该有delete [] matrix[i];delete [] matrix; (缺少括号[])吗?毕竟,我们分配了一个指针数组int*[N],据我所知,这很重要。
【解决方案2】:

您需要将矩阵变量声明为int* matrix,因为动态数组被声明为指针。但是你不能在一个新的二维数组中做一个两个维度都是可变的。您可以创建一维数组并自行计算索引。
int* matrix = new int[x*y];
// Set element x1,y1 to 5
matrix[x1+y1*x] = 5;

【讨论】:

  • @Zanson:仔细阅读问题。
  • @Zanson:“作为一个数组是一个指针”是不正确的。数组是一个“数组”,它可能会在需要时转换为指针类型,例如在将数组传递给函数时,调用函数中的数组将转换为指针类型作为被调用函数的正式参数。
  • @Prasoon 是的,我阅读了编译器警告并在我第一次回答时错过了 2d 部分。
【解决方案3】:

使用boost::multi_array。 有关详细信息,请参阅文档和 this question

这将帮助您避免很多错误。

【讨论】:

    【解决方案4】:

    如果matrix的大小不需要通过函数改变,可以将存储string长度的ints声明为const。这允许您创建一个多维数组,该数组的大小可以针对每个函数调用而变化,但在函数执行期间保持不变。

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int someFunc(string, string);
    
    int someFunc(string s1, string s2)
    {
        const int x = s1.length();
        const int y = s2.length();
    
        int matrix[x][y];
        int result=0;
    
        for(int i=0;i<x;i++)
            for(int j=0;j<y;j++)
                matrix[i][j]=i*j;
    
        for(int i=0;i<x;i++)
            for(int j=0;j<y;j++)
                result+=matrix[i][j];
    
        return result;
    }
    
    int main()
    {
        string s1 = "fubar";
        string s2 = "somethingelse";
    
        cout<<someFunc(s1,s2)<<endl;
    }
    

    编辑:在阅读我写我的时候发布的其他答案之一时,我想你应该使用const size_t 而不是const int。抱歉,我的 C++ 有点生锈了。

    【讨论】:

      【解决方案5】:

      你不能有一个非常量行大小的矩阵。

      您可以选择拥有一个“指向数组的指针数组”结构,它可以像矩阵一样被索引为 pp[a][b]。您不能使用单个new 分配这样的结构。您必须在缓冲区中手动构建它。

      【讨论】:

        【解决方案6】:

        这更像是一个语法问题。

        在 gcc 4.4 中的最后一次检查,int matrix[x][y]; 似乎按预期工作。如果您的数组不需要在函数中间调整大小。你可以试试这个语法,看看它是否适用于你的编译器。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-02-26
          • 1970-01-01
          • 2021-10-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多