2

可能重复:
typedef struct vs struct 定义

最近在看nginx源码。有很多结构定义为

typedef struct {
    field_1;
    field_2;
    /* ... */
} some_obj_t;

但仍有一些其他结构定义为

struct some_obj_s {
    field_1;
    field_2;
    /* ... */
};

然后,在其他一些头文件中,例如ngx_core.h,做一些typedef

typedef struct some_obj_s some_obj_t;

我的问题是(可能重复...):

  • 为什么作者不使用相同的形式来定义所有结构?
  • 在什么情况下我们应该typedefstruct定义上使用?是否有任何 OO 或设计模式注意事项?
4

4 回答 4

3

您在结构上使用 typedef 主要是为了方便。例如:

typedef struct List_
{
    ...

} List;

这允许您将 List 类型的变量简单地定义为:

List myList;

代替:

struct List_ myList;

所有这些额外的结构语句都会使您的代码变得混乱。如您所示, typedef 的另一种用途是将一种类型实现为另一种类型。例如:

typedef List Queue;

这将新类型 Queue 定义为先前定义的类型 List。然后,您可以像使用 List 一样使用 Queue。

于 2012-10-10T05:03:45.803 回答
1

不同的用途反映了该类型是否(仅)用于接口,或者是否必须知道结构信息。

符号:

typedef struct some_obj_s some_obj_t;

告诉编译器有一个带有 tagsome_obj_s和 typedef name的结构类型some_obj_t。如果此类型对用户来说是不透明的类型,则无需指定结构的详细信息。some_obj_t *可以声明和使用带有参数(可能是限定的)或返回此类值的函数,而无需进一步的信息。(你甚至可以声明这种类型的extern变量,因为编译器主要需要一个地址。)类型不完整(也称为不透明),但可以完成。

在实现的某个地方,您会找到结构类型的定义(除了最不寻常的情况),例如:

struct some_obj_s
{
    ...members defined...
};

如果此声明(定义)在范围内,您可以创建some_obj_tor类型的变量struct some_obj_s,以及指向该类型的指针。代码可以使用结构的成员。

符号:

typedef struct /* no tag */
{
    ...
} another_obj_t;

定义了一个无标记的结构类型。提供了类型的详细信息,因此类型是完整的。

您可能还会看到:

typedef struct yao_s
{
   ...members defined...
} yao_t;

这两者都使用其标记和 typedef 声明结构类型。

单独的 typedef 具有自引用结构的优势,例如列表:

typedef struct GenericList GenericList;
struct GenericList
{
    void        *data;
    GenericList *next;
    GenericList *prev;
};

如果没有单独的typedef行,您必须struct GenericList在结构内部编写。这意味着同样的事情;你仍然可以写它;但是使用单独的 typedef,您可以在结构中使用与稍后引用它相同的符号。

请注意,POSIX为实现保留类型名称结尾_t。这意味着在您自己的代码中使用该约定可能很危险。

不需要为标签和 typedef 使用单独的名称(如GenericList示例所示),尽管_sand_t后缀也是一个众所周知的约定。C++ 会自动将标签变成类型名,不需要显式 typedef(但允许显式 typedef),所以我通常使用相同的标签和类型名称。

于 2012-10-10T05:05:31.887 回答
0

为什么作者不使用相同的形式来定义所有结构?

因为他们采用了一定的编码风格。

例如,Linux 内核编码标准使用没有 typedef 的结构表示法。那是纯粹的编码风格,他们没有令人信服的理由说明为什么要这样做,他们只是相信代码中的“结构”提高了可读性,因为他们认为 typedef “隐藏了类型”。

其他人不同意,例如 Windows API 全部使用 typedef 表示法,而从不使用 struct 表示法。我想说这种编码风格要普遍得多,因为它让人想起许多支持 OO 的语言风格:C++、Java、C# 等。

任何形式都不能轻易地被证明是正确的,这都是非常主观的。像大多数编码风格一样重要。

在哪种情况下,我们应该在结构定义上使用 typedef?是否有任何 OO 或设计模式注意事项?

确实有。C 中有一些称为不透明或不完整类型的东西,它允许您实现变量的真正私有封装。请参阅我昨天发布的这个示例。

在那个例子typedef struct vector vector;中,头文件中有一个,它基本上创建了一个抽象基类:调用者可以创建指针但不能分配的对象。调用者将永远无法访问结构成员。

然后在 .c 文件中,有一个结构的实现,struct vector { ... };它只对 .c 文件可见,而对调用者不可见。

于 2012-10-10T06:51:04.130 回答
-1

请通过以下链接找到第二个问题的答案:

为什么我们要在 C 中如此频繁地对结构进行 typedef 呢?

于 2012-10-10T05:05:07.987 回答