C++动态/静态数组作为函数的参数

foF*_*Fox 1 c++ arrays parameters

我一直在尝试使用2D数组作为我的C++类中的构造函数的参数.

标题:

Matrix::Matrix(double **initComponents, int rows, int columns)
Run Code Online (Sandbox Code Playgroud)

如果我只是继续定期调用new和初始化子数组,将指针传递给构造函数,它的一切都很好但是我想,我可以用初始化器创建静态2D数组并将指针传递给构造函数?

double A[][3] = { {2.0, 3.0, 4.0} , {1.0, 3.0, 4.0} , {2.0, 3.0, 4.0} }; 
Matrix *mtx = new Matrix(A, 3, 3);
Run Code Online (Sandbox Code Playgroud)

这不起作用:(

MS Visual Studio编译器:

" error C2664: 'Matrix::Matrix(double **,int,int)' : cannot convert parameter 1 from 'double [3][3]' to 'double ** "
Run Code Online (Sandbox Code Playgroud)

有谁能解释为什么?我以为它会在引用和指针之间进行自动转换.

第二个问题是,为什么我只能声明A为double A[][],为什么我必须指定第二个维度,即使我指定了所有值.

Vau*_*ato 5

数组确实转换为指针,但它只适用于一个级别.数组数组不会转换为指针指针.

数组可以转换为指针,因为指针仍然提供了查找数组值的合理方法,但是数组数组与指针指针的根本不同.数组数组连续存储在内存中.例如,如果您有这样的定义:

int a[2][2] = {{1,2},{3,4}};
Run Code Online (Sandbox Code Playgroud)

然后将[0] [0]存储在第一个存储单元中,[0] [1]存储在第二个存储单元中,a [1] [0]存储在第三个存储单元中,[1] [1]存储在第二个存储单元中.第四.当你想查找像[i] [j]这样的特定元素时,编译器可以计算位置,因为它知道数组的大小:

int value = ((int *)a)[i*2+j];
Run Code Online (Sandbox Code Playgroud)

将其与指针指针进行比较

int a0[2] = {1,2};
int a1[2] = {3,4};
int **a = {a0,a1};
Run Code Online (Sandbox Code Playgroud)

现在当你使用[i] [j]时,编译器无法直接知道在哪里查看.首先必须查看[0]并查看指向的位置,然后再次查看该值.

int *ap = a[i];
int value = ap[j];
Run Code Online (Sandbox Code Playgroud)

因为编译器必须使用不同的方式查找数组数组和指针指针中的值,所以不能互换使用它们.

同样,在这样的声明中:

int a[][2] = {{1,2},{3,4}};
Run Code Online (Sandbox Code Playgroud)

可以省去第一个维度的大小,因为编译器会为你填写它,但这只适用于一个级别.原则上,编译器可以很好地猜测其他维度应该是什么,但它实际上是该语言中的单独规则.

如果你真的想要能够传递一个2D数组,你可以使用这样的模板化构造函数:

template<int rows, int cols>
Matrix(const double (&initComponents)[rows][cols])
{
  // initialize matrix elements here
}
Run Code Online (Sandbox Code Playgroud)

然后你甚至不需要明确地传递大小:

double A[][3] = { {2.0, 3.0, 4.0} , {1.0, 3.0, 4.0} , {2.0, 3.0, 4.0} };
Matrix *mtx = new Matrix(A);
Run Code Online (Sandbox Code Playgroud)