以下声明有效。
struct node
{
int a;
struct node *next;
};
但是,当我们定义以下内容时,它会给出错误。
"error: field ‘next’ has incomplete type"
为什么会这样?
struct node
{
int a;
struct node next; /* Not a pointer */
};
答案 0 :(得分:2)
您不能拥有将自己包含为成员的结构:
struct node
{
int a;
struct node next;
};
想想这个问题:如果可能的话,这种结构的大小是多少? struct node
包含struct node next
作为成员,然后成员next
也会包含struct node
类型的成员,依此类推,依此类推...是无限的。
答案 1 :(得分:2)
struct node
中的节点是" struct标签",在您编写它时,它会创建一个"不完整类型":一个结构变量,此时不是声明但未定义。在结构的最终};
之前,类型尚未完成。
在C中,通过使用指向该类型的指针,即使在完全定义之前,也可以引用不完整类型。但是,您不能分配该类型的变量(实例),因为尚未定义实际的结构定义。 (它与C ++中的抽象基类完全相同,如果您熟悉它们的话。)
所以当你写
struct node {
int a;
struct node *next;
};
行struct node *next
表示"这里是指向结构节点的指针,即使我不知道该类型是如何定义的#34;。但是你不能在同一类型的结构定义中声明类型struct node
的变量,只是因为你在创建它之前不能使用它。
答案 2 :(得分:1)
你的第二个声明将定义一个无限深度嵌套的结构,这是不可能的。
答案 3 :(得分:1)
这与类/结构类型的前向声明的情况相同:
struct node;
struct node* node_ptr; /* is valid */
struct node node_instance; /* is invalid */
所以struct node;
基本上说:嘿,在这个文件之外的某处定义了一个结构。类型有效,可以使用指针,但不能实例化对象。
这是因为指针的大小是已知的并且特定于目标体系结构(例如32或64位)。在宣布之前,结构的大小是未知的。
当您声明类型completey时,您将被允许声明该类型的对象:
struct node {
int a;
struct node* b; /* this will work, but the size of struct is unknown yet */
}
struct node* node_ptr; /* this works always with full and forward declarations */
struct node node_object; /* now, the size of struct is known, so the instance may be created */
答案 4 :(得分:0)
它应该是这样的:
struct node {
int a;
struct node *next;
};
这有效,
但是
struct node {
int a;
struct node next;
};
编译器无法理解因为node
变为递归结构,并且编译器不知道要为node
分配多少内存。
但是,如果使用指针,它会理解指针的大小等于要寻址的内存的大小,因此保留该空间,而不管node
是否是完整的结构。 / p>
答案 5 :(得分:0)
指针存储地址,struct具有结构。如果声明为struct,那将是递归的和无限的。如果像指针一样声明它指向其他地方的其他结构。
答案 6 :(得分:0)
节点内的无限节点?那有意义吗? " struct node"?
的大小是多少?