我对C数组如何存储在内存中存在疑问。但是我在提一个问题时遇到了麻烦,所以这是我最好的尝试。我的英语有问题。假设我们有一个三维数组:
int foo[2][3][4];
可以使用数组或指针符号访问元素:
foo[i][j][k]
*(*(*(foo + i) + j) + k)
我们可以将数组视为指向int指针的指针,或者例如指向诸如(* a)[2] [3]之类的二维数组的指针。
我认为的问题是:我本以为要“提取”数组中的值,我们只需要解引用数组的顶层(即[i])一次,第二遍级别(即[j])两次,第三级别(即[k])三次。但是实际上,我们总是必须取消引用3次才能获得任何值。为什么是这样?还是这种情况?
我试图想象内存中的数组结构。
很抱歉表达我的意思。
答案 0 :(得分:2)
您的数组foo
的数组在内存中的排列方式如下:
+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+----------+ | foo[0][0][0] | foo[0][0][1] | foo[0][0][2] | foo[0][0][3] | foo[0][1][0] | foo[0][1][1] | foo[0][1][2] | foo[0][1][3] | ... etc. | +--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+----------+
foo[0][0][0]
将位于最低的内存位置,foo[1][2][3]
将位于最高的内存位置。
还有一个重要的注意事项:数组不是指针。它可以衰减指向其第一个元素的指针,但是请不要“想”一个数组作为指针。
另一个重要说明:指针&foo
,&foo[0]
,&foo[0][0]
和&foo[0][0][0]
都指向相同的位置,但是它们都是不同的类型< / em>,这使它们在语义上有所不同:
&foo
的类型为int (*)[2][3][4]
&foo[0]
的类型为int (*)[3][4]
&foo[0][0]
的类型为int (*)[4]
&foo[0][0][0]
的类型为int *
最后一个关于数组到指针衰减的注释,它仅一步发生。这意味着foo
衰减为&foo[0]
,foo[0]
衰减为&foo[0][0]
,而foo[0][0]
衰减为&foo[0][0][0]
。
答案 1 :(得分:1)
数组不是与存储位置(内存地址)一样简单,而是具有类型和布局的对象。 >
因此,在您的示例中,foo
是由3个数组组成的数组,其中4个数组为int
,其长度为2。*f
是 int
的4个数组,而**f
是int
的数组。
即使每个解引用级别都提供相同的内存地址,但它们却有所不同,因为它们具有不同的类型,因此,同一位置的数据应以不同的方式解释。