将指针传递给C中的指针

编译:

#include  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  void f(int ** v) { } int main() { int * v[2]; f(v); return 0; } 

在我看来,数组的更深层次必须在编译时解决,有人可以详细说明它吗?

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

原因与内存布局有关。 你看,如果aT *类型,则a[i]转换为*(a + sizeof(T) * i) (假设直接添加指针而不进行缩放); 但如果aT [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) 。 内存布局不再兼容。

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

在执行v++ ,必须通知编译器,是否通过sizeof(int)array_length*sizeof(int)递增地址