当你写
double m[3][4]
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
编译器实际上创建了一个双精度数组,就像您编写的一样
double _m[] = {2, 4, 5, 7, 4, 5, 1, 12, 9, 12, 13, -4};
但是,由于 C/C++ 类型系统,编译器记住m
's 的类型是double [3][4]
. 特别是它记得大小 3 和 4。
当你写
m[i][j]
编译器将其替换为
_m[i * 4 + j];
(4
来自 中的第二个大小double [3][4]
。)例如,
m[1][2] == 1
以及_m[1 * 4 + 2] == _m[6] == 1
。
正如其他人所说, adouble**
是一种不同的类型,它不携带尺寸。要考虑double** a
为 3 x 4 矩阵,a[0]
和a[1]
必须
a[2]
是指向double
(即double*
)指向相应行的第一个元素的指针。你可以用
double* rows[] = { &m[0][0], &m[1][0], &m[2][0] };
double** a = &rows[0];
一个简单的演员表不会创建rows
上面的变量。让我介绍其他替代(但等效)的方法来定义rows
double* rows[] = { &m[0][0], &m[0][0] + 4, &m[0][0] + 2 * 4};
double* rows[] = { &_m[0], &_m[4], &_m[2 * 4]};
如您所见,只需要第二种尺寸(即4
)。通常,对于多维数组,除了第一个之外的所有大小都是必需的。因此,一维数组
double x[4] = { 1, 2, 3, 4 };
可以隐式转换为double*
double* y = x;
利用这个事实,我们也可以写
double* rows[] = { _m, _m + 4, _m + 2 * 4};
事实上,_m
被转换为double*
指向m[0]
。然后, in _m + 4
,
_m
is 被转换为double*
指向m[0]
并添加到 this 的指针4
。因此,_m + 4
是第四个 double 之后的指针
_m[0]
,_m[4]
以此类推。
到目前为止,我已经解释了为什么不能将 a double [3][4]
(或任何其他大小)转换为double**
. 现在,我将在您的特定情况下展示如何定义计算。
template <int N>
void calculate(double (&m)[N][N+1]) {
// use m as a double[N][N+1]
}
你打电话
calculate(m);
编译器会为你推导出大小N
。一般来说(即,当第二维不是 时N + 1
)你可以写
template <int N, int M>
void calculate(double (&m)[N][M]) {
// use m as a double[N][M]
}