结构定义应该放在.h还是.c文件中?

Aar*_*ken 96 c struct header

我已经struct在头文件和声明中看到了s的完整定义- 一种方法对另一种方法有什么优势吗?

如果它有所不同,我通常会在这里输入一个这样的结构 .h

typedef struct s s_t;
Run Code Online (Sandbox Code Playgroud)

编辑

需要明确的是,选项是头文件中的声明和类中的定义,或者头文件中的声明和定义.两者都应该产生相同的可用性,即使一个是通过联系,不应该吗?


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

τεκ*_*τεκ 98

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

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

  • 我想我更赞同这个答案.它不是通过任何其他.c文件使用结构,而是结构是否应被视为公共(因此,可访问). (4认同)
  • @Geo Papas这是一个关于C的问题.`public`不是C中的关键字.如果你看下面的Matthew Slattery的答案,你可以看到如何在标题中仅使用前向声明导致编译器错误,当用户尝试使用时私有(不透明)结构的成员. (3认同)

Mat*_*ery 67

两者都应该产生相同的可用性,即使一个是通过联系,不应该吗?

不,当你考虑包括相同标题的其他.c文件时.如果编译器看不到结构的定义,则不能使用该定义的详细信息.没有定义的声明(例如just 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;          |
                                      | }                               |
                                      +---------------------------------+
Run Code Online (Sandbox Code Playgroud)

API的此客户端适用于以下任一版本:

#include "api.h"

void good(struct s *foo)
{
    api_func(foo, 123);
}
Run Code Online (Sandbox Code Playgroud)

这个在实现细节中探讨:

#include "api.h"

void bad(struct s *foo)
{
    foo->internal = 123;
}
Run Code Online (Sandbox Code Playgroud)

它将使用"头文件中的定义"版本,但不适用于"实现中的定义"版本,因为在后一种情况下,编译器无法看到结构的布局:

$ gcc -Wall -c bad.c
bad.c: In function 'bad':
bad.c:5: error: dereferencing pointer to incomplete type
$
Run Code Online (Sandbox Code Playgroud)

因此,"实现中的定义"版本可防止意外或故意滥用私有实现细节.

  • 只是想知道你是如何创建这些代码窗口的,并且仍然在其中突出显示代码...手动?这个OP似乎已经使用了stackoverflow:'(其他人可以告诉我...... (2认同)

nos*_*nos 7

如果结构将由其他编译单元(.c文件)使用,请将其放在头文件中,以便您可以在任何需要的地方包含该头文件.

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


Jon*_*ood 6

关键是,将其放在头文件中允许您使用多个源文件中的结构(或任何其他定义),只需包含该头文件即可。

但如果您确定它只会从一个源文件中使用,那么它实际上没有任何区别。