为什么编译器不能将int [] []转换为int **,这在理论上是可行的?

时间:2012-01-27 10:52:57

标签: c

在C中,二维数组的存储方式与线性数组一样,但它们使用双指针进行索引。也就是说,如果我们定义

int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}.

a首先指向类似

的内容
{p1 = 0x7fff5fbffb58 , p2 = 0x7fff5fbffb70, p3 = 0x7fff5fbffb88}

然后p1指向1,p2指向4,p3指向7。

那么为什么编译器不允许从二维数组转换为双指针,这在理论上是可行的?尽管二维数组是逐个存储的,但索引信息总是可以传递给任意双指针。

5 个答案:

答案 0 :(得分:9)

这在理论上是不可能的。不使用双指针索引2d数组 - 编译器将其转换为一个索引。例如,如果您有int a[3][5],并且访问a[i][j],则编译器会将其转换为((int[])a)[5*i+j]。 (你的解释是完全错误的)

由于所有这些,如果要将int[][]转换为int**,则需要分配内存以保存所有子阵列的地址,并获取其地址。只有(int**)a无效。

答案 1 :(得分:1)

您的示例说明了编译器无法执行此操作的原因:p1p2p3的值计算,未存储。编译器知道p1的地址,并在掌握数组大小知识的情况下计算其他两个地址。另一方面,对于双指针,所有三个指针都需要存储在顺序存储器位置,形成一个指针数组。

答案 2 :(得分:0)

int[][]转换为int**需要引入充满数据的int指针数组。我们喜欢c因为没有明确要求而没有采取这种自由。

答案 3 :(得分:0)

因为C是这样说的。

  

(C99,6.3.2.1p3)“除非它是sizeof运算符或一元&的操作数。   运算符,或者是用于初始化数组的字符串文字,具有类型“数组类型”的表达式将转换为类型为“指向类型的指针”的表达式,该表达式指向数组对象的初始元素,而不是左值。“

此转换规则对于数组数组不是递归的。

转换后,int [N][M]类型的对象的值为int (*)[M]

答案 4 :(得分:0)

因为是两件不同的事情。 int a [3] [3] ,在内存中是9个元素的数组 int **你应该有一个包含3个元素的指针数组,每个元素都会指向另一个包含数据的数组。