c - C 数组的结构如何

标签 c arrays

我有一个关于 C 数组如何存储在内存中的问题。但我在表达这个问题时遇到了困难,所以我尽力用语言表达它。我的英语有问题。假设我们有一个三维数组:

int foo[2][3][4];

可以使用数组或指针表示法访问元素:

foo[i][j][k]    
*(*(*(foo + i) + j) + k)

我们可以将数组视为指向 int 指针的指针,或者例如指向 (*a)[2][3] 等二维数组的指针。

我的想法中的问题是这样的:我本以为为了“提取”数组中的值,我们只需取消引用数组的顶层(即 [i])一次,第二次级别(即[j])两次,第三级别(即[k])三次。但实际上我们总是必须取消引用三次才能获得任何值。为什么是这样?还是事实确实如此?

我尝试想象内存中的数组结构。

对于我表达这一点的糟糕方式表示歉意。

最佳答案

数组的数组的数组 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] 都指向同一位置,但它们都是不同的类型,这使得它们在语义上不同:

  • &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]

关于c - C 数组的结构如何,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52467167/

相关文章:

c - 输入由空格分隔的 int 并将它们传递给 int 数组

c - 为什么这个函数被视为委托(delegate)?

C程序,从旋转角度得到笛卡尔坐标

c - 返回 char* 时出现段错误

c - VirtualBox 无法加载 .img 或 .flp 文件

c++ - 如何从文本文件中读取字符串类型(不是数字)并将数据存储在 C++ 数组中?

c - 当结构体的属性是指向另一个结构体的指针时

c - GNU ARM 汇编程序在错误消息中给出看似无关的寄存器

c - 错误结果私有(private)数组 openmp

java - 返回二维数组 java.lang.Object 中任意对象的索引。