C++铸造静态二维双数组加倍**

Gre*_*zak 9 c++ double pointers casting

我的程序中有这样的矩阵:

double m[3][4] = 
    {
        {2, 4, 5, 7},
        {4, 5, 1, 12},
        {9, 12, 13, -4}
    };
Run Code Online (Sandbox Code Playgroud)

而且我想把它投入到double**打字中.

我已经尝试过简单double** a = (double**)m;,但它不起作用(当我尝试读取任何值时,我得到"访问冲突读取位置0x00000000.",这意味着我正试图从NULL地址读取.

我找到了几乎可行的解

double *b = &m[0][0];
double **c = &b;
Run Code Online (Sandbox Code Playgroud)

当我读取字段时它工作c[0][any] 但是当我尝试从字段读取值时,会出现相同的NULL地址读取问题c[1][0].

double m[3][4]数组转换为键入的正确方法是什么double**

编辑:你说这是不可能的.所以我会稍微改变一个问题.如何将二维双数组作为参数传递给函数?我的功能有原型:

void calculate(double **matrix, int n); //where matrix size is always n by n+1 
Run Code Online (Sandbox Code Playgroud)

它在动态分配的数组中运行良好.我怀疑只有它的工作方式是分配新的动态数组并将原始静态数组复制一个元素......

Mar*_*som 14

你不能.

符号表示double**指针数组.你没有指针数组,你有一组双打数组.


Vau*_*ato 9

你不能只是投射数组.你将不得不创建这样的东西:

double m[3][4] = 
    {
        {2, 4, 5, 7},
        {4, 5, 1, 12},
        {9, 12, 13, -4}
    };

double *marray[3] = {m[0],m[1],m[2]};
calculate(marray,3);
Run Code Online (Sandbox Code Playgroud)

或者您可以使用循环:

const size_t n = 3;
double *marray[n];
for (size_t i=0; i!=n; ++i) {
    marray[i] = m[i];
}
calculate(marray,n);
Run Code Online (Sandbox Code Playgroud)


Cas*_*eri 7

当你写作

double m[3][4] 
    {
        {2, 4, 5, 7},
        {4, 5, 1, 12},
        {9, 12, 13, -4}
    };
Run Code Online (Sandbox Code Playgroud)

编译器实际上创建了一个双精度数组,就像你写的那样

double _m[] = {2, 4, 5, 7, 4, 5, 1, 12, 9, 12, 13, -4};
Run Code Online (Sandbox Code Playgroud)

但是,由于C/C++类型系统,编译器会记住它m的类型是double [3][4].特别是它记住尺寸3和4.

当你写作

m[i][j]
Run Code Online (Sandbox Code Playgroud)

编译器替换它

_m[i * 4 + j];
Run Code Online (Sandbox Code Playgroud)

(该4来自于所述第二尺寸double [3][4].)例如, m[1][2] == 1_m[1 * 4 + 2] == _m[6] == 1为好.

正如其他人所说,a double**是一种不同的类型,不带有它的尺寸.考虑double** a作为一个3×4矩阵,a[0],a[1]a[2]必须是指向double(即,double*)指向相应行的第一个元素.你可以实现这一目标

double* rows[] = { &m[0][0], &m[1][0], &m[2][0] };
double** a = &rows[0];
Run Code Online (Sandbox Code Playgroud)

简单的强制转换不会创建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]};
Run Code Online (Sandbox Code Playgroud)

如您所见,只需要第二个尺寸(即4).通常,对于多维阵列,除了第一个之外都需要所有尺寸.出于这个原因,一维阵列

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

可以隐式转换为 double*

double* y = x;
Run Code Online (Sandbox Code Playgroud)

使用这个事实我们也可以写

double* rows[] = { _m, _m + 4, _m + 2 * 4};
Run Code Online (Sandbox Code Playgroud)

的确,_m转换为double*指向m[0].然后,在_m + 4, _mis被转换为double*指向m[0]并指向它的指针4.因此,_m + 4是一个指针第四双以下 _m[0],这是_m[4]等.

到目前为止,我已经解释了为什么你不能将double [3][4](或任何其他尺寸)投射到一个double**.现在,我会在您的特定情况下显示如何定义计算.

template <int N>
void calculate(double (&m)[N][N+1]) {
   // use m as a double[N][N+1]
}
Run Code Online (Sandbox Code Playgroud)

你打电话

calculate(m);
Run Code Online (Sandbox Code Playgroud)

并且编译器将为您推断出大小N.一般情况下(即第二个维度不是N + 1),你可以写

template <int N, int M>
void calculate(double (&m)[N][M]) {
   // use m as a double[N][M]
}
Run Code Online (Sandbox Code Playgroud)