【C语言】编译和链接

s_little_monster_ 2024-07-05 16:35:04 阅读 73

在这里插入图片描述

个人主页点这里~

本文篇幅较短,但内容在理解c语言内部逻辑方面却十分重要,希望大家能够认真的阅读


编译和链接

一、翻译环境和运行环境二、翻译环境1、预处理2、编译①词法分析②语法分析③语义分析

3、汇编4、链接

三、运行环境

一、翻译环境和运行环境

在c语言的实现中,存在两个环境

翻译环境:在这个环境中源代码被转换成可执行的二进制指令

运行环境:实际执行代码

二、翻译环境

翻译由编译和链接两个过程组成

编译又可以分为预处理、编译、汇编三个过程

一个c语言的项目一般是由多个.c文件一起构建的,多个.c文件通过如下步骤生成可执行程序:

①多个.c文件单独经过编译器,编译处理生成对应的目标文件

②多个目标文件和链接库一起经过链接器处理生成最终的可执行程序

③链接库是指运行时库(支持程序运行的基本函数集合)或者第三方库

注意:在Windows环境下目标文件的后缀是.obj,Linux环境下的目标文件的后缀是.o

以下就是编译与链接的过程:

在这里插入图片描述

1、预处理

在预处理阶段,源文件和头文件都会被处理成为.i为后缀的文件

预处理阶段主要处理源文件中#开始的预编译指令,规则如下:

①将所有的#define删除,并展开所有的宏定义

②处理所有的条件编译指令

③处理 #include 预编译指令,将包含的头文件的内容插入到该预编译指令的位置。这个过程是递归进行的,因为包含的头文件可能包含其他文件

④删除所有的注释

⑤添加行号和文件名标识,方便后续编译器生成调试信息

⑥保留所有的 #pragma 的编译器指令,后续编译器会使用

经过预处理后的.i文件中不再包含宏定义,所有的宏定义已经被展开了,我们可以通过查看预处理后的.i文件来确认宏定义和头文件是否包含正确

2、编译

编译的过程就是将预处理后的文件进行语法词法的分析和优化,生成汇编代码

①词法分析

源代码程序会被输入扫描器,在扫描器中被简单词法分析,把代码中的字符分割开

arr[input] = (input+2)*(5-2);

这个代码是一个数组赋值代码,我们进行词法分析的时候会将它们全部拆开:

记号 类型
arr 标识符
[ 左方括号
input 标识符
] 右标识符
= 赋值
( 左圆括号
input 标识符
+ 加号
2 数字
) 右圆括号
* 乘号
( 左圆括号
5 数字
- 减号
2 数字
) 右圆括号

②语法分析

然后进入语法分析器,将分割开的字符记号进行语法分析,产生语法树(以表达式为结点的树)

在这里插入图片描述

③语义分析

然后进入语义分析器进行语义分析,也就是对表达式进行语法层面的分析,这个分析是静态分析,编译器能且只能做到静态分析,它通常包括声明和类型的匹配,类型的转换等,这个阶段会报告错误的语法信息

在这里插入图片描述

3、汇编

然后接下来一步是进入汇编器,将汇编指令转换为机器可执行的指令,根据汇编指令和机器指令的对照表一一翻译,不做指令优化

4、链接

然后就是链接,链接就是把一堆文件链接在一起生成可执行程序,它的过程主要包括:地址和空间的分配、符号决议、重定位等

重定位:当我们使用多个.c文件生成一个可执行程序的时候,由于编译的时候是每个文件单独编译的,当我们在一个文件中使用另一个文件定义的函数时,我们是需要明确地址的,这时我们会将地址暂时搁置,等到链接的时候再将地址修正,让它们的地址真正成为这个函数的地址,这个地址修正的过程,就叫做重定位

三、运行环境

1、程序必须载入内存当中:程序必须载入内存当中,在有操作系统的环境中,一般由这个操作系统来完成,在独立的环境中,需要手动操作,也可能是通过可执行代码置入只读内存完成

2、程序执行:程序执行便开始调用main函数

3、开始执行程序代码:开始执行程序代码时程序将使用一个运行时堆栈,存储函数的局部变量和返回地址,程序同时也可以使用静态内存,存储于静态内存中的变量在程序的整个执行过程一直保留它们的值

4、终止程序:正常终止main函数或意外终止


今日分享就到这里了~

在这里插入图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。