简体   繁体   English

struct typedef中的声明规则

[英]Declaration rule in struct typedef

I'm reading 'The C Programming Language' and encountered a problem about typedef of struct . 我正在阅读'C编程语言',并遇到了关于struct的 typedef的问题。 The code is like this: 代码是这样的:

typedef struct tnode *Treeptr;
typedef struct tnode { /* the tree node: */
    char *word; /* points to the text */
    int count; /* number of occurrences */
    struct tnode *left; /* left child */
    struct tnode *right; /* right child */
} Treenode;

By the time we write 到我们写的时候

typedef struct tnode *Treeptr;

tnode is still not declared yet, but we don't get any compilation error, but when we change the statement above into: tnode仍未声明,但我们没有得到任何编译错误,但是当我们将上面的语句更改为:

typedef Treenode *Treeptr;

We get compilation error: 我们得到编译错误:

error: parse error before '*' token
warning: data definition has no type or storage class

What causes the difference? 是什么导致了差异? Isn't "struct tnode" the same as "Treenode"? “struct tnode”与“Treenode”不一样吗?

You can't use a type before it is defined. 在定义之前不能使用类型。

With the typedef struct tnode { ... } Treenode; 使用typedef struct tnode { ... } Treenode; declaration, the type Treenode is not defined until the semi-colon is reached. 声明, Treenode类型直到达到分号才定义。

The situation with typedef struct tnode *Treeptr; typedef struct tnode *Treeptr; is different. 是不同的。 This tells the compiler 'there is a structure type called struct tnode , and the type Treeptr is an alias for a pointer to a struct tnode '. 这告诉编译器“有称为结构类型struct tnode ,类型Treeptr为指针的别名struct tnode ”。 At the end of that declaration, struct tnode is an incomplete type. 在该声明的最后, struct tnode是一个不完整的类型。 You can create pointers to incomplete types but you cannot create variables of the incomplete type (so you could define Treeptr ptr1; or struct tnode *ptr2; and they are the same type, but you could not define struct tnode node; ). 您可以创建指向不完整类型的指针,但不能创建不完整类型的变量(因此您可以定义Treeptr ptr1;或者struct tnode *ptr2;它们是相同的类型,但您无法定义struct tnode node; )。

The body of the struct tnode could be written as: struct tnode的主体可以写成:

typedef struct tnode
{
    char    *word;
    int      count;
    Treeptr  left;
    Treeptr  right;
} Treenode;

because Treeptr is a known alias for the type struct tnode * before the structure is defined. 因为在定义结构之前, Treeptrstruct tnode *类型的已知别名。 You can't use Treenode *left; 你不能使用Treenode *left; because Treenode is not a known alias until the final semi-colon is reached (roughly speaking). 因为Treenode不是已知的别名,直到达到最终的分号(粗略地说)。

When you declare TreePtr , you are not implementing the struct. 声明TreePtr ,您没有实现该结构。 That is known as a " forward declaration ". 这被称为“ 前沿宣言 ”。 Something like: "here we use this, but later I will explain it better". 类似的事情:“我们在这里使用它,但后来我会更好地解释它”。 The implementation must appear later, only once, and that is what you find in the second typedef . 实现必须稍后出现,只能出现一次,这就是您在第二个typedef找到的内容。

And TreePtr is not the same as the struct, because TreePtr will be in fact a new type that includes the fact of beeing a pointer. TreePtr与struct不同,因为TreePtr实际上是一个包含指针的新类型。

A line typedef struct tnode *Treeptr; 一行line typedef struct tnode *Treeptr; has implicit forward declaration of "tnode" struct. 具有“tnode”结构的隐式前向声明。 It's similar to: 它类似于:

typedef struct tnode Treenode;
typedef Treenode *Treeptr;

struct tnode { /* the tree node: */
    char *word; /* points to the text */
    int count; /* number of occurrences */
    struct tnode *left; /* left child */
    struct tnode *right; /* right child */
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM