2010-10-28 196 views

回答

8

这里有几个用例。最明显的是你的主程序很少需要头文件。

第二个是你的不要对每个C文件都有一个标题。我已经把库之前(比方说,一个B树库这个答案的目的),其中每个独立的功能是其自己的源文件,但有一个图书馆,宽头文件,是这样的:

btree.h 
btree_priv.h 
btreeInit.c 
btreeDestroy.c 
btreeConfig.c 

和等等。专用头文件用于需要在代码之间共享的内容,但不会在API中发布。

+0

所以我想这个答案的一个必然结果是门面模式往往会导致非一对一的.c到.h关系? – Tommy 2012-02-11 15:43:12

5

最明显的是当.c完全自包含,并且不需要为其他.c文件创建原型或外部文件。这基本上只适用于非常小的程序或通过def文件导出到预定义界面的插件。

1

如果您不需要.h文件中的声明,但实际上永远不会。

3

当.c文件包含不需要被任何代码使用的数据时。

无可否认这是罕见的 - 但它可能发生。例如,我已经在嵌入式设备中完成这项工作,用引导图形填充视频帧缓冲区。

3

如果您将程序划分为多个模块,通常会有一个“main”模块,其中包含main()函数以及其他一些内容。如果此模块没有任何应该被其他模块调用或使用的内容,则不需要在.h文件中导出接口。

5

我见过大量的代码库,其中一个.h文件定义了某个组件的接口,并且有几个.c文件实现它。为了可维护性的原因,这个实现被分成几个文件,并且试图在一些逻辑范围内进行。有人可能会争辩说,这样一个逻辑界限可以用来将组件分成子组件,因此有多个头文件,但是设计决策很少是白色事物,有时这种方法确实有意义。

1

很多时候,即使我不期望其他代码必须访问它,我也会为'main'创建一个头文件,因为(1)调试版本最终会在主模块之外(2)由于(嵌入式系统)编译器限制,主模块最终不得不分裂。每个.c文件包含它自己的.h文件的模式足够强大,以至于我经常创建几乎空的.h文件,即使是定义了代码中未引用的东西的.c文件(例如中断跳转表等)。

当一个文件包含多个程序生成的文件或者包含需要多次编译的文件(例如,文件)时,命名约定会变得更复杂一些。我的一个项目有两个电机,其代码相同,只是它们使用不同的I/O端口和不同的变量;我motor.c文件包含:

 
#define LOCK L0 
#include "motor.i" 
#undef LOCK 
#define LOCK L1 
#include "motor.i" 
#under LOCK 

注意,在这个特定的嵌入式编译器, - >操作是非常低效的,所以如下语句:

 
    L0.speed++; 

将编译成一个指令,而声明一样:

 
    L0->speed++; 

将转化为五个指令,如果“速度”是在结构中的第一项,或七个,如果它占据任何其他职位。因此,复制具有恒定可解析地址的代码比使一个例程处理两个电动机的代码快得多,且更节省空间。

如果有一个与.c文件关联的额外文件,并且它包含真实代码,我会将其命名为“.i”。不知道如果有多个,该怎么办。

3

我认为.c和.h文件之间的1对1映射是一个不好的开始假设。抛出并开始新鲜。 :D

不同地看着你的问题,你可能会问:“什么时候创建一个头文件是合适的?”

我会建议以下,其中术语“代码模块”是一个或多个相关.c文件组(通常是目录):

  1. 创建公共接口/定义一个报头必须可用于其他代码模块。
  2. 为必须在代码模块内共享但不与其他代码模块共享的专用接口/定义创建标头。

这些是你唯一需要的头文件。如果这些都不是必需的,那么你不需要头。

一些编码人员喜欢人为地将原型/宏/ typedefs/etc分隔成独立于.c中的全局变量/函数的.h。我建议不要这种方法,并建议在一个文件中包含所有相关的功能。然后,根据需要移动到标题,以防止在其他.c文件中出现'extern'。

相关问题