C 中的头文件和源文件如何工作? [英] How do header and source files in C work?

查看:46
本文介绍了C 中的头文件和源文件如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经仔细阅读了可能的重复项,但是没有一个答案会被理解.

I've perused the possible duplicates, however none of the answers there are sinking in.

tl;dr:C 中的源文件和头文件有何关联?项目是否在构建时隐式地整理声明/定义依赖项?

tl;dr: How are source and header files related in C? Do projects sort out declaration/definition dependencies implicitly at build time?

我试图理解编译器如何理解.c.h 文件之间的关系.

I'm trying to understand how the compiler understands the relationship between .c and .h files.

给定这些文件:

header.h:

int returnSeven(void);

source.c:

int returnSeven(void){
    return 7;
}

ma​​in.c:

#include <stdio.h>
#include <stdlib.h>
#include "header.h"
int main(void){
    printf("%d", returnSeven());
    return 0;
}

这个烂摊子会编译吗?我目前正在使用 Cygwin 的 gccNetBeans 7.0 中完成我的工作,它可以自动化大部分构建任务.当一个项目被编译时,所涉及的项目文件是否会根据 header.h 中的声明对 source.c 的这种隐含包含进行梳理?

Will this mess compile? I'm currently doing my work in NetBeans 7.0 with gcc from Cygwin which automates much of the build task. When a project is compiled will the project files involved sort out this implicit inclusion of source.c based on the declarations in header.h?

推荐答案

将 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.

这篇关于C 中的头文件和源文件如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆