当前位置:   article > 正文

【C语言】编译和链接

【C语言】编译和链接

在这里插入图片描述

个人主页点这里~

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


一、翻译环境和运行环境

在c语言的实现中,存在两个环境
翻译环境:在这个环境中源代码被转换成可执行的二进制指令
运行环境:实际执行代码

二、翻译环境

翻译由编译和链接两个过程组成
编译又可以分为预处理、编译、汇编三个过程
一个c语言的项目一般是由多个.c文件一起构建的,多个.c文件通过如下步骤生成可执行程序:
①多个.c文件单独经过编译器,编译处理生成对应的目标文件
②多个目标文件和链接库一起经过链接器处理生成最终的可执行程序
③链接库是指运行时库(支持程序运行的基本函数集合)或者第三方库
注意:在Windows环境下目标文件的后缀是.obj,Linux环境下的目标文件的后缀是.o
以下就是编译与链接的过程:
在这里插入图片描述

1、预处理

在预处理阶段,源文件和头文件都会被处理成为.i为后缀的文件
预处理阶段主要处理源文件中#开始的预编译指令,规则如下:
①将所有的#define删除,并展开所有的宏定义
②处理所有的条件编译指令
③处理 #include 预编译指令,将包含的头文件的内容插入到该预编译指令的位置。这个过程是递归进行的,因为包含的头文件可能包含其他文件
④删除所有的注释
⑤添加行号和文件名标识,方便后续编译器生成调试信息
⑥保留所有的 #pragma 的编译器指令,后续编译器会使用
经过预处理后的.i文件中不再包含宏定义,所有的宏定义已经被展开了,我们可以通过查看预处理后的.i文件来确认宏定义和头文件是否包含正确

2、编译

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

①词法分析

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

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

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

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

②语法分析

然后进入语法分析器,将分割开的字符记号进行语法分析,产生语法树(以表达式为结点的树)
在这里插入图片描述

③语义分析

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

3、汇编

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

4、链接

然后就是链接,链接就是把一堆文件链接在一起生成可执行程序,它的过程主要包括:地址和空间的分配、符号决议、重定位等
重定位:当我们使用多个.c文件生成一个可执行程序的时候,由于编译的时候是每个文件单独编译的,当我们在一个文件中使用另一个文件定义的函数时,我们是需要明确地址的,这时我们会将地址暂时搁置,等到链接的时候再将地址修正,让它们的地址真正成为这个函数的地址,这个地址修正的过程,就叫做重定位

三、运行环境

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


今日分享就到这里了~

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/522811
推荐阅读
相关标签
  

闽ICP备14008679号