结构数组与结构数组的指针数组

时间:2017-02-19 14:58:01

标签: c data-structures

当我继续学习C语言时,我有一个疑问。使用其中每个元素是结构的数组和使用其中每个元素是指向同一类型结构的指针的数组之间的区别。在我看来,你可以平等地使用它们(虽然在指针中你必须处理内存分配)。有人可以解释我在哪种情况下最好使用其中一种吗?

谢谢。

1 个答案:

答案 0 :(得分:5)

结构数组和结构指针数组是组织内存的不同方法。

结构阵列具有以下优点:

  • 使用struct s *p = calloc(n, sizeof(*p));一步动态分配这样的数组很容易。
  • 如果数组是封闭结构的一部分,则根本不需要单独的分配代码。本地和全局数组也是如此。
  • 数组是一个连续的内存块,指向下一个和前一个元素的指针可以很容易地计算为struct s *prev = p - 1, *next = p + 1;
  • 访问数组元素成员可能会更快,因为它们在内存中很接近,从而提高了缓存效率。

他们也有缺点:

  • 必须明确传递数组的大小,因为无法从指向数组的指针告诉它有多少元素。
  • 表达式p[i].member生成乘法,如果结构的大小不是2的幂,则在某些体系结构上可能代价很高。
  • 更改元素的顺序是昂贵的,因为它可能涉及复制大量内存。

使用指针数组具有以下优点:

  • 可以通过分配额外元素并将其设置为NULL来确定数组的大小。此约定用于提供给argv[]函数的main()命令行参数数组。
  • 如果未使用上述约定,并且元素的数量单独传递,则NULL指针值可用于指定缺少的元素。
  • 只需移动指针即可轻松更改元素的顺序。
  • 可以使多个元素指向相同的结构。
  • 重新分配数组更容易,因为只有指针数组需要重新分配,可选地保持单独的长度和大小计数以最小化重新分配。增量分配也很容易。
  • 表达式p[i].member生成一个简单的移位和一个额外的内存访问,但可能比结构数组的等效表达式更有效。

以及以下缺点:

  • 分配和释放这个间接数组更麻烦。需要一个额外的循环来分配和/或初始化数组指向的结构。
  • 对结构元素的访问涉及额外的内存间接。如果在同一个函数中访问多个成员,编译器可以为此生成有效的代码,但并非总是如此。
  • 指向相邻结构的指针不能从指向给定元素的指针派生。

编辑:正如David Bowling所暗示的那样,人们可以通过一方面分配一组结构和一个指向第一个元素的单独指针数组来结合两种方法的一些优点。阵列。这是一种实现排序顺序的方便方法,甚至是带有单独指针数组的多个伴随排序顺序,如数据库索引。