我仔细阅读了可能的复本,但没有一个答案能让我理解.

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

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

鉴于这些文件:

header.h:

int returnSeven(void);

source.c:

int returnSeven(void){
    return 7;
}

main.c:

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

这乱七八糟的事情会发生吗?我目前在NetBeans 7.0年和Cygwin的gcc年一起完成我的工作,Cygwin自动化了大部分构建任务.当一个项目被编译时,所涉及的项目文件会根据header.h中的声明来整理这source.c个隐含的包含吗?

推荐答案

将C源代码文件转换为可执行程序通常分为两个步骤:compilinglinking.

首先,编译器将源代码转换为目标文件(*.o).然后,链接器获取这些对象文件以及静态链接的库,并创建一个可执行程序.

在第一步中,编译器获取一个compilation unit,它通常是一个预处理的源文件(因此,它是一个源文件,包含它所包含的所有头的内容),并将其转换为一个目标文件.

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

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

函数returnSevensource.c中定义(函数mainmain.c中定义).

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

关于链接:

external linkage号和internal linkage号.默认情况下,函数具有外部链接,这意味着编译器使这些函数对链接器可见.如果您创建一个函数static,则它有内部链接-它只在定义它的编译单元中可见(链接器不知道它存在).对于在源文件内部执行某些操作的函数,以及您希望对程序的睡觉隐藏的函数,这可能很有用.

C++相关问答推荐

try 使用libusb控制音量时LIBUSB_WRIGHT_PIPE

漏洞仅出现在FreeBSD上,但在Windows、Linux和MacOS上运行得非常好

从C函数调用asm函数时生成错误的BLX指令(STM32H753上的gcc)

Mise()在虚拟内存中做什么?

在32位处理器上优化53—32位模计算>

当main函数调用被重构时,C函数给出错误的结果

如何设置指针指向在函数中初始化的复合文字中的整数?

编译的时候g++通常会比GCC慢很多吗?

有没有可能我不能打印?(C,流程)

C由四个8位整数组成无符号32位整数

可以将C变量限制为特定的读/写速度吗?

调用mProtection将堆栈上的内存设置为只读,直接导致程序SIGSEGV

S的这种管道实施有什么问题吗?

不同原型的危险C函数是可能的

C11/C17标准允许编译器清除复合文字内存吗?

当我用scanf(&Q;%S%S%S&Q;,单词0,单词1,单词2)输入多个单词时,除了最后一个单词外,每个单词的第一个字符都丢失了

如何在zOS上编译共享C库

如果类型是新的,offsetof是否与typeof一起工作?

从系统派生线程调用CRT

保存有符号整数结果的变量是否会溢出(后增量的副作用),并且此后从未在任何表达式中使用过它,是否会导致 UB?