C++多维数组初始化

9

在C++中,我想要像平常不使用指针一样初始化一个双精度矩阵(二维双精度数组),就像这样:

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

然而,由于我想将其返回并传递给函数,所以我需要它作为double **指针。因此,基本上我需要以良好的方式初始化数据(如上所述),但之后我需要保存指向2D数组的指针,在函数退出时不丢失数据。
有什么帮助吗? :-)

4
为什么你需要使用 double**,而不是 double (*)[4]?使用 double (*)[4] 有什么问题吗? - CB Bailey
这是C++。这个数组作为成员,可以作为一个类吗?当您调用成员函数时,它会传回一个引用吗? - Merlyn Morgan-Graham
可能是通过指针传递二维数组的重复问题。虽然是C而不是C++,但问题完全相同。 - CB Bailey
没有一个答案命中要害。我发现我可以这样做:double ** d = new double[4][4];但是,如何初始化值而不必编写像d [0] [0] = 1; d [0] [1] = 0; ...这样的代码呢? - Felix
不行,例如,g++拒绝编译您的代码片段:error: cannot convert 'double (*)[4]' to 'double**' in initialization - fredoverflow
7个回答

10

除非你特别需要指针,否则我会更喜欢在这里使用引用

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);
}

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


我认为这个答案越来越接近了。它可能就是我正在寻找的那一个! - Felix
通过使用复制函数替换“init”,优雅地模拟了我的问题。谢谢! - Felix

6

你所有的矩阵都是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)
{
    // ...
}

这将避免您处理数组指针消失的问题,并使代码在我看来更易读。

6

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

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])
{
   ...
   ...
}

这个方法可以将数组作为引用传递,而不需要使用指针。

希望这能有所帮助。


1
谢谢!那一行代码的初始化正是我一直在寻找的。 - sleighty

3

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

只需勾画两者在内存中的布局,您就应该理解为什么不能互换使用它们。


由于我不知道或理解“double (*)[4]”,所以我无法勾画它。这是什么意思? - Felix

1
这个怎么样(带指针,并且做了你要求的事情)?
#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;
}

1

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


0
虽然有点晚了,但是......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://dev59.com/h2sy5IYBdhLWcg3w-i7h#12616826

好处是什么? 它可以很好地与std算法配合使用,知道其大小,具有相同的性能等。 参考:std::array vs array performance


此外,如果您不知道大小,请使用std::vector - Barney Szabolcs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接