什么时候.c文件应该没有关联的.h文件?

什么时候.c文件应该没有关联的.h文件?,c,header-files,C,Header Files,在C编程中,大多数情况下,每个代码文件(.C)至少会有一个头文件(.h),用于函数原型 什么时候不为代码文件创建头文件比较合适?最明显的情况是.c是完全独立的,不需要为其他.c文件创建原型或外部文件。这基本上只适用于非常小的程序,或者那些通过def文件导出以插入预定义接口的程序。如果您不需要.h文件中的声明,但实际上永远不需要。如果.c文件包含任何代码都不需要使用的数据 诚然,这是罕见的,但也可能发生。例如,我在嵌入式设备中这样做,用引导图形填充视频帧缓冲区。有一些使用案例。最明显的是,主程序很

在C编程中,大多数情况下,每个代码文件(
.C
)至少会有一个头文件(
.h
),用于函数原型


什么时候不为代码文件创建头文件比较合适?

最明显的情况是
.c
是完全独立的,不需要为其他
.c
文件创建原型或外部文件。这基本上只适用于非常小的程序,或者那些通过def文件导出以插入预定义接口的程序。

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

如果.c文件包含任何代码都不需要使用的数据


诚然,这是罕见的,但也可能发生。例如,我在嵌入式设备中这样做,用引导图形填充视频帧缓冲区。

有一些使用案例。最明显的是,主程序很少需要头文件

第二种情况是,每个C文件没有一个头。我以前已经把库放在一起(为了回答这个问题,让我们说一个BTree库),其中每个函数都在自己的源文件中,但有一个库范围的头文件,类似于:

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

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

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

我看到了大量的代码库,其中单个
.h
文件定义了与某个组件的接口,几个
.c
文件实现了它。纯粹出于可维护性的原因,将实现分为几个文件,并在某些逻辑范围内进行了尝试


有人可能会说,这种逻辑界限可以用于将组件划分为子组件,并因此具有多个头文件,但设计决策很少是非黑即白的事情,有时这种方法确实有意义。

通常,我将为“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 #包括“电机i” #取消锁定 #定义锁L1 #包括“电机i” #被锁定 请注意,在这个特定的嵌入式编译器上,->运算符的效率非常低,因此可以使用如下语句:

L0.speed++; L0->speed++; L0.speed++; 将编译为一条指令,而语句如下:

L0.speed++; L0->speed++; L0->speed++; 如果“速度”是结构中的第一项,则将转换为五条指令;如果它占据任何其他位置,则将转换为七条指令。因此,使用恒定可解析地址复制代码比使用一个例程处理两个电机要快得多,而且更节省空间


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

我认为期待.c和.h文件之间的1对1映射是一个糟糕的开始假设。扔掉它,重新开始。:D

以不同的方式看待您的问题,您可能会问“何时创建头文件合适?”

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

  • 为其他代码模块必须可用的公共接口/定义创建标头
  • 为必须在代码模块内共享但不与其他代码模块共享的专用接口/定义创建标头
  • 这些是您应该需要的唯一头文件。如果两者都不是必需的,则不需要头文件


    有些程序员喜欢人为地将原型/宏/typedefs/etc与.c中的全局函数/函数分离成一个.h。我建议不要使用这种方法,并建议将所有相关功能都放在一个文件中。然后根据需要移动到标题中,这些东西对于防止其他.c文件中出现“extern”是绝对必要的。

    我猜这个答案的一个推论是,门面模式通常会导致非一对一的.c到.h关系?