0

编译:

#include <stdlib.h>


void f(int ** v)
{
}

int main()
{
    int v[2][3];
    f(v);
    return 0;
}

失败:

g.cpp:13:8: error: cannot convert ‘int (*)[3]’ to ‘int**’ for argument ‘1’ to ‘void f(int**)’

但是通过了以下更改:

#include <stdlib.h>


void f(int ** v)
{
}

int main()
{
    int * v[2];
    f(v);
    return 0;
}

在我看来,数组的更深维度必须在编译时解决,有人可以详细说明一下吗?

4

2 回答 2

2

C 和 C++ 自动将数组强制转换为指针。该错误是由于这种强制仅发生一次(即仅在第一级)。这意味着int [10]将被强制执行int *;但int [10][10]最多可以强制转换为int *[10].

原因与内存布局有关。你看,a[i]转换为*(a + sizeof(T) * i)if ais 的类型T *(假设添加到指针直接添加而不缩放);但如果a是 类型T [N],则a[i]转换为*(&a[0] + i)。因此,可以通过获取第一个元素的地址T [N]将类型值强制转换为类型值T *——在这种情况下,内存布局是兼容的。

但是,二维数组aT [2] [4]例如 类型)的存储方式与双指针(类型T **)的存储方式不同。在第一种情况下,你有四个元素,在内存T [0][0]T [0][3]布局,然后是T [1][0]toT [1][3]等等,模对齐。在第二种情况下,您只有一堆指针(指向T)一个接一个地布置。在第一种情况下,a[i][j]将降低到*(&a[0][0] + sizeof(T) * 4 * i + sizeof(T) * j),而在第二种情况下,它将降低到*(*(a + sizeof(T) * i) + sizeof(T) * j). 内存布局不再兼容。

于 2013-01-10T21:23:49.970 回答
0

指向 int 的指针与指向数组的指针不同。

执行此操作时v++,必须通知编译器是否将地址递增sizeof(int)或递增array_length*sizeof(int)

于 2013-01-10T19:12:44.383 回答