C中的源文件和头文件之间有什么根本区别?

时间:2010-08-14 10:42:04

标签: c

我不太明白应该如何在C的源文件和头文件中分隔。我经常看到许多项目有两组具有相同名称的文件(没有表示源文件和头文件的扩展名)。

到目前为止,由于缺乏理解,当我编写库时,我已经将所有类和类方法代码放入一个文件中,并且选择文件扩展名时犹豫不决。

标题中应包含哪些内容以及源文件中应包含哪些内容?我该如何实现这种分离?

4 个答案:

答案 0 :(得分:60)

没有技术的区别。如果您愿意,编译器很乐意让您包含.c文件或直接编译.h文件。

然而,存在巨大的文化差异:

  • 声明(原型)进入.h个文件。 .h文件是相应.c文件中实现的接口

  • 定义进入.c个文件。他们实现 .h文件中指定的接口。

不同之处在于.h文件可以(并且通常会)#include进入多个编译单元(.c文件)。如果.h文件中定义一个函数,它将以多个.o文件结束,并且链接器会抱怨多重定义的符号。这就是定义不应该放在.h文件中的原因。 (内联函数是例外。)

如果在.c文件中定义了一个函数,并且您想要从其他.c文件中使用它,则需要在其他.c中提供该函数的声明。 }文件。这就是为什么你把声明放在.h#include中的原因。您还可以在每个.c文件中重复声明,但这会导致大量代码重复和无法更替的混乱。

如果在.c文件中定义了一个函数,但想要从其他.c文件中使用它,则无需在其中声明它头。它本质上是.c文件的实现细节。在这种情况下,也要创建函数static,这样它就不会与其他文件中具有相同名称的函数冲突。

答案 1 :(得分:14)

  

标题中应包含哪些内容以及源文件中应包含哪些内容?

通常标头包含以下一项或多项:

  • 功能声明(静态除外)
  • 变量声明(通常为全局)
  • 用户定义的类型声明(阅读structunion等。)
  • 宏定义

另一方面,源文件有:

  • 功能/变量定义
  • 静态函数声明和定义(您不希望将这些公开给客户)
  • 变量定义
  • 有些人更喜欢在标题
  • 中定义内联函数(C99)
  

如何实现这种分离?

One Definition Rule是您的朋友。

请记住,如果您正在编写库,那么这就是您的客户可以看到的内容。因此,请提供帮助,并提供可供他们使用您的图书馆的所有信息。源文件通常以二进制形式编译和提供。

顺便说一下,C没有类的概念。

答案 2 :(得分:2)

通常,头文件包含声明,源文件包含代码。

因此,如果在源文件A.c中需要在源文件B.c中实现的函数,则只需包含B.h即可获得其声明。

答案 3 :(得分:1)

.c和.h文件之间几乎没有根本区别(尽管有些编译器可能会拒绝编译原始的.h文件)。差别更多的是按惯例。

通常.h文件提供API,而.c提供实现。

因此.h文件只包含其他源文件访问.c文件提供的工具所需的内容。因此.h文件将提供全局函数的函数原型,全局变量的声明(如果你真的必须拥有它们),以及它们使用的结构和其他类型。 (如果API只需要指向结构的指针,则不要公开结构。)

.h文件中也经常包含内联函数,但某些编码指南更喜欢使用单独的扩展名(例如.inl)

所有其他函数实现,变量的定义和初始化以及本地(静态)变量和函数的声明都将在.c文件中。