每个源文件的标头

时间:2009-07-22 20:02:16

标签: c header

我正在尝试了解每个源文件方法的一个标头背后的目的。正如我所看到的,标题用于在使用它们的几个文件之间共享函数声明,typedef和宏。当您为.c文件创建头文件时,它的缺点是每次要查看函数声明或宏时都需要引用头文件,通常一切都在一个源中更简单文件(当然不是整个软件)。

那么为什么程序员会使用这种方法?

7 个答案:

答案 0 :(得分:7)

C中的头文件单独声明(必须可用于使用这些函数的每个.c文件)来自定义(必须在一个位置)。此外,它们提供了一点模块性,因为您只能将公共接口放入头文件中,而不能提及应该在.c文件内部的函数和静态变量。它使用文件系统来提供公共接口和私有实现。

一个.h文件到一个.c文件的做法大多是方便的。这样,您就知道声明在.h文件中,以及相应的.c文件中的定义。

答案 1 :(得分:7)

逻辑,结构化组织和小型源文件启用:

  • 更快,更好的编程 - 将代码分解为更易于管理和可理解的块,可以更轻松地查找,理解和编辑相关代码。
  • 代码可重用性 - 代码的不同“模块”可以分为源/头文件组,您可以更轻松地将它们集成到不同的程序中。
  • 更好的“封装” - 只有专门包含该标头的.c文件才能使用其中的功能,这有助于您最小化代码不同部分之间的关​​系,这有助于模块化。它不会阻止您从任何地方使用东西,但它可以帮助您思考特定c文件为什么需要访问特定标头中声明的函数。
  • 帮助团队合作 - 两个试图同时更改相同代码文件的程序员通常会导致问题(例如排他锁)或额外工作(例如代码合并),这些问题会相互减慢。
  • 更快的编译 - 如果您有一个标题,那么每次更改它时都必须重新编译所有内容。对于许多小标题,只有#include更改的标题的.c文件必须重建。
  • 更易于维护重构 - 出于上述所有原因

特别是,“每个源文件的一个标头”使得查找与您正在使用的c文件相关的声明变得非常容易。一旦开始将多个标头合并到一个文件中,它就会开始变为很难将c和h文件联系起来,最终使构建大型应用程序变得更加困难。如果你只是在一个小应用程序上工作,那么养成使用可扩展方法的习惯仍然是一个好主意。

答案 2 :(得分:4)

因为,正如您所说,将“整个软件”放入一个源文件是不可行的。

如果您的程序非常小,那么只需将所有内容放在一个.c文件中就更简单了。随着程序变大,通过将相关函数放在不同的.c文件中来组织事物会很有帮助。此外,在.h文件中,您可以限制您为其他.c文件中的内容使用所谓的内容的声明所声明的声明。如果.c文件不包含任何本身可以访问的文件,则不需要标题。

例如,如果.c有函数foo()和fooHelper(),但除了foo()之外的任何人都应该直接调用fooHelper(),那么只需将foo()和fooHelper()放入foo.c中,将foo()的声明放在foo.h中,并将fooHelper()声明为静态,它有助于强制程序的其他部分只应访问foo()并且不应该知道或关心fooHelper()。一种非面向对象的封装形式。

最后,make引擎通常足够智能,只能重建自上次构建以来已更改的文件,因此拆分为多个.c文件(使用.h文件共享需要共享的内容)有助于加快构建。 / p>

答案 3 :(得分:4)

您只需在头文件中输入其他源文件为了编译而“查看”所需的最低限度。我已经看到一些人将所有非代码放入头文件(所有typedef,所有#define,所有结构等),即使代码库中没有其他内容将使用它们。这使得头文件更难以为自己和想要使用模块的人阅读。

答案 4 :(得分:4)

程序员使用这种方法是因为允许他们将接口与实现分开,而保证客户端代码和实现在函数声明上达成一致。 .h文件是关于每个函数原型的“单点事实”(参见“不要重复自己”)。

(客户端代码是#include为.h文件的代码,以便使用导出的函数,但不实现.h中的任何函数。)

答案 5 :(得分:1)

每个源文件不需要一个标头。每个模块一个标头,包含公共接口,可能还包含一个包含私有声明的标头,以及该模块中文件之间共享的标头。

答案 6 :(得分:0)

通常,源文件方法的标头意味着您只声明该标头中该编译单元的函数。

这样你就不会污染你不需要的声明。 (在大型软件项目中可能存在问题)

对于单独的编译单元,如果将私有符号声明为静态,这些可以加速编译并帮助您避免冲突。