【问题标题】:C++ multi-dimensional array initializationC++多维数组初始化
【发布时间】:2011-04-03 00:34:13
【问题描述】:

在 C++ 中,我想初始化一个双矩阵(二维双数组),就像我通常在没有这样的指针的情况下所做的那样:

    double data[4][4] = {
    1,0,0,0,
    0,1,0,0,
    0,0,1,0,
    0,0,0,1
};

但是,由于我想返回并将它传递给函数,我需要它作为 double** 指针。所以,基本上我需要以一种很好的方式初始化数据(如上),但之后我需要保存指向二维数组的指针,而不会在函数退出时丢失数据。

对此有任何帮助吗? :-)

【问题讨论】:

  • 为什么需要它作为double**double (*)[4] 有什么问题?
  • 这是 C++。这可以是一个类,以这个数组作为成员,在调用成员函数时将引用传回吗?
  • Passing two-dimensional array via pointer 的可能重复项是 C,不是 C++,但问题完全相同。
  • 所有答案都没有击中靶心。我发现我可以这样做: double ** d = new double[4][4];但是,我将如何在不编写诸如 d[0][0] = 1; 之类的繁琐代码的情况下初始化值d[0][1] = 0;...
  • 不,你不能。比如g++拒绝编译你的sn-p:error: cannot convert 'double (*)[4]' to 'double**' in initialization.

标签: c++ pointers initialization multidimensional-array


【解决方案1】:

除非你对指针特别感兴趣,否则我更喜欢这里的参考

void init( double (&r)[4][4]){
    // do assignment
    r[0][0] = 1;
}

int main(){
    double data[4][4] = {
        1,0,0,0,
        0,1,0,0,
        0,0,1,0,
        0,0,0,1
    };

    init(data);
}

顺便说一句,如果你以这种方式将它传递给一个函数,你将是“分配”而不是“初始化”。

【讨论】:

  • 我认为这个答案越来越温暖。它可能就是我要找的那个!
  • 通过将“init”替换为复制功能,这可以优雅地模拟我的问题。谢谢!
【解决方案2】:

您的所有矩阵都是 4x4 的吗?然后我会简单地定义一个带有double[4][4] 成员的类并传递该类的对象:

class Matrix
{
    double m[4][4];
    // ...
};

void function(const Matrix& matrix)
{
    // ...
}

如果您需要各种维度的矩阵,但它们在编译时是已知的,请使用模板:

template <size_t n>
class Matrix
{
    double m[n][n];
    // ...
};

template <size_t n>
void function(const Matrix<n,n>& matrix)
{
    // ...
}

这使您免于处理数组到指针的衰减,并使代码更具可读性恕我直言。

【讨论】:

    【解决方案3】:

    首先,双维数组的声明不正确。需要按如下方式进行:

    double data[4][4] = {  
            {1.0,0,0,0},  
            {0,1,0,0},  
            {0,0,1,0},  
            {0,0,0,1}  
        };
    

    其次,要在函数中传递它,您可以这样做

    show(data);
    

    在函数声明中,您需要将参数作为数组提供,并提供除第一个以外的所有维度。所以声明看起来像:

    void show(double arr[][4])
    {
       ...
       ...
    }
    

    这会将数组作为引用传递,而无需使用指针。

    希望这会有所帮助。

    【讨论】:

    • 谢谢!那一行初始化是我一直在寻找的。​​span>
    【解决方案4】:

    double (*)[4]double ** 非常不同

    只需在内存中为两者勾勒出双打的布局,您就应该明白为什么不能互换使用它们。

    【讨论】:

    • 由于我不知道也不理解“double (*)[4]”,所以我无法画出它。这是什么意思?
    【解决方案5】:

    以这种方式初始化临时变量,然后将其复制到动态分配的内存中。

    【讨论】:

      【解决方案6】:

      这个怎么样(用指针,按照你的要求做)

      #include <iostream>
      
      using namespace std;
      
      int refer(double (*a)[4])
      {
         cout<<"First value is "<<(*a)[0];
         (*a)[0] = 37;
         cout<<"changed value is "<<(*a)[0];
      }
      
      int main()
      {
         double data[4][4] = {
          1.0,0,0,
          0,1,0,0,
          0,0,1,0,
          0,0,0,1
         };
         refer(data);
         return 0;
      }
      

      【讨论】:

        【解决方案7】:

        迟到了,但是.... c++ 旨在与 c++ stl 一起使用。 (至少根据 Bjarne Stroustrup 的说法,如果您在 c++ 中使用原始指针,那么您做错了什么。)

        #include <array> // on top
        // ..    
        
        std::array<std::array<int, 4>, 4> data {{
            {1,0,0,0},
            {0,1,0,0},
            {0,0,1,0},
            {0,0,0,1}
        }};
        
        // access it normally 
        
        data[1][2] = 123;
        std::cout << data[0][0]; // prints 1. (#include <iostream>)
        
        // You can return std::array from a function as a normal return value, don't worry it is not going to be reallocated, or missing.
        
        std::array<std::array<int, 4>, 4> give_me_data() {
          std::array<std::array<int, 4>, 4> data {{
            {1,0,0,0},
            {0,1,0,0},
            {0,0,1,0},
            {0,0,0,1}
          }};
          return data;
        }
        

        (适用于 Mac 的 XCode,gcc 也支持它https://stackoverflow.com/a/12616826/1031191

        有什么好处? 它与标准算法很好地配合,知道它的大小,相同的性能等。 参考:std::array vs array performance

        【讨论】:

        • 另外,如果您不知道大小,请使用std::vector
        猜你喜欢
        • 2015-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-01
        • 1970-01-01
        相关资源
        最近更新 更多