0

我正在浏览 libgphoto2 存储库并看到了这个:

struct _PTPObjectHandles {
    uint32_t n;
    uint32_t *Handler;
};
typedef struct _PTPObjectHandles PTPObjectHandles;

为什么有人想要这样做而不是仅仅调用结构PTPObjectHandles并省略整typedef行?

编辑:我可能应该注意到_PTPObjectHandles代码中再也不会使用它了。

4

4 回答 4

2

这样做的最常见原因只是为了缩短键入时间并开始看起来像“真实数据类型”。

例如,这个:

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。但是,同样,这是一种风格选择。

于 2014-04-01T13:40:58.333 回答
1

部分原因是您可以在其内部转发引用结构,但也可以在其余代码中使用有意义的名称,这是:

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;

因为它很清楚这两种类型是相同的。

于 2014-04-01T13:55:37.907 回答
0

在该行代码之后,您可以仅使用PTPObjectHandles. 创建该结构

没有 typedefstruct _PTPObjectHandles aStruct;
有 typedef:PTPObjectHandles aStruct;

于 2014-04-01T13:43:22.323 回答
0

这个模式用来表示“_PTPObjectHandles是一个内部(技术)名称,不要使用它。使用它PTPObjectHandles来代替。”

通常,在 C 语言中,前导下划线表示“这是内部的,走开”。对于没有适当名称空间的语言来说,这是一个便宜的解决方案(注意:我在这里谈论的是纯 C,而不是 C++)。

于 2014-04-01T14:04:18.030 回答