题
说我有一C节目,它坏了一套*.c*.h文件。如果代码从一个文件使用的职能从另一文件,其中应包括我的头文件?内*.c文件,使用该功能、或内部的头的这一文件?
E.g。文件 foo.c
包括 foo.h
, ,其中包含的所有声明 foo.c
;同样用于 bar.c
和 bar.h
.功能 foo1()
内部 foo.c
电话 bar1()
, ,其中声明 bar.h
和定义 bar.c
.现在的问题是,应该包括我 bar.h
内部 foo.h
, 或内部 foo.c
?
是什么将是一个很好的设定的规则的经验,这种问题?
解决方案
你应该包括foo。h内foo。c.这种方式的其他文件,包括foo。h不会进行吧。h不必要的。这是我的建议包括标题的文件:
- 增加的定义包括在文件c-这种方式的文件的依赖性更加明显,当阅读的编码。
- 分裂foo。h在两个单独的文件,说foo_int.h和foo。h。第一个携带的类型和向声明,只需要通过foo。c.Foo.h包括的职能和类型需要通过外部模块。这是我喜欢的私人和公共部foo。
- 避免交叉引用,即foo引用酒吧和酒吧,引用foo。这可能导致联的问题,也是一个迹象的糟糕的设计
其他提示
正如其他人所说,标题foo.h应声明能够使用源文件foo.c提供的功能所必需的信息。这将包括foo.c提供的类型,枚举和函数。 (你不使用全局变量,不是吗?如果你这样做,那么那些也在foo.h中声明。)
标题foo.h应该是自包含的和幂等的。自包含意味着任何用户都可以包含foo.h而不需要担心可能需要哪些其他头文件(因为foo.h包含那些头文件)。幂等意味着如果标题包含多次,则不会造成任何损害。这是通过经典技术实现的:
#ifndef FOO_H_INCLUDED
#define FOO_H_INCLUDED
...rest of the contents of foo.h...
#endif /* FOO_H_INCLUDED */
问的问题是:
文件foo.c包含foo.h,其中包含foo.c的所有声明;对于bar.c和bar.h也是如此。 foo.c中的函数foo1()调用bar1(),它在bar.h中声明并在bar.c中定义。现在的问题是,我应该在foo.h中包含bar.h,还是在foo.c中包含?
这取决于foo.h提供的服务是否依赖于bar.h。如果使用foo.h的其他文件需要bar.h定义的类型或枚举之一才能使用foo.h的功能,那么foo.h应该确保包含bar.h(通过包含它)。但是,如果bar.h的服务仅在foo.c中使用,并且使用foo.h的人不需要,则foo.h不应包含bar.h
我只会在头文件本身所需的* .h文件中包含头文件。在我看来,源文件所需的头文件应该包含在源文件中,以便从源中明显看出依赖关系。应该构建头文件以处理多个包含,因此为了清楚起见,您可以将它放在两者中。
我在 .h
文件中包含了最小的标头集,并将其余部分包含在 .c
文件中。这有利于减少编译时间。举个例子,如果 foo.h
真的不需要 bar.h
但是还是包含它,而其他一些文件包含 foo.h
,如果 bar.h
发生变化,那么该文件将被重新编译,即使它实际上可能不需要或使用 bar.h
。
.h文件应该定义.c文件中函数的公共接口(也就是api)。
如果file1的接口使用file2的接口,那么#include file2.h在file1.h中
如果file1.c中的实现使用了file2.c中的东西,那么file1.c应该#include file2.h。
我必须承认 - 虽然我总是#include file1.h在file1.c中 - 我通常不会在file1.c中直接#including file2.h,如果它已经在file1.h中#include
如果您发现自己处于两个.c文件#include彼此.h文件的情况,那么这表明模块化已经崩溃,您应该考虑重组一些事情。
使用的实例 foo.c
和 foo.h
我发现这些指导方针有所帮助:
记住,目的
foo.h
是要便于使用的foo.c
, ,因此,保持它作为简单、有组织的和不言自明的,因为可能。将自由带有注解释 如何 和 时 使用的特点foo.c
-当 不 使用它们。foo.h
宣布公的特点foo.c
:功能、宏typedef,和(不寒而栗)全球变量。foo.c
应该#include "foo.h
-看到讨论,并且还乔纳森*莱弗勒的以下评论。如果
foo.c
需要额外头为它编纂,包括他们在foo.c
.如果外部头都需要
foo.h
汇编,包括他们在foo.h
利用预处理,以防止
foo.h
从被包含超过一次。(请见下文。)如果由于某种原因,外部头,将需要为使另一个
.c
文件使用的功能foo.c
, 包括头foo.h
保存下来的开发人员的不必要调试。如果你不愿意到这一点,考虑加入宏观,这将显示说明在编写时间如果需要的标题还没有被包括在内。不不 包括一个
.c
文件内的另一个.c
文件除非你有一个 非常 很好的理由和文件,它清楚。
作为kgiannakakis指出,它将有助于独立的公共口从定义和声明只需要内 foo.c
本身。但是,而不是创建两个文件,它有时候最好让预处理器为你做这个:
// foo.c
#define _foo_c_ // Tell foo.h it's being included from foo.c
#include "foo.h"
. . .
// foo.h
#if !defined(_foo_h_) // Prevent multiple inclusion
#define _foo_h_
// This section is used only internally to foo.c
#ifdef _foo_c_
. . .
#endif
// Public interface continues to end of file.
#endif // _foo_h_ // Last-ish line in foo.h