当struct中的指针指向struct本身时,C如何解析循环定义?

时间:2017-03-06 01:36:53

标签: c

我已经习惯了以下代码。

但C编译器如何解决循环定义问题?或者这个问题真的存在吗?

struct node {
    int data;
    struct node *next; // circular definition for "struct node" type?
};

ADD 1

或者,在32位机器上,我是否可以将struct node * next成员视为32位无符号整数类型的成员?这让我感觉好多了。

ADD 2

我认为循环定义的原因是,当编译器遇到类似next -> datanext -> next的内容时,它必须知道要添加到每个成员的确切偏移量 next指针,用于获取每个成员的正确位置。这种计算需要了解每个成员的类型。因此,对于成员next,可能会出现循环定义问题:

  

next的类型为struct node *struct node类型   包含nextnext的类型为struct node * ...

ADD 3

编译器如何计算sizeof(struct node)

ADD 4

嗯,我认为理解这个看似圆形的问题的关键概念是,指针的大小与它指向的类型无关。并且特定计算机上的大小固定。在编译时,指针的类型有意义,编译器可以生成指针计算指令。

2 个答案:

答案 0 :(得分:7)

nextstruct node *,它只是一个指针,而不是struct node,因此没有实际的循环定义。不需要结构的细节来弄清楚如何指向它。

要解决您的附录:

  1. 虽然这或多或少准确并可能有效,但标准并不保证,你不应该这样做。
  2. 同样,struct nodestruct node *是完全不同的类型。 struct node *不包含任何其他对象。

答案 1 :(得分:1)

让我按顺序回答你的问题:

  

但C编译器如何解决循环定义问题?

struct node *next;不是循环定义,struct node是不完整的类型,next被定义为类型struct node *的成员,它只是一个指针。

  

或者这个问题真的存在吗?

不,不是真正的问题。事实上,您可以将成员定义为指向任何未定义结构的指针。

  

或者,在32位机器上,我是否可以将struct node *next成员视为32位无符号整数类型的成员?

您不应对结构构件的实际尺寸,偏移或对齐做出任何假设。 32位机器的指针大小不是32位,只要你将它们用作指针而不是整数就没关系。

  

我认为循环定义的原因是,当编译器遇到next->datanext->next之类的东西时,它必须知道要添加到next指针的每个成员的确切偏移量获得每个成员的正确位置。

这是正确的,但是当编译器解析这样的代码时,结构定义已经完成,它可以确定datanext成员的偏移量。

  

编译器如何计算sizeof(struct node)

在解析结构定义之后,编译器具有计算结构实例大小所需的所有信息。对于这样的计算,假设所有指向结构和/或联合的指针具有相同的大小。

  

嗯,我认为理解这个看似循环的问题的关键概念是,指针的大小与它指向的类型无关。并且尺寸固定在特定的机器上。指针的类型仅在编译时有意义,编译器才能生成指针计算指令。

指针大小 与其指向的类型相关,并且在某些体系结构上,不同的指针类型可能具有不同的大小。然而,C标准规定了一些限制因素:

  • 所有指针类型都可以转换为void *并返回。
  • 指向所有结构和联合的指针具有相同的大小。

在大多数现代架构上,特别是在Posix兼容系统上,所有标准指针类型都具有相同的大小。