指向C中的自结构的指针

时间:2013-01-14 21:25:20

标签: c struct typedef

给出以下代码:

typedef struct elementT {
  int data;
  struct elementT *next;
} element;

为什么有必要做struct elementT *next而我不能在结构声明本身内做element *next?是因为它尚未宣布吗?

4 个答案:

答案 0 :(得分:3)

typedef仅在struct定义后发生。考虑以下代码;语法无效,但它希望它显示事物的顺序/优先级:

typedef (struct {
  int field1, field2;
}) item;

即,struct{...}是表示类型的“表达式”。 typedef通过为其命名来对该类型进行操作。

相比之下,

struct foo {
    foo *next;
};

因为C的两个特殊规则而起作用:struct <name>不仅定义了一个类型,而且还给它一个struct标记,并且该标记在{{1}的其余部分内立即可见声明(原因很明显:如果没有这些规则,链接列表,树等等将会非常痛苦。)

答案 1 :(得分:2)

因为C这么说:

  

(C99,6.2.1p7)“[...]任何其他标识符的范围都在其声明者完成之后开始。”

答案 2 :(得分:2)

一旦编译器看到两个令牌elementT,名称struct elementT(类型名称struct elementT的一部分)就会变为可见(作为不完整类型),因此您可以使用它作为结构定义中的类型名称。

名称element是一个typedef名称,在标识符element出现之前不会显示,在结束后结束{{1} }})结构定义;因此你不能在结构定义中使用它,因为它还不存在。

我个人的偏好(以及很多非常聪明的人在这一点上与我不同)不是完全使用}。该类型已经有一个非常好的名字,typedef;为什么要添加第二个?我只想写:

struct ElementT

并将类型称为struct element { int data; struct element *next; };

如果您认为该类型的单字名称足够有用,当然,您仍然可以使用typedef。请记住,在声明结束之后才能看到typedef名称。并且不需要使用两个不同的标识符:

struct element

现在,您可以将该类型称为typedef struct element { int data; struct element *next; } element; struct element

(请注意,C ++有不同的规则;它有效地为element(或structunionclass)类型创建了一个隐式typedef。在C ++中, enum是不必要的,但无害。)

答案 3 :(得分:1)

如果将struct声明与其定义分开,则可以实现此行为:

struct ElementT;                   // not strictly needed

typedef struct ElementT element;   // this declares "struct ElementT" as well

struct ElementT
{
    element * next;
};