标头包含多个C文件

我有两个文件foo.c和bar.c,我用gcc -c单独编译然后链接。 这两个文件都需要stdio.h和stdlib.h头文件。

我是否必须将它们包括在内? 不觉得有点多余吗? 我应该使用#ifdef吗?

什么是最佳做法?

每个C文件都是不同的翻译单元 。 换句话说,它是一个完整的独立程序 ,在语法上完整和正确。 因此,每个C文件必须独立于任何其他C文件进行编译 ,并且必须包含它使用的每个标识符的每个声明,无论这些声明是否也出现在其他C文件中。 从编译器的角度来看,每个C文件本身都是一个完整的程序(尽管有未解析的引用)。

按照惯例, 头文件是包含必须出现在一组C文件中的声明的文件。 头文件可以包含在预处理器中 – 这是在包含点进行简单的文本复制和粘贴 – 以避免手动复制翻译单元之间的声明。

总结:在不同的C文件中包含相同的文件并不是多余的 – 这是正式要求的。

(之后,您目标文件(只是较小的程序)链接到一个较大的最终程序。较大的程序大致是较小子程序的总和,所有引用都在它们之间解决。一般来说,链接阶段对此没有任何了解。生成结果对象文件的原始文件的语言结构。)

您必须在两个文件中包含标题。 标头只是函数声明和常量声明的列表。 编译器需要这些以确保您的语法和函数调用是正确的。

头文件应该(并且将)有一个#ifndef包装器来防止这个问题(问题实际上是循环包含 – 你包括 – > foo.h包括bar.h bar.h包括foo.h)。

在您的情况下,实际上需要“重复”包含(对于函数原型,结构定义),因为(正如您所说)两个文件都是单独编译的。 foo.c的编译过程对bar.c的编译一无所知。

您必须在任何自己编译的文件中包含标题,即使您稍后将其链接也是如此。
标题中已有#ifdef,因此它实际上只会使用一次。

是的,你必须将它们都包括在内。 我主要使用C ++工作,我尽可能在我的.cpp文件中包含文件,只有在我必须的情况下才能在我的.h文件中。 这通常意味着在.h文件中执行某种类型的前向引用。

我参与的一些平台创建了一个包含一堆标准文件的.h,这样你就可以只包含一个文件。 就个人而言,我从来没有特别喜欢这种方法。

您编写的每个.h文件都应该包含所谓的“包含警卫”。 这些是#ifdef语句,可以防止标题被多次包含。 你会注意到你提到的那些已经包括警卫了。 但请确保将它们放在foo.h和bar.h中。