【问题标题】:Difference between multi dimensional arrays and array of pointers多维数组和指针数组的区别
【发布时间】:2017-03-07 21:53:20
【问题描述】:

我一直相信在 C 中:

int a[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

指的是一个数组数组,在内存中存储了十五个连续的块,但a[0]是指向a[0][0]的指针,a[1]是指向a[1][0]的指针,依此类推。所以我认为它类似于一个指针数组。它们有什么区别?

【问题讨论】:

标签: c arrays


【解决方案1】:

数组和指针在 C(和 C++)中有着非常奇妙而亲密的关系。在大多数情况下,如果您有一个“X 数组”,那么它将被静默转换为指向该数组第一个元素的“指向 X 的指针”。

你的信念

int a[5][3];

创建一个数组数组是完全正确的。根据声明,它是一个array of 5 arrays of 3 ints,它在内存中占用了15个连续整数。

你出错的地方在于相信a[0] 是一个指针。事实上,a[0]a 的第一个子数组,它本身就是一个array of 3 ints。但是,由于指针和数组之间奇怪的关系,表达式a[0] 几乎总是被转换为指针。

数组数组和指针数组之间的主要区别之一在于数组元素所在的位置。数组数组将始终占用一个连续的内存块,但指针数组中的指针将各自引用它们自己的(通常是不相交的)内存块。

【讨论】:

  • 如果您要添加一个注释“并且它在内存中占用 15 个连续整数”,那么说“在 C 实现中”会有所帮助。
  • 指针数组(指向数组)也可以描述锯齿状数组,而不是像 user1369975 描述的二维数组。
  • @JimmyHoffa:这个添加有什么帮助?
  • @BartvanIngenSchenau 在许多语言中说数组占用内存中的连续空间是不准确的,你说的是 C,所以在这里它是准确的,但如果你只是将该陈述限定为关于 C,它会确保将来没有可怜的绿色 Ruby 或 PHP 开发人员会误解您的陈述
  • @JimmyHoffa:这个问题被清楚地标记为 C 问题(并且可以说属于 SO)。如果 PHP 或 Ruby 开发人员因为没有注意标签而得到错误的印象,我认为这是他们的问题。作为旁注,我几乎不赞成您的回答,因为 C 中的数组绝对不是高级构造。
【解决方案2】:

数组和指针大致等同于同一事物。当您声明一个数组 N long 时,您正在分配一块内存 N long(乘以值类型的大小)并返回指向第一个元素的指针。然后像arr[2] 这样的表达式通过从第一个指针向前计数来从该内存中检索一个值。如果您有一个数组数组,那么您在第一个数组(在您的a 数组中)中存储的所有内容都是指向其他数组存储位置的指针。 (也就是说,我相信它们应该像你说的那样在一个连续的块中)

这对解释有帮助吗?

【讨论】:

  • 无指针 != 数组。数组不是一流的,在表达式中使用时会衰减为指针。这种差异通过 extren 声明和 sizeof 暴露出来
  • 加入The Whiteboard聊天如果你想了解你的答案发生了什么
  • @Katana314:您在 P.SE 获得的反对票很可能是由您的第一句话触发的。将指向数组的指针等同起来是 C 语言中最难摆脱的误解之一。如果你认为指针和数组是一样的,那么你被难以理解的错误所困扰。
【解决方案3】:
 int a[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

这是一个真正的二维数组:已预留 15 个int 大小的位置,并使用常规矩形下标来查找元素a[row][col]

int *b[5];

这是一个指针数组,它分配了 5 个指针并且未初始化,但 a[3][2]b[3][2] 在语法上都是对单个 int 的合法引用。

假设b 的每个元素都 指向一个三元素数组,那么会有15 ints留出,再加上五个单元格 指针。

指针数组的重要优点是数组的行可以是 不同的长度。即b的每个元素不需要指向一个三元素向量,有些 可能指向两个元素,有的指向 9,有的根本没有。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 2012-07-15
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多