C语言:编译与链接

本篇博客给大家带来的是代码从运行到生成可执行文件的流程和原理

🐟🐟文章专栏:C语言

🚀🚀若有问题评论区下讨论,我会及时回答

❤❤欢迎大家点赞、收藏、分享

你们的支持就是我创造的动力

今日思想:不能因为遇到了坏的事情,就总是悲观看人!!


Ⅰ、翻译环境和运行环境

在ANSIC的任何一种实现中,有两种不同的环境,他们有各自的作用

翻译环境:把源代码转换成可执行的二进制指令

运行环境:用于实际执行代码

Ⅱ、翻译环境=预编译+编译+汇编+链接

1、翻译环境

笼统的讲翻译环境是由编译和链接组成,但是编译又分成预处理(预编译)、编译、汇编三个过程。
编译: 通过cl.exe编译器把.c文件转换成.obj文件

注意:在Windows环境下生成的是.obj文件,在Linux环境下生成.o文件

链接:把多个obj文件加上链接库经过链接器(link.exe)生成可执行文件

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

2、预处理

预处理阶段:处理#开头的源文件

具体如下:

1.将所有的 #define 删除,并展开所有的宏定义。

2.处理所有的条件编译指令,如: #if、#ifdef、#elif、#else、#endif 。

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

4. 删除所有的注释

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

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

3、编译

编译:将预处理生成的文件 进行一系列的词法分析、语法分析、语义分析及优化,然后生成相应的汇编文件

假设有下面的代码:

cpp 复制代码
array[index] = (index+4)*(2+6);

3、1词法分析

语义分析:将源代码程序被输入扫描器,扫描器的任务就是简单的进行词法分析,把代码中的字符分割成⼀系列的记号(关键字、标识符、字⾯量、特殊字符等)。

将上面的代码进行词法分析可得16个记号:

3、2语法分析

语法分析:通过语法分析器将对扫描产生的记号进行语法分析,从而产⽣语法树。这些语法树是以表达式为节点的树。

语法树:

3、3语义分析

语义分析:由语义分析器来完成语义分析,即对表达式的语法层面分析。编译器所能做的分析是语义的静态分析。静态语义分析通常包括声明和类型的匹配,类型的转换等。这个阶段会报告错误的语法信息。

4、 汇编

汇编:通过汇编器将汇编代码转变成机器可执⾏的指令(2进制的指令),每⼀个汇编语句几乎都对应⼀条机器指令。就是根据汇编指令和机器指令的对照表⼀的进行翻译,也不做指令优化**。**

5、链接

链接:把多个文件链接在一起生成可执行文件

过程:地址和空间分配、符号决议和重定位等步骤

目的:解决一个项目中多文件、多模块之间互相调用的问题

代码实例:

test.c文件代码

cpp 复制代码
#include<stdio.h>
extern int Add(int, int);
extern int g_val;
int main()
{
	int a = 10;
	int b = 20;
	int sum = Add(a, b);
	printf("%d\n", sum);
	return 0;
}

add.c文件代码

cpp 复制代码
int g_val = 2024;
int Add(int x,int y)
{
	return x + y;
}

在链接阶段他们会合并各自的符号表:

合并为:

tste.c文件运行时会通过这个符号表来查找外部变量

Ⅲ、运行环境

1. 程序必须载入内存中。在有操作系统的环境中:⼀般这个由操作系统完成。在独立的环境中,程序 的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。

2. 程序的执行便开始。接着便调用main函数。

3. 开始执行程序代码。这个时候程序将使⽤⼀个运行时堆栈(stack),存储函数的局部变量和返回 地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程 ⼀直保留他们的值。

4. 终止程序。正常终止main函数;也有可能是意外终止。

完!!

相关推荐
asdzx672 分钟前
告别手动校对:使用 Python 对比两个 PDF 文档的差异
开发语言·python·pdf
Rust研习社3 分钟前
Rust 操作 Redis 从入门到生产级应用
开发语言·redis·后端·rust
xyq202412 分钟前
Memcached stats items 命令详解
开发语言
Evand J13 分钟前
【MATLAB例程】多传感器协同DOA目标跟踪与EKF滤波,输出动态目标轨迹、轨迹误差对比分析
开发语言·matlab·目标跟踪·滤波·定位·导航
csbysj202013 分钟前
《jEasyUI 自定义分页》
开发语言
初心未改HD15 分钟前
Go语言Context深度解析与工程实践
开发语言·golang
SilentSamsara19 分钟前
Python 内存管理:引用计数、循环垃圾回收与内存泄漏排查
开发语言·vscode·python·青少年编程·pycharm
Rabitebla1 小时前
【C++】string 类:原理、踩坑与对象语义
linux·c语言·数据结构·c++·算法·github·学习方法
傻啦嘿哟2 小时前
如何在 Python 中使用 colorama 库来给输出添加颜色
开发语言·python
geovindu3 小时前
go: Visitor Pattern
开发语言·设计模式·golang·访问者模式