为什么我们在自引用结构中使用指针?

时间:2018-01-29 21:07:39

标签: c pointers struct self-reference

为什么我们在自引用结构中使用指针?这是义务还是不是?如果没有,我们在struct中使用指向struct的指针与普通的struct定义相比有什么优势呢?

typedef struct _Struct {
  struct _Struct* next;  // do we really need this pointer?
} Struct;

3 个答案:

答案 0 :(得分:6)

指针具有固定大小,因此编译器可以在解析时确定结构_Struct的大小。

如果_Struct在物理上包含自身,则无法确定其大小,它是一个循环定义。

答案 1 :(得分:3)

结构包含作为外部结构的实例的成员是没有意义的。除了要求您声明一个不完整的类型之外,它将是无限的并且永远不会有足够的字节,因为您添加的每个实例也需要一个实例。

使用指针没问题;但是,这种方法通常用于创建链接列表。指针指向链中的下一个实例。

答案 2 :(得分:2)

您不能在结构定义中使用struct _Struct类型成员变量,因为它必须是完整类型才能执行此操作。但是,struct _Struct在声明符合}后才会完成。

但是对于指针,我们可以这样做,因为指针的大小是相同的,它是指向完整类型或不完整类型的指针 - 所以当编译器读取它们时,它可以决定它的大小。 (与它自己引用的情况不同)。

它必须是指针而不是结构本身,因为类型尚未完成 - 不知道它的大小是什么。

支持我所说的话 - 来自standard§6.7.2.1p3

  

结构或联合 包含不完整或功能类型 的成员(因此,结构不得包含本身的实例,但可以包含指向其自身实例的指针),除了具有多个命名成员的结构的最后一个成员可能具有不完整的数组类型;这样的结构(以及可能递归地包含这种结构的成员的任何联合)不应该是结构的成员或数组的元素。

什么时候完成?来自§6.7.2.1p8

  

struct-or-union-specifier中struct-declaration-list的存在在转换单元中声明了一个新类型。 struct-declaration-list是结构或联合成员的一系列声明。如果struct-declaration-list不包含任何命名成员(直接或通过匿名结构或匿名联合),则行为未定义。 类型不完整,直到终止列表的}之后,然后完成。

如果有人问结构或联合的不完整类型是什么?来自standard§6.2.5p22

  

未知内容的结构或联合类型(如6.7.2.3中所述)是不完整的类型。

这就是为什么我们不能使用正在声明的结构的实例 - 因为只是它的大小是不可能知道的。