指向C中的自构造

给出以下代码:

typedef struct elementT { int data; struct elementT *next; } element; 

为什么有必要做struct elementT *next而且我不能在struct声明本身里面做element *next ? 是因为它还没有申报吗?

typedef仅在定义struct后发生。 考虑以下代码; 语法无效,但它希望它显示事物的顺序/优先级:

 typedef (struct { int field1, field2; }) item; 

即, struct{...}是表示类型的“表达式”。 typedef通过给它命名来操作该类型。

相比之下,

 struct foo { foo *next; }; 

因为C的两个特殊规则而起作用: struct 不仅定义了一个类型,而且还给它一个struct标签,并且该标签在struct声明的其余部分内立即可见(原因很明显:链表,没有这些规则,实施树木等将非常痛苦。

因为C这样说:

(C99,6.2.1p7)“[……]任何其他标识符的范围都在其声明者完成之后开始。”

一旦编译器看到两个标记struct elementT ,名称elementT (类型名称struct elementT )就变为可见(作为不完整类型),因此您可以将其用作结构定义中的类型名称。

name element是一个typedef名称,在标识符element出现之前不会变为可见,这是结构定义的结束(结束} ); 因此你不能在结构定义中使用它,因为它还不存在。

我个人的偏好(以及很多非常聪明的人在这一点上与我不同)并不是使用typedef 。 该类型已经有一个非常好的名称, struct ElementT ; 为什么要添加第二个? 我只想写:

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

并将类型称为struct element

如果您认为该类型的单字名称足够有用,当然,您仍然可以使用typedef。 请记住,在声明结束之后才能看到typedef名称。 并且不需要使用两个不同的标识符:

 typedef struct element { int data; struct element *next; } element; 

现在,您可以将类型引用为struct elementelement

(注意,C ++有不同的规则;它有效地为struct (或unionclassenum )类型创建一个隐式typedef。在C ++中, typedef是不必要的但是无害的。)

如果将struct声明与其定义分开,则可以实现此行为:

 struct ElementT; // not strictly needed typedef struct ElementT element; // this declares "struct ElementT" as well struct ElementT { element * next; };