在哪种情况下我们应该使用typedef进行结构定义?

时间:2012-10-10 04:48:28

标签: c struct typedef

  

可能重复:
  typedef struct vs struct definitions

最近我正在阅读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;

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

  • 为什么作者不使用相同的形式来定义所有结构?
  • 在哪种情况下我们应该在typedef定义上使用struct?是否有任何OO或设计模式考虑因素?

4 个答案:

答案 0 :(得分:3)

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

typedef struct List_
{
    ...

} List;

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

List myList;

而不是:

struct List_ myList;

所有这些额外的struct语句都会使代码混乱。在你展示它时使用typedef的另一种方法是将一种类型实现为另一种类型。例如:

typedef List Queue;

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

答案 1 :(得分:1)

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

符号:

typedef struct some_obj_s some_obj_t;

告诉编译器,结构类型包含标记some_obj_s和typedef name some_obj_t。如果此类型是用户的opaque类型,则无需指定结构的详细信息。采用some_obj_t *参数(可能是合格的)或返回此类值的函数可以在没有进一步信息的情况下声明和使用。 (你甚至可以声明这种类型的extern variables,因为编译器主要需要一个地址。)类型不完整(也称为不透明),但可以完成。

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

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

如果此声明(定义)在范围内,您可以创建类型为some_obj_tstruct 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 reserves类型名称以_t结尾,用于实现。这意味着在您自己的代码中使用该约定会很危险。

不需要为tag和typedef使用单独的名称(如GenericList示例所示),尽管_s_t后缀也是一个众所周知的约定。 C ++自动将标记转换为类型名称而不需要显式的typedef(但允许使用显式的typedef),因此我通常对标记和类型使用相同的名称。

答案 2 :(得分:0)

  

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

因为他们采用了某种编码风格。

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

其他人不同意,例如Windows API全部使用typedef表示法,而不是结构表。我想说这种编码风格更为常见,因为它提醒了很多支持OO的语言风格:C ++,Java,C#等。

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

  

在哪种情况下我们应该在结构定义上使用typedef?是否有任何OO或设计模式考虑因素?

确实有。 C中有一些称为opaque或incomplete类型的东西,它允许你实现变量的真正私有封装。 See this example我昨天发布了。

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

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

答案 3 :(得分:-1)

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

Why should we typedef a struct so often in C?