考虑下面的代码:
typedef struct elementT {
int data;
struct elementT *next;
} element;
为什么有必要做struct elementT *next
,我不能做的element *next
结构声明本身里面? 是不是因为它是尚未宣布?
考虑下面的代码:
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)“[...]的任何其它标识符具有范围,只是其声明符完成后开始。”
该名elementT
,类型名称的一部分struct elementT
,变得可见(作为一个不完整的类型),只要编译器看到两个标记struct elementT
,所以你可以使用它作为结构定义范围内的类型名称。
名称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 ++有不同的规则,它有效地用于创建一个隐含的typedef struct
(或union
, class
,或enum
)型在C ++中,。 typedef
是不必要的,但无害的。)
如果你分开的定义结构声明就可以实现此行为:
struct ElementT; // not strictly needed
typedef struct ElementT element; // this declares "struct ElementT" as well
struct ElementT
{
element * next;
};