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

In which cases should we use typedef for a structure definition?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
typedef struct vs struct definitions

最近我在读nginx源代码。有这么多的结构被定义为

1
2
3
4
5
typedef struct {
    field_1;
    field_2;
    /* ... */
} some_obj_t;

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

1
2
3
4
5
struct some_obj_s {
    field_1;
    field_2;
    /* ... */
};

然后,在其他一些头文件(如ngx_core.h中,执行一些typedef操作:

1
typedef struct some_obj_s some_obj_t;

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

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


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

1
2
3
4
5
typedef struct List_
{
    ...

} List;

这允许您将list类型的变量定义为:

1
List myList;

而不是:

1
struct List_ myList;

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

1
typedef List Queue;

这将新类型队列定义为以前定义的类型列表。这样就可以像使用列表一样使用队列。


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

注记:

1
typedef struct some_obj_s some_obj_t;

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

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

1
2
3
4
struct some_obj_s
{
    ...members defined...
};

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

注记:

1
2
3
4
typedef struct /* no tag */
{
    ...
} another_obj_t;

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

您还可以看到:

1
2
3
4
typedef struct yao_s
{
   ...members defined...
} yao_t;

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

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

1
2
3
4
5
6
7
typedef struct GenericList GenericList;
struct GenericList
{
    void        *data;
    GenericList *next;
    GenericList *prev;
};

如果没有单独的typedef行,则必须在结构内部编写struct GenericList。这意味着相同的事情;您仍然可以编写它;但是对于单独的typedef,您可以在结构中使用相同的表示法,正如您稍后将使用的那样。

注意,posix为实现保留以_t结尾的类型名。这意味着在您自己的代码中使用该约定是危险的。

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


Why do authors not use the same form to define all structures?

因为它们采用了某种编码方式。

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

其他人不同意,例如,WindowsAPI使用的全是typedef表示法,而不是结构表示法。我认为,这种编码方式更为常见,因为它提醒了很多面向OO支持的语言风格:C++、爪哇、C等。

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

In which case(s) should we use typedef on a struct definition? Is there any OO or design pattern considerations?

确实有。在C语言中有一种不透明或不完整的类型,它允许您实现变量的真正私有封装。看看我昨天发布的这个例子。

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

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


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

为什么我们要在C中如此频繁地使用typedef结构?