我正在浏览 libgphoto2 存储库并看到了这个:
struct _PTPObjectHandles {
uint32_t n;
uint32_t *Handler;
};
typedef struct _PTPObjectHandles PTPObjectHandles;
为什么有人想要这样做而不是仅仅调用结构PTPObjectHandles
并省略整typedef
行?
编辑:我可能应该注意到_PTPObjectHandles
代码中再也不会使用它了。
我正在浏览 libgphoto2 存储库并看到了这个:
struct _PTPObjectHandles {
uint32_t n;
uint32_t *Handler;
};
typedef struct _PTPObjectHandles PTPObjectHandles;
为什么有人想要这样做而不是仅仅调用结构PTPObjectHandles
并省略整typedef
行?
编辑:我可能应该注意到_PTPObjectHandles
代码中再也不会使用它了。
这样做的最常见原因只是为了缩短键入时间并开始看起来像“真实数据类型”。
例如,这个:
struct _PTPObjectHandles *ptr1;
int something;
struct _PTPObjectHandles *ptr2;
如果您将其重写为:
PTPObjectHandles *ptr1;
int something;
PTPObjectHandles *ptr2;
这是主要原因。
但是,它还为库开发人员提供了使您使用它的能力,可以在将来将其重新定义为其他内容。我见过将 typedef 从真实结构更改为指向结构的指针的案例(例如,OpenSSL)(例如)。(当然,这不起作用,但您可以想象 typedef 确实发生变化并且它会起作用的情况。)
所以,你必须吗?不。
人们这样做是为了让代码更具可读性吗?是的。
请注意,C++ 类实际上是在做同样的事情。如果您从头开始阅读一本好的 C++ 书籍,您会发现它首先以结构开头,然后将“结构”一词更改为“类”,并开始使用直接名称对其进行实例化。
编辑:并且...确保您阅读下面@Bathsheba 的评论并检查C 中的正确命名约定。正如他所指出的,它应该是带有小写p 的_pTPObjectHandles。对于我自己的风格,我避免使用大写 typedef,因为我喜欢我的大写类型是 C++ 中的真正类,并且想知道它们何时只是 typedef。但是,同样,这是一种风格选择。
部分原因是您可以在其内部转发引用结构,但也可以在其余代码中使用有意义的名称,这是:
struct _mylist
{
struct _mylist *next;
/* etc ... */
};
typedef struct _mylist MyList;
请注意,切换顺序会使事情更具可读性,但您仍然需要两个声明,因此:
typedef struct _mylist MyList;
struct _mylist
{
MyList *next;
/* etc ... */
};
你不能做的是:
typedef struct { MyList *next; } MyList;
所以你必须有2个声明。
我倾向于使用类似于第一种形式的东西,如下所示:
typedef struct _mylist
{
struct _mylist *next;
/* etc ... */
} MyList;
因为它很清楚这两种类型是相同的。
在该行代码之后,您可以仅使用PTPObjectHandles
. 创建该结构
没有 typedefstruct _PTPObjectHandles aStruct;
有 typedef:PTPObjectHandles aStruct;
这个模式用来表示“_PTPObjectHandles
是一个内部(技术)名称,不要使用它。使用它PTPObjectHandles
来代替。”
通常,在 C 语言中,前导下划线表示“这是内部的,走开”。对于没有适当名称空间的语言来说,这是一个便宜的解决方案(注意:我在这里谈论的是纯 C,而不是 C++)。