![](/img/trans.png)
[英]What is the meaning of `struct X typedef` vs. `typedef struct X`?
[英]What is the identifier of typedef struct
我来学习链表。 但是,我对使用struct声明链表的几种方法感到困惑。
这是一种方式
typedef struct Nodetag {
int dataNum;
struct Nodetag* nextNode;
} NODE;
这是不使用typedef的另一种方式
struct NODE {
int dataNum;
struct NODE* nextNode;
};
我很好奇,当我们使用typedef
进行声明时,我知道Nodetag
用于让编译器知道struct Nodetag* nextNode;
是。 但是,该struct
的实际标识符是什么? Nodetag
还是NODE
? 如果是Nodetag
,则何时使用NODE
?
您可以选择给结构添加标签,如struct Nodetag
或struct NODE
。 这些标签(以及并集标签和枚举标签)与普通标识符位于单独的命名空间中。
typedef
版本为struct Nodetag
创建别名:
typedef struct Nodetag { ... } NODE;
现在, NODE
是普通标识符名称空间中的类型名称,它是struct Nodetag
的同义词或别名。
请注意,您还可以编写:
typedef struct Nodetag NODE;
struct Nodetag
{
int dataNum;
NODE *nextNode;
};
第一行说“存在带有标签Nodetag
的结构类型,而NODE
是此类型的别名”。 第二个块表示“ struct Nodetag
包含这些项”,并列出了NODE *
作为成员之一。
请注意,这个问题被标记为C,您将获得直接的C答案(这很好)。 但是,如果您遇到过C ++,则会发现:
struct Nodetag
{
int dataNum;
Nodetag *nextNode;
};
是有效的C ++,并在普通标识符名称空间(以及(结构)标签名称空间中的标签Nodetag
中生成类型名称Nodetag
。这在C中无效。如果最终使用C ++编译器执行以下操作,可能会感到困惑但是,编译C代码。
这个:
struct Nodetag {
/* ... */
};
创建一个名为struct Nodetag
的类型。 同样,这:
struct NODE {
/* ... */
};
创建一个名为struct NODE
的类型。
无论哪种情况,都可以用typedef
声明包装该声明,为同一类型创建另一个名称:
typedef struct S {
/* ... */
} T;
这使您可以将类型引用为struct S
或T
(您不能仅用S
来称呼它,尽管如果使用C ++而不是C进行编程,则可以。)
编写以上内容的等效方法是:
struct S {
/* ... */
};
typedef struct S T;
请注意,结构标记和typedef名称位于不同的命名空间(在C ++中不是“名称空间”一词),因为结构标记只能跟随关键字struct
。 因此,无需将它们区分开。
typedef struct Node {
/* ... */
} Node;
现在,您可以将类型称为struct Node
也可以称为Node
。
添加这样的typedef没有太大的优势; 如果愿意,可以忽略它,而仅将其称为struct Node
。 (但是许多C程序员喜欢能够为类型使用一个单词的名称,而typedef是实现此目的的唯一好方法( #define
是实现它的另一种方法,但不是一种好方法。)
也可以省略标签名称,而只需使用typedef即可:
typedef struct {
/* ... */
} Node;
这为您提供了一个匿名结构类型,然后立即创建引用它的名称Node
。 但是使用这种方法,结构不能包含指向其自身的指针,因为名称Node
直到结构定义结束后才可见。
第一个结构称为struct Nodetag
,第二个结构称为struct NODE
。
在第一个实例中,已经定义了一个typedef,它为struct Nodetag
别名化了NODE
,但是它并没有改变结构的名称。 它的作用是让您键入例如NODE*
而不是struct Nodetag*
。 这是简写,仅此而已。
结构标记和类型位于不同的命名空间中。 您可以有一个struct node
,也可以有一个type node
。 结构标记必须与struct
specifier / prefix一起使用以区分它们。 当您这样做时:
typedef struct Nodetag {
int dataNum;
struct Nodetag* nextNode;
} NODE;
您正在定义一个新类型,还定义了一个结构标签,但是您实际上并不需要定义它只是为了方便起见。 在结构定义内,因为编译器直到读取} NODE;
才知道类型} NODE;
部分,您必须使用结构标签来引用您要定义的结构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.