C 为什么要将空结构设为新的typedef并将其用作指针类型?
我有一个标题和一个使用这个标题的示例应用程序,全部用C语言编写,除了这个,我几乎得到了这个软件的所有逻辑;这是标题的有趣部分:C 为什么要将空结构设为新的typedef并将其用作指针类型?,c,pointers,struct,typedef,C,Pointers,Struct,Typedef,我有一个标题和一个使用这个标题的示例应用程序,全部用C语言编写,除了这个,我几乎得到了这个软件的所有逻辑;这是标题的有趣部分: struct A; typedef struct A A; 在C应用程序中,此A仅在声明这样的指针时使用 A* aName; 我很确定这是一个解决方案,只需在作用域/名称空间中包含a,并为一个基本上无效的指针提供一个名称,因为这种指针只用于处理某种数据,它更像是某种名称空间糖 这可能是为了什么?我假设结构A是一个转发声明。它很可能是在一个.c-文件中定义的 这样做结
struct A;
typedef struct A A;
在C应用程序中,此A
仅在声明这样的指针时使用
A* aName;
我很确定这是一个解决方案,只需在作用域/名称空间中包含a
,并为一个基本上无效的指针提供一个名称,因为这种指针只用于处理某种数据,它更像是某种名称空间糖
这可能是为了什么?我假设结构A是一个转发声明。它很可能是在一个
.c
-文件中定义的
这样做
结构A的成员对于定义它的模块来说是私有的。您是正确的,它就像一个空指针,因为void
是一个不完整的类型,在这个文件中A
也是一个不完整的类型。对于不完整的类型,您所能做的就是传递指向它们的指针
与此文件中的void*
相比,它有一个优势,即它是一种不同的、不兼容的类型,不同于使用B
执行相同操作的其他代码位。所以你有点类型安全。如果A
是windowHandle
而B
是jpgHandle
,则不能将错误的传递给函数
它比.c
文件中的void*
具有优势,该文件定义了接受A*
的函数——该文件可以包含结构A
的定义,并为A
提供第一个文件不需要知道的任何成员
但是,您说在任何头文件中都没有提到A
,这意味着没有函数接受或返回它。您还说源文件中A
的唯一用途是声明指针——我想知道这些指针的值从何而来,如果有的话
如果有人定义了一个未初始化的A*
并且从未使用过它,那么很明显,这是一些旧代码的残余,或者是一些从未编写过的代码的开始,它不应该出现在文件中
最后,如果实际类型被称为比a
稍不愚蠢的名称,那么该名称可能会给出其用法的线索。这是一个不透明指针的示例,用于传递句柄。有关更多信息,请参阅。从C++的观点来看,可能有意思的是,您可以用一个成员定义一个类,该成员是指向(尚未)定义的代码>结构> <代码>的指针。尽管此struct
因此尚未在标头中定义,但在以后的一些cpp实现中,此struct
被赋予主体,其余部分由编译器完成。这种策略也被称为Pimpl习语(更多的习语可以在互联网上找到)。Microsoft在中简要讨论了它。结构A
可以在另一个头文件中定义,并且struct A
只是声明它,告诉编译器有一个名为a
的结构。typedef在那里只是为了避免到处写“struct”。@JoachimPileborg我实际上是在用doxygen扫描所有的标题,没有其他对这个标签的引用。@Andreashening我明白了,问题是它是空的。结构A
可能是一个系统结构,您不仅要检查自己的头文件,还要检查系统的所有头文件。我所说的检查是指进行适当的搜索,而不仅仅是信任Doxygen的输出。线索的问题是,这个名称是不言自明的,但没有类似的东西,没有任何库或其他包含可以提醒我这个名称或函数,看起来像是我无论如何都无法理解的东西,可能头不是很好,或者某个相关库已经包含了A的定义,但是如果库已经拥有why putstruct A的定义代码>?@Ken:由于typedef结构A,该行是多余的
本身为类型定义了两个名称:struct A
和A
。作者可能认为关于语法的这一事实并不清楚,因此更倾向于每行定义一个新的东西。但是,这并不影响它是一个不完整类型的事实,而且不完整类型的可能用途是有限的。之所以需要一个名字,是因为除此之外,a*aName代码>无法编译。