指向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 element
或element
。
(注意,C ++有不同的规则;它有效地为struct
(或union
, class
或enum
)类型创建一个隐式typedef。在C ++中, typedef
是不必要的但是无害的。)
如果将struct声明与其定义分开,则可以实现此行为:
struct ElementT; // not strictly needed typedef struct ElementT element; // this declares "struct ElementT" as well struct ElementT { element * next; };