给定以下代码:
typedef struct elementT { int data; struct elementT *next; } element;
为什么必须做struct elementT *next,而不能在struct声明中做element *next?是因为它还没有声明吗?
struct elementT *next
element *next
nzrxty8p1#
typedef只在定义了struct之后发生。语法是无效的,但它希望它能显示事物的顺序/优先级:
typedef
struct
typedef (struct { int field1, field2; }) item;
也就是说,struct{...}是一个表示类型的"表达式",typedef通过给它一个名称来操作该类型。与此相反,
struct{...}
struct foo { struct foo *next; };
之所以有效,是因为C语言的两个特殊规则:struct <name>不仅定义了一个类型,而且还为它提供了一个struct标记,该标记在struct声明的其余部分中立即可见(原因显而易见:链表、树等在没有这些规则的情况下实现将非常痛苦)。
struct <name>
wmomyfyw2#
因为C是这么说的:(C99,6.2.1p7)“[...]任何其他标识符的作用域都是在其声明符完成后立即开始的。”
xmakbtuz3#
名称elementT(类型名称struct elementT的一部分)在编译器看到两个标记struct elementT时就变得可见(作为不完整类型),因此您可以将其用作struct定义中的类型名称。名称element是一个typedef名称,直到标识符element出现后才变得可见,该标识符位于结构体定义的末尾(结束的})之后;因此你不能在结构定义中使用它,因为它还不存在。我个人的偏好(在这一点上,许多非常聪明的人和我意见不一)是根本不使用typedef,因为该类型已经有了一个非常好的名称struct ElementT;为什么还要加第二个呢?我只会写:
elementT
struct elementT
element
}
struct ElementT
struct element { int data; struct element *next; };
并且将该类型称为struct element。当然,如果你觉得用一个单词来命名类型就足够了,你仍然可以使用typedef,只要记住typedef的名字在声明结束之前是不可见的,而且没有必要使用两个不同的标识符:
struct element
typedef struct element { int data; struct element *next; } element;
现在,您可以将该类型称为struct element或element。(Note C有不同的规则它有效地为struct(或union、class或enum)类型创建了一个隐式typedef(在C中,typedef是不必要的,但无害)。
union
class
enum
rbpvctlc4#
如果将结构声明与其定义分开,则可以实现此行为:
struct ElementT; // not strictly needed typedef struct ElementT element; // this declares "struct ElementT" as well struct ElementT { element * next; };
4条答案
按热度按时间nzrxty8p1#
typedef
只在定义了struct
之后发生。语法是无效的,但它希望它能显示事物的顺序/优先级:也就是说,
struct{...}
是一个表示类型的"表达式",typedef
通过给它一个名称来操作该类型。与此相反,
之所以有效,是因为C语言的两个特殊规则:
struct <name>
不仅定义了一个类型,而且还为它提供了一个struct
标记,该标记在struct
声明的其余部分中立即可见(原因显而易见:链表、树等在没有这些规则的情况下实现将非常痛苦)。wmomyfyw2#
因为C是这么说的:
(C99,6.2.1p7)“[...]任何其他标识符的作用域都是在其声明符完成后立即开始的。”
xmakbtuz3#
名称
elementT
(类型名称struct elementT
的一部分)在编译器看到两个标记struct elementT
时就变得可见(作为不完整类型),因此您可以将其用作struct定义中的类型名称。名称
element
是一个typedef名称,直到标识符element
出现后才变得可见,该标识符位于结构体定义的末尾(结束的}
)之后;因此你不能在结构定义中使用它,因为它还不存在。我个人的偏好(在这一点上,许多非常聪明的人和我意见不一)是根本不使用
typedef
,因为该类型已经有了一个非常好的名称struct ElementT
;为什么还要加第二个呢?我只会写:并且将该类型称为
struct element
。当然,如果你觉得用一个单词来命名类型就足够了,你仍然可以使用typedef,只要记住typedef的名字在声明结束之前是不可见的,而且没有必要使用两个不同的标识符:
现在,您可以将该类型称为
struct element
或element
。(Note C有不同的规则它有效地为
struct
(或union
、class
或enum
)类型创建了一个隐式typedef(在C中,typedef
是不必要的,但无害)。rbpvctlc4#
如果将结构声明与其定义分开,则可以实现此行为: