Why do we include header files in C

5

为什么在C语言中要包含头文件

我不明白为什么需要在C语言中添加头文件。如果不使用它们会发生什么?

7个回答

22

最初是一个带有跨递归的编译问题:

void foo() {
  //bar? what is this function???
  bar();
}

void bar() {
  //I know foo() because it appears before. 
  foo();
}
  • foo 只有在之前被定义了才能调用 bar
  • bar 只有在之前被定义了才能调用 foo

那么我们先定义哪个呢?

为了解决这个问题,出现了原型

//prototype of foo()
void foo();
//prototype of bar()
void bar();

void foo() {
  // I can call bar() because I know it exists
  bar();
}

void bar() {
  // I can call foo() because I know it exists
  foo();
}

然后原型被收集在.h文件中。

这成为了一种良好的实践方法,因为它把接口与实现分离开来。


很棒的例子! - Timur Fayzrakhmanov

9

大型项目会被编译为目标文件".o",然后链接在一个二进制文件中。

这意味着在编译时,如果访问位于另一个目标文件中的函数,编译器对它们没有任何了解,因此通过包含一个.h文件来声明将在链接时可用的函数,编译器相信它们将存在,而不会因缺少函数而引发错误。


抱歉,头文件并不是为此而设计的。您可以直接#include "another.c",只要您没有交叉递归的问题,它就会起作用。请查看我的答案以获取更多解释。(但我承认,在大多数情况下,#include "another.c"都是非常糟糕的做法)。 - Arnaud Denoyelle
1
当然会工作... 但它需要更多的编译时间,因为它会重新编译所有内容,而不仅仅是已更改的文件。 - LtWorf

4

实际上没有必要使用头文件。它们可以避免您在每个源文件中都包含所使用的所有函数的定义。头文件只是在使用#include的地方插入其内容而已。如果您愿意,完全可以自己编写所有内容。


1
如果您使用一些交叉递归,它们实际上非常有用。 - Arnaud Denoyelle
3
好的,根据您的回答,您可以像头文件中所做的那样编写函数原型。除了保持一致性外,实际上并没有必要使用它们(除非为了保证代码规范性)。 - Joey
2
没错,我同意。 - Arnaud Denoyelle

3

维基百科:

头文件是一种文件,允许程序员将程序源代码的某些元素分离到可重用的文件中。头文件通常包含类、子例程、变量和其他标识符的前向声明。希望在多个源文件中声明标准标识符的程序员可以将这样的标识符放在单个头文件中,然后在需要头文件内容时,其他代码就可以包含它。这是为了将接口与实现分开而将其放在头文件中。


0

除非你包含头文件或提供完全相同的声明(精确副本),否则其他头文件中的声明将无法在该文件中可见。

使用头文件是在源文件中使用另一个程序的最简单(也是唯一合理)方法。通过包含,您指示编译器读取文件的内容,以便您可以轻松地使用该文件中的任何内容。


0

计算机本身无法自行发现任何事情。它只是执行我们告诉它要做的事情[程序]。我们包含的文件也是如此,它提供了关于我们在程序中使用的命令以及如何使其工作的基本概念。这些信息存在于所包含的文件中。


0

它对于层次结构设计非常有用。您可以在不使用头文件的情况下编写c,然后您会发现每个源文件都变得太大而难以理解或使用,当您需要相同的代码时,您需要复制或重写它。通过“头文件”,我们可以将系统的不同部分分别编写到头文件中,然后我们可以进行测试或重用。


我只是使用这个网站,因为我想做一个类似的网站作为我的项目。请不要给我投反对票。 :) - Anirudh Garg
1
我喜欢层次结构。它们让我进入... 休眠状态。 - Engineer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接