我上来学习链表。但是,我对使用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
?
答案 0 :(得分:5)
您可以选择为结构提供标记,如struct Nodetag
或struct NODE
。这些标记(以及union标记和枚举标记)与普通标识符位于不同的名称空间中。
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代码,那就会感到困惑。
答案 1 :(得分:3)
此:
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;
请注意,struct标签和typedef名称位于不同的名称空间中(不是C ++意义上的“名称空间”一词),因为struct标签只能跟随关键字struct
。所以没有必要让它们与众不同。
typedef struct Node {
/* ... */
} Node;
现在,您可以将该类型称为struct Node
或Node
。
添加像这样的typedef没有什么大的优势;如果您愿意,可以省略它,只需将类型称为struct Node
即可。 (但是很多C程序员喜欢能够为一个类型使用单字名称,而typedef是唯一可以做到这一点的好方法(#define
是另一种方法,但不是很好方式。)
也可以省略标签名称,只需使用typedef:
typedef struct {
/* ... */
} Node;
这为您提供了匿名结构类型,然后立即创建引用它的名称Node
。但是使用这种方法,struct不能包含指向自身的指针,因为名称Node
在结构定义结束之后才会变得可见。
答案 2 :(得分:0)
第一个结构称为struct Nodetag
,第二个结构称为struct NODE
。
在第一个实例中,已经为NODE
定义了一个“别名”struct Nodetag
的typedef,但它不会更改结构的名称。它的作用是让您输入NODE*
而不是struct Nodetag*
。这是速记,仅此而已。
答案 3 :(得分:0)
结构标记和类型存在于不同的命名空间中。您可以拥有struct node
和node
类型。结构标记必须与struct
说明符/前缀一起使用才能区分它们。当你这样做时:
typedef struct Nodetag {
int dataNum;
struct Nodetag* nextNode;
} NODE;
您正在定义一个新类型并定义一个结构标记,但您不需要为了方便而定义一个类型。在结构定义中,由于编译器在读取} NODE;
部分之前不知道类型,因此必须使用结构标记来引用您定义的结构。