将指针传递给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]
。
原因与内存布局有关。 你看,如果a
是T *
类型,则a[i]
转换为*(a + sizeof(T) * i)
(假设直接添加指针而不进行缩放); 但如果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)
。 内存布局不再兼容。
指向int的指针与指向数组的指针不同。
在执行v++
,必须通知编译器,是否通过sizeof(int)
或array_length*sizeof(int)
递增地址