当struct中的指针指向struct本身时,C如何解析循环定义?
我已经习惯了以下代码。
但是C编译器如何解决循环定义问题? 或者这个问题真的存在吗?
struct node { int data; struct node *next; // circular definition for "struct node" type? };
添加1
或者,在32位机器上,我可以稍微将struct node * next
成员视为32位无符号整数类型的成员吗? 这让我感觉好多了。
添加2
我想到循环定义的原因是,当编译器遇到类似next -> data
或next -> next
,它必须知道要添加到next
指针的每个成员的确切偏移量 ,以获得每个成员的正确位置。 而这种计算需要了解每个成员的类型 。 因此,对于next
的成员,可能会出现循环定义问题:
接下来的类型是
struct node *
,struct node
类型包含next
,next
类型是struct node *
…
添加3
编译器如何计算sizeof(struct node)
?
添加4
好吧,我认为理解这个看似循环的问题的关键概念是,指针的大小与它指向的类型无关。 并且尺寸固定在特定的机器上。 指针的类型仅在编译时有意义,以便编译器生成指针计算指令。
next
是一个struct node *
,它只是一个指针,而不是一个struct node
,因此没有实际的循环定义。 不需要结构的细节来弄清楚如何指向它。
要解决您的附录:
- 虽然这或多或少准确并且可能会起作用,但标准并不保证,你不应该这样做。
- 同样,
struct node
和struct node *
是完全不同的类型。struct node *
不包含任何其他对象。
让我按顺序回答你的问题:
但是C编译器如何解决循环定义问题?
struct node *next;
不是循环定义, struct node
是不完整的类型, next
定义为类型为struct node *
的成员,它只是一个指针。
或者这个问题真的存在吗?
不,不是真正的问题。 事实上,您可以将成员定义为指向任何未定义结构的指针。
或者,在32位机器上,我可以稍微将
struct node *next
成员视为32位无符号整数类型的成员吗?
您不应对结构构件的实际尺寸,偏移或对齐做出任何假设。 32位机器的指针大小可能不是32位,只要你将它们用作指针而不是整数就没关系。
我认为循环定义的原因是,当编译器遇到类似
next->data
或next->next
,它必须知道要添加到next
指针的每个成员的确切偏移量以获得每个成员的正确位置。
这是正确的,但是当编译器解析这样的代码时,结构定义就完成了,它可以确定data
和next
成员的偏移量。
编译器如何计算
sizeof(struct node)
?
在解析结构定义之后,编译器具有计算结构实例大小所需的所有信息。 对于这样的计算,假设所有指向结构和/或联合的指针具有相同的大小。
好吧,我认为理解这个看似循环的问题的关键概念是,指针的大小与它指向的类型无关。 并且尺寸固定在特定的机器上。 指针的类型仅在编译时有意义,以便编译器生成指针计算指令。
指针大小与它指向的类型相关,并且在某些体系结构上,不同的指针类型可能具有不同的大小。 然而,C标准规定了一些限制:
- 所有指针类型都可以转换为
void *
和back。 - 所有结构和工会的指针都有相同的大小。
在大多数现代架构上,特别是在符合Posix的系统上,所有标准指针类型都具有相同的大小。