且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C 中的头文件和源文件如何工作?

更新时间:2021-09-27 01:58:29

将 C 源代码文件转换为可执行程序通常分两步完成:编译链接.

Converting C source code files to an executable program is normally done in two steps: compiling and linking.

首先,编译器将源代码转换为目标文件(*.o).然后,链接器将这些目标文件连同静态链接库一起创建一个可执行程序.

First, the compiler converts the source code to object files (*.o). Then, the linker takes these object files, together with statically-linked libraries and creates an executable program.

在第一步中,编译器采用一个编译单元,它通常是一个预处理过的源文件(因此,一个源文件包含它#includes) 并将其转换为目标文件.

In the first step, the compiler takes a compilation unit, which is normally a preprocessed source file (so, a source file with the contents of all the headers that it #includes) and converts that to an object file.

在每个编译单元中,所有使用的函数都必须声明,让编译器知道该函数存在以及它的参数是什么.在您的示例中,函数 returnSeven 的声明位于头文件 header.h 中.当你编译 main.c 时,你在声明中包含头文件,以便编译器在编译 main.c 时知道 returnSeven 存在.

In each compilation unit, all the functions that are used must be declared, to let the compiler know that the function exists and what its arguments are. In your example, the declaration of the function returnSeven is in the header file header.h. When you compile main.c, you include the header with the declaration so that the compiler knows that returnSeven exists when it compiles main.c.

当链接器完成它的工作时,它需要找到每个函数的定义.每个函数必须在其中一个目标文件中准确定义一次 - 如果有多个目标文件包含同一函数的定义,链接器将因错误而停止.

When the linker does its job, it needs to find the definition of each function. Each function has to be defined exactly once in one of the object files - if there are multiple object files that contain the definition of the same function, the linker will stop with an error.

您的函数 returnSevensource.c 中定义(而 main 函数在 main.c 中定义>).

Your function returnSeven is defined in source.c (and the main function is defined in main.c).

总而言之,您有两个编译单元:source.cmain.c(以及它包含的头文件).您将它们编译为两个目标文件:source.omain.o.第一个将包含returnSeven 的定义,第二个将包含main 的定义.然后链接器会将这两者粘合到一个可执行程序中.

So, to summarize, you have two compilation units: source.c and main.c (with the header files that it includes). You compile these to two object files: source.o and main.o. The first one will contain the definition of returnSeven, the second one the definition of main. Then the linker will glue those two together in an executable program.

关于联动:

外部链接内部链接.默认情况下,函数具有外部链接,这意味着编译器使这些函数对链接器可见.如果您创建一个函数 static,它具有内部链接 - 它仅在定义它的编译单元内可见(链接器不会知道它存在).这对于在源文件内部执行某些操作并且您想对程序的其余部分隐藏的函数很有用.

There is external linkage and internal linkage. By default, functions have external linkage, which means that the compiler makes these functions visible to the linker. If you make a function static, it has internal linkage - it is only visible inside the compilation unit in which it is defined (the linker won't know that it exists). This can be useful for functions that do something internally in a source file and that you want to hide from the rest of the program.