指向C中self结构的指针

mrwjdhj3  于 2023-01-29  发布在  其他
关注(0)|答案(4)|浏览(191)

给定以下代码:

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

为什么必须做struct elementT *next,而不能在struct声明中做element *next?是因为它还没有声明吗?

nzrxty8p

nzrxty8p1#

typedef只在定义了struct之后发生。语法是无效的,但它希望它能显示事物的顺序/优先级:

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

也就是说,struct{...}是一个表示类型的"表达式",typedef通过给它一个名称来操作该类型。
与此相反,

struct foo {
    struct foo *next;
};

之所以有效,是因为C语言的两个特殊规则:struct <name>不仅定义了一个类型,而且还为它提供了一个struct标记,该标记在struct声明的其余部分中立即可见(原因显而易见:链表、树等在没有这些规则的情况下实现将非常痛苦)。

wmomyfyw

wmomyfyw2#

因为C是这么说的:
(C99,6.2.1p7)“[...]任何其他标识符的作用域都是在其声明符完成后立即开始的。”

xmakbtuz

xmakbtuz3#

名称elementT(类型名称struct elementT的一部分)在编译器看到两个标记struct elementT时就变得可见(作为不完整类型),因此您可以将其用作struct定义中的类型名称。
名称element是一个typedef名称,直到标识符element出现后才变得可见,该标识符位于结构体定义的末尾(结束的})之后;因此你不能在结构定义中使用它,因为它还不存在。
我个人的偏好(在这一点上,许多非常聪明的人和我意见不一)是根本不使用typedef,因为该类型已经有了一个非常好的名称struct ElementT;为什么还要加第二个呢?我只会写:

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

并且将该类型称为struct element
当然,如果你觉得用一个单词来命名类型就足够了,你仍然可以使用typedef,只要记住typedef的名字在声明结束之前是不可见的,而且没有必要使用两个不同的标识符:

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

现在,您可以将该类型称为struct elementelement
(Note C有不同的规则它有效地为struct(或unionclassenum)类型创建了一个隐式typedef(在C中,typedef是不必要的,但无害)。

rbpvctlc

rbpvctlc4#

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

struct ElementT;                   // not strictly needed

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

struct ElementT
{
    element * next;
};

相关问题