简体   繁体   English

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

[英]C++ Dynamic/Static arrays as parameters to functions

I have been trying to use 2D array as a parameter to a constructor in my C++ class. 我一直在尝试使用2D数组作为C ++类中构造函数的参数。

Header: 标头:

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

If I just go ahead and do regular calls to new and initialize sub arrays, pass a pointer to a constructor, its all good BUT I was thinking , can I just create static 2D array with initializer and pass a pointer to it, to a constructor? 如果我只是继续对新数组和初始化子数组进行常规调用,将指针传递给构造函数,那么我想的一切都很好,我是否可以使用初始化函数创建静态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);

that does not work :( 那不起作用:(

MS Visual Studio compiler : MS Visual Studio编译器:

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

Can anyone explain why? 谁能解释为什么? I thought it will do an automatic conversion between reference and a pointer. 我以为它将在引用和指针之间进行自动转换。

Second question is, why can I just declare A as double A[][] , why do I have to specify the second dimension, even though I specify all values. 第二个问题是,为什么我只能A声明为double A[][] ,即使我指定了所有值,为什么也必须指定第二维。

An array does convert to a pointer, but it only works for one level. 数组确实会转换为指针,但仅适用于一个级别。 An array of arrays does not convert to a pointer to pointers. 数组数组不会转换为指向指针的指针。

An array can be converted to a pointer because a pointer still provides a reasonable way to look up the values of the array, but an array of arrays is a fundamentally different thing than a pointer to pointers. 数组可以转换为指针,因为指针仍然提供查找数组值的合理方法,但是数组的数组与指针的指针本质上是不同的。 An array of arrays is stored in memory contiguously. 数组的数组连续存储在内存中。 For example, if you had a definition like this: 例如,如果您具有如下定义:

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

Then a[0][0] is stored in the first memory location, a[0][1] is stored in the second, a[1][0] in the third, and a[1][1] in the fourth. 然后a [0] [0]存储在第一个存储位置,a [0] [1]存储在第二个存储位置,a [1] [0]存储在第三个存储位置,a [1] [1]存储在第二个存储位置。第四。 When you want to look up a particular element like a[i][j], the compiler can compute the location since it knows the size of the arrays: 当您要查找像a [i] [j]之类的特定元素时,编译器可以计算位置,因为它知道数组的大小:

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

Compare this to a pointer to pointers 将此与指向指针的指针进行比较

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

Now when you use a[i][j], the compiler can't directly know where to look. 现在,当您使用a [i] [j]时,编译器无法直接知道在哪里查看。 It first has to look at a[0] and see where that points to, and then look a second time to find the value. 它首先必须查看a [0]并查看其指向的位置,然后再次查看以找到该值。

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

Because the compiler has to use a different way of looking up the values in arrays of arrays and pointers to pointers, you can't use them interchangeably. 因为编译器必须使用不同的方式在数组数组和指针指针中查找值,所以您不能互换使用它们。

Likewise, in a declaration like this: 同样,在这样的声明中:

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

it is okay to leave off the size of the first dimension because the compiler will fill it in for you, but this only works for one level. 可以保留第一个维度的大小,因为编译器会为您填充它,但这仅适用于一个级别。 In principle, the compiler could make a good guess about what the other dimensions should be, but it would really be a separate rule in the language. 原则上,编译器可以很好地猜测其他维度应该是什么,但这实际上是语言中的一个独立规则。

If you really want to be able to pass a 2D array, you can do it with a templated constructor like this: 如果您确实希望能够传递2D数组,则可以使用如下模板化的构造函数来实现:

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

And then you don't even need to pass the size explicitly: 然后,您甚至不需要显式传递大小:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM