在研究C中的队列时,我遇到了类似于下面的示例.为什么结构在大括号的开头和之后都命名?为什么在添加相同类型的项时,结构类型在结构内部再次使用?这些事情是多余的还是有意义的?
typedef void* vpoint_t;
typedef struct queue_item_t{
vpoint_t void_item;
struct queue_item_t* next;
} queue_item_t;
Run Code Online (Sandbox Code Playgroud)
Jon*_*art 17
typedef struct queue_item_t { // 1
vpoint_t void_item;
struct queue_item_t* next; // 2
} queue_item_t; // 3
Run Code Online (Sandbox Code Playgroud)
首先,请注意这整个陈述是定义一个typedef.
3)说我们正在定义(via 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;
Run Code Online (Sandbox Code Playgroud)
但是,在您的示例中,由于我们需要结构能够引用自身,因此next指针必须具有已定义的类型.我们可以通过前面声明 struct,typedefing然后使用typedefd类型定义struct来实现next:
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
}
Run Code Online (Sandbox Code Playgroud)
4)声明struct _queue_item存在,但尚未提供它的定义.
5) Typedef queue_item_t与struct _queue_item.相同.
6)现在给出结构的定义......
7) ...使用我们的typedef'd queue_item_t.
所有这一切......在我看来,请不要使用typedef作为结构.
struct queue_item {
void *data;
struct queue_item *next;
}
Run Code Online (Sandbox Code Playgroud)
简单而完整.您可以设法键入这六个额外的字符.
第5章:Typedef
请不要使用"vps_t"之类的东西.将typedef用于结构和指针是错误的.当你看到一个
Run Code Online (Sandbox Code Playgroud)vps_t a;在源头,这是什么意思?相反,如果它说
Run Code Online (Sandbox Code Playgroud)struct virtual_container *a;你实际上可以告诉"a"是什么.
有一些例外情况,您可以阅读.
最近的一些相关问题:
让我们稍微更改一下声明,使讨论更容易进行:
typedef struct queue_item {
vpoint_t void_item;
struct queue_item* next;
} QueueItemType;
Run Code Online (Sandbox Code Playgroud)
C支持几种不同的名称空间;为联合,结构和枚举类型上的标记名称保留一个名称空间。在这种情况下,标签名称为queue_item。另一个名称空间为常规标识符保留,包括typedef名称,如QueueItemType。
该next成员用于指向另一个类型的实例struct queue_item(即队列中的下一个项目)。声明它为的指针struct queue_item有两个原因:
struct类型不能包含其自身的实例;一方面,类型必须无限大(struct queue_item包含一个member next,这是一个struct queue_item包含member next,这是a struct queue_item包含一个member next,ad infinitum);
直到close ,结构类型定义才完整},您不能声明不完整类型的实例。但是,您可以声明一个不完整类型的指针,我们将在下面进行操作:
struct queue_item *下一步;
为什么不使用QueueItemType *next;代替struct queue_item *next?同样,结构类型定义在声明时还不完整next。typedef名称QueueItemType尚不存在。但是,标记名称queue_item已经对编译器可见,因此我们可以使用type声明指针struct queue_item。
由于标记名称和typedef名称占用不同的名称空间,因此可以将相同的名称用于标记名称和typedef名称而不会发生冲突。编译器通过struct关键字的存在来消除两者之间的歧义。
| 归档时间: |
|
| 查看次数: |
3107 次 |
| 最近记录: |