[英]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. 因为在定义结构之前,
Treeptr
是struct 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.