在C中使用typedef时,是否使用指向struct的指针

kon*_*ych 7 c struct pointers typedef list

为了在C中定义新的数据类型,例如链表的类型,
可以使用以下定义之一

struct list_node {
    int x;
    struct list_node * next;
};

//1
typedef struct list_node list1;
//2
typedef struct list_node *list2;
Run Code Online (Sandbox Code Playgroud)

从我所看到的,通常的做法是第一个定义.

问题是第二个定义是否也是可接受的做法.在哪种情况下,如果有人应该比第一个更喜欢第二个?如果我们使用的变量是struct list_node的指针,那么可以对两种类型执行相同的操作吗?第一个有什么好处?

Hav*_*c P 6

我要求API用户键入"*",即typedef结构,而不是指向结构的指针.这是GLib中广泛使用的样式,它是更受欢迎的C栈之一.

它运行良好,因为知道你是否有指向结构或结构本身的指针很重要的.例如,您可以在类型的变量中存储NULL吗?如果隐藏对象是指针,则必须创建特殊的NIL_NODE或其他值来替换NULL.如果你只是把它作为一个指针,那么人们可以像对待它一样.

另一个重要的好处是能够将实际的struct定义放在私有的位置,即在.c文件而不是在头文件中.您只需将typedef放在标头中,同时保持结构本身对API用户不透明.这要求人们只使用您提供的导出方法来操作结构.这也意味着如果更改结构字段,则不必重建世界.

采用这种方法的另一个原因是,有时你确实想要一个可以复制的结构,你仍然想要输入它.拿一个像GdkPoint这样的东西:

  typedef struct {
     int x, y;
  } GdkPoint;
Run Code Online (Sandbox Code Playgroud)

这里允许直接的struct访问很有用,例如:

 GdkPoint point = { 10, 10 };
 GdkPoint copy = point;
 do_stuff_with_point(&copy);
Run Code Online (Sandbox Code Playgroud)

但是,如果您的约定是"GdkPoint"typedef将是一个指针,那么您将不得不一致.

如果你可以告诉什么是指针和什么不是代码,代码就更清楚了,如果不在头文件中放置结构定义,代码会被更好地封装(对于表示抽象,不透明数据类型的结构,这可能是最常见的类).

我的C数据类型的默认模板在标题中是这样的:

typedef struct MyType MyType;
 MyType* my_type_new(void);
 void    my_type_unref(MyType *t);
 void    my_type_ref(MyType *t);
Run Code Online (Sandbox Code Playgroud)

然后是.c文件中的实际"struct MyType",以及该类型的new,unref和任何操作.

例外的是Point,Rectangle,Color等类型,它是"普通旧数据"并且需要直接字段访问; 另一种变化是如果您不需要引用计数,则使用my_type_free()而不是_unref().

无论如何,这是一种风格,基本上是GLib风格,它被广泛使用并且已知效果很好.

  • 我完全同意.使用`typedef`来隐藏类型是指针还是结构通常不是一个好主意(除非你为库接口使用不透明指针).老实说,我通常更喜欢调用`struct`一个`struct`并完全避免`typedef`,但是如果你要`typedef`的话,那就把它当成结构而不是指针. (2认同)