代码之家  ›  专栏  ›  技术社区  ›  Senthil Kumaran

C类型语法如何避免循环定义?

  •  1
  • Senthil Kumaran  · 技术社区  · 6 年前

    这个陈述和例子来自 Essential C by Nick Parlante.

    C类型语法的一个优点是 避免了循环定义问题 当指针结构需要引用自身时出现。以下定义定义了链接列表中的节点。注意,不需要节点指针类型的预备声明。

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

    C编译器如何知道 struct node* 当它仍然在struct节点中时。

    还有一个循环定义的例子,其中 struct treenode* 在进一步定义之前使用。

    typedef struct treenode* Tree;
    struct treenode {
        int data;
        Tree smaller, larger;   // equivalently, this line could say
                                // "struct treenode *smaller, *larger"
    };
    

    C编译器如何知道 树状结构* 当它还没有被定义的时候。

    相关SO问题: How does C resolve circular definition when a pointer in struct points to the struct itself? (这是相关的,它没有回答“如何”的问题)。

    编辑:我假设C编译器能够在一次传递中完成这项工作。

    3 回复  |  直到 6 年前
        1
  •  6
  •   Jonathan Leffler vy32    6 年前

    C标准规定 §6.2.5 Types ¶28 (重点补充):

    指向void的指针应具有与 指向字符类型的指针。 48页) 类似地,指向 兼容类型应具有相同的表示和对齐要求。 全部 指向结构类型的指针应具有相同的表示和对齐要求 就像彼此一样。 所有指向联合类型的指针都应具有相同的表示形式和 相互对准要求。指向其他类型的指针不必具有相同的 表示或对齐要求。

    因此,C编译器知道如何处理任何结构指针类型,因为所有结构指针必须具有相同的表示和对齐要求。这适用于是否嵌入 struct node * 或者 struct value * –无论编译器以前是否知道 struct value . 这也有助于处理“不透明类型”,您可以将指针指向编译器不知道结构内容的结构类型。

    你不能做的是嵌入 struct node (而不是 结构节点* )在定义范围内 结构节点 . 可以将以前已知的结构类型作为值嵌入到结构中。也可以在另一个结构类型中定义结构类型:

    struct node
    {
        int data;
        struct node *next;
        struct key_value
        {
            int key;
            char *value;
        } kv;
    };
    

    与C++不同, struct key_value 类型是可用的,但没有范围问题它不限制在类型中使用 结构节点 是的。这不是良好的编码实践,但这是允许的。

        2
  •  4
  •   John Bode    6 年前

    可以声明指向不完整类型的指针-指针的大小和表示形式不取决于指向类型的大小或表示形式。

    它也有助于按照语言标准指出 struct 类型具有相同的大小和表示形式

        3
  •  0
  •   fnisi Sumit Naik    6 年前

    您可以定义指向结构本身实例的指针(其大小由编译器知道),但在类型声明中在同一类型的结构内定义结构是非法的。

    如果您试图声明 struct 而不是 struct* ,将出现编译器错误。