编译:
#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;
}
在我看来,数组的更深层次必须在编译时解决,有人可以详细说明它吗?
答案 0 :(得分:2)
C和C ++自动将数组强制转换为指针。该错误是由于这种强制仅发生一次(即仅在第一级)的事实引起的。这意味着int [10]
将被强制转移到int *
;但int [10][10]
最多可以强制转换为int *[10]
。
原因与内存布局有关。您看,如果a[i]
属于*(a + sizeof(T) * i)
类型,a
会转换为T *
(假设添加指针直接添加而不进行缩放);但如果a
属于T [N]
类型,则a[i]
会转换为*(&a[0] + i)
。因此,通过获取第一个元素的地址,可以将类型T [N]
的值强制转换为类型T *
的值 - 在这种情况下,内存布局是兼容的。
但是,二维数组a
(类型为T [2] [4]
)的存储方式与双指针(类型T **
)的存储方式不同。在第一种情况下,您有四个元素,T [0][0]
到T [0][3]
在内存中排列,然后是T [1][0]
到T [1][3]
,依此类推,模数对齐。在第二种情况下,你只有一堆指针(到T
)一个接一个地布局。在第一种情况下,a[i][j]
将降低到*(&a[0][0] + sizeof(T) * 4 * i + sizeof(T) * j)
,而在第二种情况下,它会降低到*(*(a + sizeof(T) * i) + sizeof(T) * j)
。内存布局不再兼容。
答案 1 :(得分:0)
指向int的指针与指向数组的指针不同。
执行v++
时,必须通知编译器,是否按sizeof(int)
或array_length*sizeof(int)
增加地址