2017-02-19 122 views
4

随着我继续学习C语言,我有了疑问。使用数组中的每个元素是一个结构并使用一个数组中的每个元素都是指向相同类型的结构的指针之间的区别。在我看来,你可以同时使用两者(尽管在指针中你必须处理内存分配)。有人可以解释我在哪种情况下最好使用其中一种?结构体数组与指向结构体的指针数组

谢谢。

+3

一个示例:使用'qsort'对指针数组进行排序可能比对结构数组进行排序更快(如果结构体非常大),因为交换两个指针会比交换两个结构更快。 – user3386109

+3

^OTOH,在结构数组上的顺序传递将更加缓存友好,并且不需要在每一步都有额外的间接寻址。 – StoryTeller

+1

我不认为这个问题过于宽泛:每种方法的优缺点都存在某种程度的个人意见,但问题在于真正的询问,并列出两种解决方案的相关特征似乎是可行的。 – chqrlie

回答

4

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

阵列具有这些长处:

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

他们也有缺点:

  • 数组的大小必须明确传递,因为没有办法从指针数组有多少元素已经告诉。
  • 表达p[i].member产生一个乘法,这可能是在某些体系结构昂贵,如果结构的大小不是2
  • 改变元素的顺序的功率是昂贵的,因为它可能涉及复制大量的存储器。

使用指针的阵列具有以下优点:

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

和以下缺点:

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

EDIT:作为暗示由David保龄球,可以通过分配的结构的一方面的阵列,并且指向所述第一数组的元素的指针的一个单独的阵列结合一些的这两种方法的优点。这是一种实现排序顺序的方便方法,甚至可以使用单独的指针数组(如数据库索引)实现多个伴随排序顺序。