应该结构定义进入.h或.c文件?

我已经在头文件中看到了struct的完整定义,只是声明 – 对另一个方法有没有优势?

如果它有所作为,我通常在.h键入一个像这样的结构

 typedef struct s s_t; 

编辑

要清楚的是,这些选项是头文件中的声明和类中的定义,或者头文件中的声明和定义。 两者应该导致相同的可用性,即使是通过链接,不是吗?


我看到许多几乎重复,例如在这里,但没有完全匹配。 请纠正我,如果我在这方面的错误。

该文件的私有结构应该放在.c文件中,如果.h文件中的任何函数都使用.h文件中的声明,

公共结构应该在.h文件中。

两者应该导致相同的可用性,即使是通过链接,不是吗?

不,当您考虑包括相同标题的其他.c文件时。 如果该结构的定义对编译器不可见,则该定义的细节不能使用。 没有定义的声明(例如只是struct s; )会导致编译器失败,如果有东西试图查看struct s内部,而仍然允许它编译struct s *foo; (只要foo不在以后解除引用)。

比较这些版本的api.hapi.c

 Definition in header: Definition in implementation: +---------------------------------+ +---------------------------------+ | struct s { | | struct s; | | int internal; | | | | int other_stuff; | | extern void | | }; | | api_func(struct s *foo, int x); | | | +---------------------------------+ | extern void | +---------------------------------+ | api_func(struct s *foo, int x); | | #include "api.h" | +---------------------------------+ | | +---------------------------------+ | struct s { | | #include "api.h" | | int internal; | | | | int other_stuff; | | void | | }; | | api_func(struct s *foo, int x) | | | | { | | void | | foo->internal = x; | | api_func(struct s *foo, int x) | | } | | { | +---------------------------------+ | foo->internal = x; | | } | +---------------------------------+ 

该API的客户端可以使用以下任一版本:

 #include "api.h" void good(struct s *foo) { api_func(foo, 123); } 

这个在实现细节中探讨:

 #include "api.h" void bad(struct s *foo) { foo->internal = 123; } 

这将与“头文件中的定义”一起工作,但不与“实现中的定义”版本一起工作,如在后一种情况下,编译器没有可见的结构布局:

 $ gcc -Wall -c bad.c bad.c: In function 'bad': bad.c:5: error: dereferencing pointer to incomplete type $ 

因此,“实施​​中的定义”版本可以防止意外或故意滥用私人实施细节。

如果结构要被其他编译单元(.c文件)使用,则将其放在头文件中,以便在需要的地方包含该头文件。

如果该结构仅用于一个编译单元(.c文件),则将其放在该.c文件中。

重点在于,将它放在一个头文件中允许你使用来自多个源文件的结构(或任何其他定义),只要包含该头文件即可。

但是如果你确定它只能从一个源文件中使用,那么它确实没有什么区别。

我把它们放到C文件中,使其更加面向对象, 参见这篇文章 。

一般来说,不pipe你把它们放在头文件还是源文件中,都不会有什么大的变化。 但是,如果您需要从多个源文件访问结构的成员,则将结构放在头文件中并将其包含在需要结构的其他任何文件中会更容易。