结构体数组与结构体指针数组

Lop*_*pan 5 c data-structures

当我继续学习C语言时,我产生了疑问。使用每个元素是结构的数组与使用每个元素是相同类型的结构的指针的数组之间的区别是什么。在我看来,您可以同等使用两者(尽管在指针中您必须处理内存分配)。在这种情况下,有人可以解释一下吗?

谢谢。

chq*_*lie 6

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

结构数组具有以下优点:

  • 使用一步就可以轻松动态地分配这样的数组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所暗示的,可以通过一方面分配结构数组和指向第一个数组元素的单独指针数组,来结合两种方法的一些优点。这是一种实现排序顺序,甚至使用单独的指针数组(例如数据库索引)实现多个伴随的排序顺序的便捷方法。