C - 如何在没有include语句的情况下包含C源文件

3

我已经决定学习C语言。从使用脚本语言(如php、perl)和一点点的C#语言背景来看,这是一个相当不错但可控的学习曲线。

我使用了网站“学习C语言的艰难之路”,到目前为止我认为自己理解得还不错,但有一部分练习题我无法理解:

http://c.learncodethehardway.org/book/ex19.html

他创建了四个源文件 - object.h、object.c、ex19.h、ex19.c。
但我不明白如何包含object.c文件。
主函数位于ex19.c中,它有一行代码。
#include "ex19.h"

文件 ex19.h 中有这行

#include "object.h"

但是 object.h 没有包含 object.c。有趣的是,object.c 包含以下行:

#include "object.h"

是否有一种隐含的包含方式,即如果包含头文件,则会自动包含同名的C源代码?

3个回答

6
这是由一个名为“链接器”的单独程序完成的工作。在C语言中,源文件需要访问其他C源文件的头文件,以便查看有关第二个C文件定义的函数、类型和变量的信息,这些信息可能是第一个文件想要使用的。然后编译每个C文件时都是相互独立的。编译器的输出是一个“目标文件”。 要构建最终程序,第二个名为“链接器”的程序将所有目标文件组合成总体可执行文件。该程序的任务是将所有不同C文件的实现进行交叉引用,以便每当一个C文件引用不同C文件中的函数或变量时,该引用实际上可以指向相应的对象。
这就是为什么您不需要包含“.c”文件的原因。一旦一个源文件有了头文件,它就足够了解其他文件以便于编译器验证其是否正确地使用了提供的函数。然后,链接器处理实际进行交叉引用的工作。您可以将编译器视为检查“如果”函数被定义,则程序将正常运行的程序。然后链接器实际上检查确保首先定义这些函数并在可执行文件中设置适当的链接。
希望这能帮到您!

太好了,那很有道理。链接器程序,它是C编译器的一部分吗? - mr mojo risin
通常情况下,C编译器会执行编译的所有阶段 - 预处理、编译、优化和链接。大多数编译器都有命令行开关,您可以使用它们来执行其中一个阶段,这通常很有趣,可以看到结果。 - templatetypedef

1

Object.c没有被包含。

它被编译为自己的单元,并且包含了object.h。

请查看make文件:

CFLAGS=-Wall -g

all: ex19

ex19: object.o

clean:
  rm -f ex19
ex19: object.o告诉你必须先创建object.o才能构建ex19,而这是从make文件中默认捕获的,因为object.c已经存在。
所以这个make文件告诉我们:
要构建所有内容,需要ex19;要获取ex19,需要object.o;要创建object.o,makefile会使用object.c构建。
从你参考的页面上可以看到:

make在object.o的文件中看不到任何东西,但它确实看到了一个object.c文件,并且它知道如何将一个.c文件转换成.o文件,所以它就做了。


0
整个逻辑都在makefile和智能编译器中。最终创建的二进制文件具有名为object.o的对象文件,其中理想情况下包含在object.h文件中定义的所有函数定义。链接器将在.h文件中声明的函数与在.o文件中可用的定义进行链接。

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