C语言程序的编译+链接详解


前言

同学们在写代码的时候,我们往往要先创建一个源文件比如test.c。写完具体代码并运行后,我们的文件夹中会生成一个test.exe的文件,也就是我们这段代码的可执行程序。那test.c到底是怎样才生成test.exe的呢?这就是我们今天的内容:程序的编译
在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、引子

在ANSIC(标准C)的任何一种实现中,存在两个不同的环境。
第一种是翻译环境,在这个环境中源代码被转换成可执行的机器指令。
第二种是指向环境,它用于实际执行代码
在这里插入图片描述

我们把test.c变成test.exe时,会经理一个翻译环境,能运行test.exe的环境,叫运行环境
在这里插入图片描述

我们常说的:编译-链接-运行就是分别在翻译环境和运行环境中发生的,比如我们现在写了一个程序要进行2+3的操作,那么这个操作经过上图步骤后就可以得到5
在这里插入图片描述
(图片来自比特就业课)
以我们以前写过的通讯录为例:我们写的源文件有test.c和contact.c那这两个源文件分别会经过编译器处理生成一个.obj目标文件。而生成的目标文件,最终会经过链接器处理,将这若干个目标文件和链接库链接,最后生成我们的可执行程序
在这里插入图片描述
ps:编译器是编译阶段的工具,链接器是链接阶段的工具,windows环境下目标文件是.obj,Linux环境下目标文件是.0

二、翻译环境

预处理
这里会进行如下操作:
1.头文件的包含,如#include<stdio.h>
2.#define定义的符号替换,如#define min 0
3.把代码中的注释删除 ps:并没有真正删除,而是编译阶段不会看到注释

编译
把C语言代码转化为汇编代码,这里会进行如下操作:
1.语法分析
2.词法分析
3.语义分析
4.符号汇总
汇编
把汇编代码转化称为二进制指令(机器指令),这里会形成符号表。
在这里插入图片描述
比如Add.c文件内有函数Add,会把Add函数名和函数所在地址放在符号表里。同理test.c文件里有函数Add和main函数,会把它们的函数名和函数所在地址放在符号表里。
链接
在经过预编译,编译和汇编相关操作后,我们会得到相关文件的目标文件,比如contact.obj和test.obj,那么我们在翻译环境的最后阶段需要做的就是把这些目标文件链接起来。这时会经历2个操作。
1.合并段表
文件在链接阶段会被分成几段进行操作,合并段表就是把相关文件对应的段连接到一起,如下图
在这里插入图片描述

2.符号表的合并和重定位
关于符号表合并,也就是将之前汇编部分产生的符号表合并,如下图
在这里插入图片描述

三、运行环境

程序执行的过程:
1.程序必须载入内存中,在有操作系统的环境中:一般由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成
2.程序的执行便开始,接着就调用main函数
3.开始执行程序代码。这个时候程序将使用一个运行时堆栈,存储函数的局部变量和返回地址。程序同时也可以使用静态内存,存储静态内存中的变量在程序的整个执行过程一直保留着他们的值
4.终止程序。正常终止main函数,但也有可能发生意外终止main函数。


总结

本文简单介绍了

Supongo que te gusta

Origin blog.csdn.net/m0_57180439/article/details/120819413
Recomendado
Clasificación