在研究C中的队列时,我遇到了类似于下面的示例。为什么结构在大括号的开头和之后都命名?为什么在添加相同类型的项时,结构类型在结构内部再次使用?这些事情是多余的还是有意义的?
typedef void* vpoint_t;
typedef struct queue_item_t{
vpoint_t void_item;
struct queue_item_t* next;
} queue_item_t;
答案 0 :(得分:16)
typedef struct queue_item_t { // 1
vpoint_t void_item;
struct queue_item_t* next; // 2
} queue_item_t; // 3
首先,请注意,整个语句定义了typedef
。
3)说我们正在定义的新类型(通过typedef
)是转到被命名为queue_item_t
1)结构的名称(正如我们所说的那样被赋予一个新名称)被命名为struct queue_item_t
。这是它的全名,包括前面的struct
。
2)因为新类型还没有存在(请记住,我们仍然在定义它的过程中),我们必须使用它所拥有的唯一名称远,struct queue_item_t
,来自 1)。
请注意,您可以使用匿名struct
定义,这样您就可以省略 1)中的名称。一个简单的例子:
typedef struct {
int x, y, z;
} vector3;
但是,在您的示例中,由于我们需要结构能够引用自身,因此next
指针必须具有已定义的类型。我们可以通过转发声明结构,键入它,然后使用typedef
的{{1}} d类型定义结构来实现:
next
4)声明struct _queue_item; // 4
typedef struct _queue_item queue_item_t; // 5
struct _queue_item { // 6
vpoint_t void_item;
queue_item_t* next; // 7
}
存在,但尚未提供定义。
5) Typedef struct _queue_item
与queue_item_t
相同。
6)现在给出结构的定义......
7) ...使用我们的struct _queue_item
' d typedef
。
所有这一切......在我看来,please don't use typedefs for structs。
queue_item_t
简单而完整。您可以设法输入这六个额外字符。
第5章:Typedef
请不要使用像" vps_t"这样的内容。 错误使用typedef作为结构和指针。当你看到
struct queue_item { void *data; struct queue_item *next; }
在源头,这是什么意思? 相反,如果它说
vps_t a;
你实际上可以告诉他们" a"是
有一些例外,你可以阅读。
最近的一些相关问题:
答案 1 :(得分:4)
让我们稍微改变声明,使讨论更容易理解:
typedef struct queue_item {
vpoint_t void_item;
struct queue_item* next;
} QueueItemType;
C支持几个不同的名称空间;在联合,结构和枚举类型上为标记名称保留一个名称空间。在这种情况下,标记名称为queue_item
。另一个名称空间保留给常规标识符,包括 typedef names ,如QueueItemType
。
next
成员用于指向另一个类型struct queue_item
的实例(即队列中的下一个项目)。它被声明为指向struct queue_item
的指针有两个原因:
结构类型不能包含自身的实例;一方面,类型必须无限大(struct queue_item
包含一个成员next
,这是一个struct queue_item
,其中包含一个成员next
,它是一个struct queue_item
1}}包含成员next
, ad infinitum );
结构类型定义不是完成直到结束}
,并且您无法声明实例不完整的类型。但是,您可以将指针声明为不完整的类型,我们将在下面执行此操作:
struct queue_item * next;
为什么不使用QueueItemType *next;
代替struct queue_item *next
?同样,结构类型定义在声明点next
时不是完成; typedef名称QueueItemType
尚不存在。但是,标记名queue_item
已经对编译器可见,因此我们可以使用类型struct queue_item
声明指针。
由于标记名称和typedef名称占用不同的名称空间,因此可以在不发生冲突的情况下对标记名称和typedef名称使用相同的名称。编译器通过struct
关键字的存在消除了两者之间的歧义。
答案 2 :(得分:0)
首先,我建议不要使用结构名称和相同的类型名称。使用typedef struct QUEUE_ITEM {...} queue_item_t;
关于问题:如果你想创建一个"递归数据结构",即一个指向自身实例的数据结构,那么你必须能够告诉编译器&# 34;这个字段是指向我们自己的一个指针。你还不完全知道我们的样子,因为我还在定义它,所以只需为指针保留空间"。要做到这一点,你宣布
struct T {
...
struct T *ptr;
....
};
使用最终} queue_item_t;
,您可以为结构创建新名称。
答案 3 :(得分:0)
" struct foo {...}"是一回事。它定义了一个结构,你需要键入" struct foo"在你使用它的每个地方。
" typedef ... foo"定义一个新类型,所以你只需键入" foo"在哪里使用它。
" typedef struct foo {...} foo"是一个成语,所以你可以使用两者,很可能只是" foo"以节省击键和视觉污染。