【问题标题】:Self referring structure declaration自引用结构声明
【发布时间】:2014-09-12 07:09:28
【问题描述】:

以下声明有效。

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

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

"error: field ‘next’ has incomplete type"

为什么会这样?

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

【问题讨论】:

  • 是的,我已经更正了

标签: c pointers struct


【解决方案1】:
struct node 中的

node 是一个“结构标记”,在您编写它时会创建一个“不完整类型”:此时尚未声明但未定义的结构变量。在你的结构体的最后一个 }; 之前类型不完整。

在 C 中,即使在完全定义之前,也可以通过使用指向该类型的指针来引用不完整的类型。但是,您不能分配该类型的变量(实例),因为尚未定义实际的结构定义。 (如果你熟悉的话,它的工作方式与 C++ 中的抽象基类完全一样。)

所以当你写的时候

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

struct node *next 行的意思是“这是一个指向结构节点的指针,尽管我还不知道该类型是如何定义的”。但是你不能在相同类型的结构定义中声明struct node 类型的变量,因为你不能在创建它之前使用它。

【讨论】:

    【解决方案2】:

    您不能拥有包含自身作为成员的结构:

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

    想想这个问题:如果可能,这种结构的大小是多少? struct node 包含 struct node next 作为成员,然后成员 next 也将包含 struct node 类型的成员,依此类推……大小将是无限的。

    【讨论】:

      【解决方案3】:

      您的第二个声明将定义一个无限深嵌套的结构,这是不可能的。

      【讨论】:

      • 其实我的问题是如果指针类型声明没有错误,为什么声明结构会出错?
      • 第一个声明是有效的,因为无论引用的结构如何,指针的大小都是恒定的。另一方面,不可能有一个嵌套在其自身中的结构,因为生成的结构将是无限大小的。
      【解决方案4】:

      这与前向声明类/结构类型的情况相同:

      struct node;
      
      struct node* node_ptr; /* is valid */
      struct node node_instance; /* is invalid */
      

      所以struct node; 基本上说:嘿,在这个文件之外的某个地方定义了一个结构。类型有效,可以使用指针,但不能实例化对象。

      这是因为指针的大小是已知的并且特定于目标架构(例如 32 位或 64 位)。在声明之前,结构的大小是未知的。

      当你完全声明类型时,你将被允许声明该类型的对象:

      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 */
      

      【讨论】:

        【解决方案5】:

        应该是这样的:

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

        这行得通,

        但是

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

        编译器无法理解为node变成递归结构,编译器不知道要为node分配多少内存。

        但是,如果您使用指针,它会理解指针的大小等于要寻址的内存大小,因此会保留该空间,而不管 node 是否是一个完整的结构。

        【讨论】:

          【解决方案6】:

          指针存储地址,struct 有结构。如果声明为 struct 它将是递归和无限的。如果声明为指针,则它引用其他地方的其他结构。

          【讨论】:

            【解决方案7】:

            一个节点中有无限个节点?那有意义吗? “结构节点”的大小是多少?

            【讨论】:

              猜你喜欢
              • 2019-12-30
              • 2010-11-01
              • 1970-01-01
              • 1970-01-01
              • 2011-08-01
              • 1970-01-01
              • 2011-07-09
              • 2018-04-03
              相关资源
              最近更新 更多