在C++中将表示2D数组的指针传递给函数

5

3
这个注释是错误的。double[3][3] 不能衰减为 double**(它会衰减为 (double*)[3])。 - kennytm
在 double **p_stuff 后尝试使用 new double *stuff[3] - George
这个C函数的签名是什么? - Erik
修改问题以反映我的意图..将这个double stuff[3][3]传递给一个C函数。 - Derek
我正在编写C函数...因此我可以根据需要更改签名。现在我的签名为(.....,double **p_stuff,...) - Derek
5个回答

15

关于编辑:如果要将double stuff[3][3]传递给C函数,您可以

1)传递整个2D数组的指针:

void dostuff(double (*a)[3][3])
{
// access them as (*a)[0][0] .. (*a)[2][2]
}
int main()
{
    double stuff[3][3];
    double (*p_stuff)[3][3] = &stuff;
    dostuff(p_stuff);
}

2) 传递第一个1D数组(即第一行)的指针和行数。

void dostuff(double a[][3], int rows)
{
// access them as a[0][0] .. a[2][2]
}
int main()
{
    double stuff[3][3];
    double (*p_stuff)[3] = stuff;
    dostuff(p_stuff, 3);
}

3) 传递指向第一行第一个值的指针,以及列和行的数量

void dostuff(double a[], int rows, int cols)
{
// access them as a[0] .. a[8];
}
int main()
{
    double stuff[3][3];
    double *p_stuff = stuff[0];
    dostuff(p_stuff, 3, 3);
}

(这个最后一个选项不是严格符合标准的,因为它将指针移动到一个一维数组(第一行)的元素之外)

如果那不是C函数的话,就还有更多的选择!


1
+1,作为对上一行的轻微扩展,在C++中您还可以通过引用传递数组,并且可以使用模板使代码独立于数组大小:template <std::size_t N, std::size_t M> void process( double (&a)[N][M] );如果您希望它能够处理不同的大小。根据需要混合和匹配:如果您只想允许平方数组,请使用单个模板参数。 - David Rodríguez - dribeas

3
你的赋值有误。 p_stuff; 是指向指针的指针,指向double,而stuff是二维数组(数组的数组)。
一个一维数组会衰变为指向其第一个元素的指针。一个二维数组会衰变为指向一维数组的指针。
试试这个:
double stuff[3][3];
double (*p_stuff)[3]; // pointer to array of 3 int
p_stuff = stuff;

1

double ** p_stuff; 对应于一个指向双精度浮点数的指针数组。double stuff[3][3]没有任何指针 - 它是一个二维双精度浮点数数组。


修改问题以反映我的意图..将这个double stuff[3][3]传递给一个C函数。 - Derek

0
除了Cubbi详细的回答之外,以下方法是将二维数组传递给函数的自然方式:
void dostuff(void *a1, int rows, int cols)
{
    double (*a)[cols] = (double (*)[cols]) a1;
    // access them as a[0][0] .. a[rows-1][cols-1];
}
int main()
{
    double stuff[3][3];
    dostuff(stuff, 3, 3);
}

你不需要提前转换它们,因为最新的C++(C++14)支持运行时大小的数组。


0

以下可能是您的答案:

#include <stdio.h>
#include <stdlib.h>

typedef unsigned int uint;
uint m[10][20];
uint **ppm;

int main() {
    int i;

    ppm = (uint **)m;
    for (i =0; i<10; ++i)ppm[i] = (uint *)&m[i];

    m[1][1] = 10;

    printf("0x%x vs 0x%x: %d vs %d\n", ppm,m, m[1][1], *(*(ppm+1)+1));

    return 0;
}

结果显示在控制台屏幕上:

0x6010a0 vs 0x6010a0: 10 vs 10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接