typedef结构的标识符是什么

时间:2013-03-21 00:06:22

标签: c

我上来学习链表。但是,我对使用struct声明链表的几种方法感到困惑。

这是一种方式,

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

这是另一种不使用typedef的方法

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

我很好奇,当我们用typedef声明时,我知道Nodetag用于让编译器知道struct Nodetag* nextNode;是什么。但是,struct的实际标识符是什么? NodetagNODE?如果是Nodetag,何时使用NODE

4 个答案:

答案 0 :(得分:5)

您可以选择为结构提供标记,如struct Nodetagstruct 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,您将获得直接的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 ST。 (你不能只称它为S - 尽管你可以使用C ++而不是C编程。)

写上述内容的等效方法是:

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

请注意,struct标签和typedef名称位于不同的名称空间中(不是C ++意义上的“名称空间”一词),因为struct标签只能跟随关键字struct。所以没有必要让它们与众不同。

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

现在,您可以将该类型称为struct NodeNode

添加像这样的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 nodenode类型。结构标记必须与struct说明符/前缀一起使用才能区分它们。当你这样做时:

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

您正在定义一个新类型并定义一个结构标记,但您不需要为了方便而定义一个类型。在结构定义中,由于编译器在读取} NODE;部分之前不知道类型,因此必须使用结构标记来引用您定义的结构。