自我引用结构声明

时间:2014-09-12 07:09:28

标签: c pointers struct

以下声明有效。

struct node
{
    int a;
    struct node *next;
};

但是,当我们定义以下内容时,它会给出错误。

"error: field ‘next’ has incomplete type"

为什么会这样?

struct node
{
    int a;
    struct node next; /* Not a pointer */   
};

7 个答案:

答案 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"?

的大小是多少?