简体   繁体   English

typedef struct的标识符是什么

[英]What is the identifier of typedef struct

I came up to learn linked list. 我来学习链表。 But, I'm quite confused with several ways of declaring linked lists with struct. 但是,我对使用struct声明链表的几种方法感到困惑。

this is one way, 这是一种方式

typedef struct Nodetag {
int dataNum;
struct Nodetag* nextNode;
} NODE;

and this is another way not using typedef 这是不使用typedef的另一种方式

struct NODE {
int dataNum;
struct NODE* nextNode;
};

I'm curious, when we are declaring with typedef , I know the Nodetag is used to let the compiler know what struct Nodetag* nextNode; 我很好奇,当我们使用typedef进行声明时,我知道Nodetag用于让编译器知道struct Nodetag* nextNode; is. 是。 But then, what is the actual identifier of the struct ? 但是,该struct的实际标识符是什么? Nodetag or NODE ? Nodetag还是NODE if it is Nodetag , when is NODE used? 如果是Nodetag ,则何时使用NODE

You can optionally give a structure a tag, as in struct Nodetag or struct NODE . 您可以选择给结构添加标签,如struct Nodetagstruct NODE These tags (and union tags, and enum tags) are in a separate namespace from ordinary identifiers. 这些标签(以及并集标签和枚举标签)与普通标识符位于单独的命名空间中。

The typedef version creates an alias for struct Nodetag : typedef版本为struct Nodetag创建别名:

typedef struct Nodetag { ... } NODE;

Now NODE is a type name in the ordinary identifiers name space that is a synonym or alias for struct Nodetag . 现在, NODE是普通标识符名称空间中的类型名称,它是struct Nodetag的同义词或别名。

Note that you can also write: 请注意,您还可以编写:

typedef struct Nodetag NODE;

struct Nodetag
{
    int   dataNum;
    NODE *nextNode;
};

The first line says 'there exists a structure type with the tag Nodetag and NODE is an alias for this type'. 第一行说“存在带有标签Nodetag的结构类型,而NODE是此类型的别名”。 The second block says ' struct Nodetag consists of these items', listing a NODE * as one of the members. 第二个块表示“ struct Nodetag包含这些项”,并列出了NODE *作为成员之一。


C and C++ are two different languages C和C ++是两种不同的语言

Note that this question is tagged C, and you are getting straight C answers (which is good). 请注意,这个问题被标记为C,您将获得直接的C答案(这很好)。 However, if you have encountered C++, you'd find that: 但是,如果您遇到过C ++,则会发现:

struct Nodetag
{
    int      dataNum;
    Nodetag *nextNode;
};

is valid C++ and generates a type name Nodetag in the ordinary identifiers name space (as well as the tag Nodetag in the (structure) tags namespace. This is not valid in C. You may get confused if you end up using a C++ compiler to compile C code, though. 是有效的C ++,并在普通标识符名称空间(以及(结构)标签名称空间中的标签Nodetag中生成类型名称Nodetag 。这在C中无效。如果最终使用C ++编译器执行以下操作,可能会感到困惑但是,编译C代码。

This: 这个:

struct Nodetag {
    /* ... */
};

creates a type named struct Nodetag . 创建一个名为struct Nodetag的类型。 Similarly, this: 同样,这:

struct NODE {
    /* ... */
};

creates a type named struct NODE . 创建一个名为struct NODE的类型。

In either case, you can wrap that declaration with a typedef declaration, creating a second name for the same type: 无论哪种情况,都可以用typedef声明包装该声明,为同一类型创建另一个名称:

typedef struct S {
    /* ... */
} T;

This lets you refer to the type either as struct S or as T . 这使您可以将类型引用为struct ST (You can't call it just S -- though you could if you were programming in C++ rather than C.) (您不能仅用S来称呼它,尽管如果使用C ++而不是C进行编程,则可以。)

An equivalent way to write the above is: 编写以上内容的等效方法是:

struct S {
    /* ... */
};
typedef struct S T;

Note that struct tags and typedef names are in different namespaces (not in the C++ sense of the word "namespaces"), since a struct tag can only follow the keyword struct . 请注意,结构标记和typedef名称位于不同的命名空间(在C ++中不是“名称空间”一词),因为结构标记只能跟随关键字struct So there's no need for them to be distinct. 因此,无需将它们区分开。

typedef struct Node {
    /* ... */
} Node;

Now you can refer to the type either as struct Node or just as Node . 现在,您可以将类型称为struct Node也可以称为Node

There's no great advantage in adding a typedef like this; 添加这样的typedef没有太大的优势; if you like, you can omit it and just refer to the type as struct Node . 如果愿意,可以忽略它,而仅将其称为struct Node (But a lot of C programmers like being able to use a one-word name for a type, and a typedef is the only good way to do that (a #define is another way to do it, but not a good way.) (但是许多C程序员喜欢能够为类型使用一个单词的名称,而typedef是实现此目的的唯一好方法( #define是实现它的另一种方法,但不是一种好方法。)

It's also possible to omit the tag name, and just use the typedef: 也可以省略标签名称,而只需使用typedef即可:

typedef struct {
    /* ... */
} Node;

This gives you an anonymous struct type, and then immediately creates the name Node that refers to it. 这为您提供了一个匿名结构类型,然后立即创建引用它的名称Node But with this approach, the struct can't contain a pointer to itself, since the name Node doesn't become visible until after the end of the struct definition. 但是使用这种方法,结构不能包含指向其自身的指针,因为名称Node直到结构定义结束后才可见。

The first struct is called struct Nodetag , the second struct is called struct NODE . 第一个结构称为struct Nodetag ,第二个结构称为struct NODE

In the first instance, a typedef has been defined that "aliases" NODE for struct Nodetag , but it doesn't change the name of the structure. 在第一个实例中,已经定义了一个typedef,它为struct Nodetag别名化了NODE ,但是它并没有改变结构的名称。 What it does do is let you type, for example, NODE* rather than struct Nodetag* . 它的作用是让您键入例如NODE*而不是struct Nodetag* It's shorthand, nothing more. 这是简写​​,仅此而已。

Structure tags and types live in different namespaces. 结构标记和类型位于不同的命名空间中。 You can have a struct node and also a type node . 您可以有一个struct node ,也可以有一个type node Structure tags must be used with the struct specifier/prefix to distinguish them. 结构标记必须与struct specifier / prefix一起使用以区分它们。 When you do: 当您这样做时:

typedef struct Nodetag {
int dataNum;
struct Nodetag* nextNode;
} NODE;

You are defining a new type and also defining a structure tag but you don't really need to define a type it is just for convenience. 您正在定义一个新类型,还定义了一个结构标签,但是您实际上并不需要定义它只是为了方便起见。 Within the structure definition, since the compiler does not know about the type until it reads the } NODE; 在结构定义内,因为编译器直到读取} NODE;才知道类型} NODE; part, you have to use the structure tags to refer to the structure you are defining. 部分,您必须使用结构标签来引用您要定义的结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM