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

时间:2012-03-04 18:52:08

标签: c++ arrays parameters

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

部首:

Matrix::Matrix(double **initComponents, int rows, int columns)

如果我只是继续定期调用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);

不起作用:(

MS Visual Studio编译器:

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

任何人都可以解释原因吗?我以为它会在引用和指针之间进行自动转换。

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

1 个答案:

答案 0 :(得分:5)

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

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

int a[2][2] = {{1,2},{3,4}};

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

int value = ((int *)a)[i*2+j];

将此与指针

的指针进行比较
int a0[2] = {1,2};
int a1[2] = {3,4};
int **a = {a0,a1};

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

int *ap = a[i];
int value = ap[j];

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

同样,在这样的声明中:

int a[][2] = {{1,2},{3,4}};

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

如果你真的想要传递2D数组,可以使用这样的模板化构造函数来完成:

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

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

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