什么时候应该使用以下语句中的一种而不是另一种?
typedef struct Foo {
int a;
} Bar;和
typedef struct {
int a;
} Bar;并像这样使用它
Bar bar1 = { 5 };我知道第二个是匿名结构,但不确定什么时候应该使用一个而不是另一个。
发布于 2019-02-19 02:02:23
它们几乎是等同的。实际上,您可以并且应该在这两个位置使用相同的名称。使用相同的名称,除非你能想出一个很好的理由不这样做。
需要非匿名的一种情况是,当您希望指针指向相同类型的对象时,例如在链表中。
typedef struct Node {
struct Node* next;
int data;
} Node;一种替代方案:
typedef struct Node Node;
struct Node {
Node * next;
int data;
};根据Linus Torvalds的说法,你应该避免使用typedefing structs,除非你想隐藏它。从Linux kernel coding style guide
请不要使用像vps_t这样的东西。使用vps_t作为结构和指针是错误的。当您在源代码中看到vps_t a;时,它是什么意思?相反,如果它写的是struct virtual_container *a;,你实际上就能知道a是什么。
很多人认为typedefs有助于提高可读性。事实并非如此。它们仅在以下情况下有用:
a)完全不透明的对象(其中typedef被用来隐藏对象是什么)。
..。
根据这一点,你永远不应该使用匿名结构,而且typedefs是严格针对接口的。所以它应该看起来像这样:
typedef struct Node {
struct Node* next;
int data;
} Node;但是如果你真的在创建一个接口,你通常应该把它分成一个头文件和一个源文件。在这种情况下,将type放在头文件中,并且在源文件中根本不使用type:ed类型。
.c
struct Node {
struct Node* next;
int data;
} Node;
void insert(struct Node* head, int data)
{
// Code
} .h
typedef struct Node Node;
void insert(Node* head, int data);考虑到以上所有情况,使用匿名结构的唯一有效情况是同时声明一个对象,如下所示:
struct {
int data;
float more_data;
} myObject; 发布于 2019-02-19 02:01:05
这真的无关紧要。如果你使用带标签的表单,你可以有指向struct Foo内部struct Foo的指针(又称工具栏)
typedef struct Foo{
int a;
struct Foo *foop;
} Bar;但是对于第二种形式是无法做到这一点的
typedef struct {
int a;
//Baz *p; not valid here since Baz isn't a typename yet
} Baz;有些代码库根本不喜欢使用结构体,每次都会简单地用typedef关键字拼写struct Foo。
此外,对于第一种形式,您可以通过标记(struct Foo)或使用typedefs (Bar或任何将来/以前的typedef)来引用类型(您可以在提供定义之前执行typedef struct Foo PreviousTypedef; )。
另一方面,对于第二种形式,您只能使用Baz typedef和未来可能的typedef(您不能对结构执行前向操作,因为它没有标记)。
(请注意,typedef并不是真正用C定义类型,而是由struct optional_tag { /*...*/ }部分定义。相反,typedef提供了类型别名(因此可能应该将其命名为typealias)。
发布于 2019-02-19 02:01:15
有一次,如果你正在制作一个链表,就需要使用前者:
typedef struct list {
int data;
struct list *next;
} list;类型定义list在结构定义中不可见,因此您需要使用实际的结构名称来创建指向它的指针。
如果你没有这样的结构,你可以使用任何一种。
但是,您不应该使用以下划线开头的标记名,例如:
typedef struct _list {
int data;
struct list *next;
} list;因为以下划线开头的名称由实现保留。
https://stackoverflow.com/questions/54752861
复制相似问题