给定以下代码:
typedef struct elementT {
int data;
struct elementT *next;
} element;
为什么有必要做struct elementT *next
而我不能element *next
在结构声明本身内部做?是因为还没有申报吗?
typedef
唯一发生在定义之后struct
。考虑以下代码;语法无效,但它希望它显示事物的顺序/优先级:
typedef (struct {
int field1, field2;
}) item;
即,struct{...}
是表示类型的“表达式”。通过typedef
给它一个名字来操作那个类型。
相比之下,
struct foo {
foo *next;
};
之所以起作用,是因为 C 的两个特殊规则:struct <name>
不仅定义了一个类型,而且还给它一个struct
标签,并且该标签在struct
声明的其余部分中立即可见(出于显而易见的原因:链表、树等将是如果没有这些规则,实施起来非常痛苦)。
因为C是这么说的:
(C99,6.2.1p7)“[...] 任何其他标识符的范围都在其声明符完成后开始。”
nameelementT
是类型 name 的一部分,struct elementT
一旦编译器看到这两个标记,就会变得可见(作为不完整的类型)struct elementT
,因此您可以将其用作结构定义中的类型名称。
name是一个 typedef 名称,在标识符出现element
之前不可见,标识符出现在结构定义的结尾(结束)之后;因此你不能在结构定义中使用它,只是因为它还不存在。element
}
我个人的偏好(很多非常聪明的人在这一点上与我不同)根本不使用typedef
。该类型已经有一个很好的名字,struct ElementT
; 为什么要添加第二个?我只想写:
struct element {
int data;
struct element *next;
};
并将类型称为struct element
。
如果您觉得为类型使用一个单词名称就足够有用了,当然,您仍然可以使用 typedef。请记住,typedef 名称直到声明结束后才可见。并且不需要使用两个不同的标识符:
typedef struct element {
int data;
struct element *next;
} element;
现在您可以将类型称为 asstruct element
或 as element
。
(请注意,C++ 有不同的规则;它有效地为struct
(or union
, class
, or enum
) 类型创建了一个隐式 typedef。在 C++ 中,这typedef
是不必要的但无害的。)
如果将结构声明与其定义分开,则可以实现此行为:
struct ElementT; // not strictly needed
typedef struct ElementT element; // this declares "struct ElementT" as well
struct ElementT
{
element * next;
};