初识C语言·编译与链接

1 翻译环境和运行环境

C语言标准ANSI C 实现C语言代码的时候 一般需要经过两种环境,一是翻译环境,二是运行环境,计算机能识别的是二进制的指令,人写完代码后通过翻译环境,使代码变成计算机能读懂的可执行的机器指令,运行环境就是用来执行实际的代码操作的环境。

1)翻译环境

那么翻译环境如何让源代码变成可执行的机器指令的呢?

翻译环境包含的是编译链接两大过程,其中编译包含预处理(也可以叫做预编译),编译,汇编

编译的时候,机器通过编译器使.c文件生成.obj文件,.obj文件是目标文件(在windows是.obj为后缀,Linux环境下是.o为后缀),多个目标文件在经过链接库的处理,最后生成 .exe文件

VS2022用到的编译器是cl.exe:

用到的链接器是link.exe:

编译的整个过程如下:(Linux下的gcc编译器为例)
.c文件 .h文件 源文件 经过预处理 生成.i为后缀的文件  ->  经过编译生成.s为后缀的文件 -> 经过汇编生成.o为后缀的文件 -> 经过链接器和链接库生成最后的可执行文件.exe

预处理:

在gcc环境下,我们使用指令:

gcc -E test.c -o test.i

使机器生成.i为后缀的文件的时候,我们就会发现代码出现了一下改变,这里因为在预处理阶段,存在以下规则:
1 删除所有的#define,所有宏定义被展开

2 处理所有的条件编译指令,如#endif #if #else

3 处理#include预编译指令,将头文件里面包含的内容插入到头文件所在的位置,这个过程是递归进行的,不排除头文件里面包含其他头文件的可能性

4 所有的注释都会被删除

5 或保留#pragma指令,编译器后续会使用,为了防止头文件重复包含

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

当我们不知道宏定义是否包含正确的时候就可以经预处理之后的.i文件进行确认。

编译:

在gcc环境下,我们使用指令:

gcc -S test.i -o test.s

使机器生成了.s为后缀的文件,在这个阶段,编译器会进行三个操作,词法分析语法分析语义分析及优化

array[index] = (index+4)*(2+6);

假定以上代码

词法分析:

词法分析就是把代码中的字符分隔开,分割成一系列的记号,如关键字,标识符,特殊字符,字面常量,如下:

语法分析

通过词法分析产生的记号,语法分析器通过记号生成语法树,以表达式为结点的树,如下:

语义分析
语义分析器会从表达式的层面分析,能做的分析使语义的静态分析,静态语义分析包括通常包括声明和类型的匹配,类型的转化等,这个阶段会显示错误的语法信息。

汇编:

汇编的指令如下:

gcc -c test.s -o test.o

汇编器将汇编代码变成机器可以执行的指令,每一个汇编语句几乎都对应一个机器指令,而汇编语言较难的一个原因就是不同的机器的汇编语言是不一样的,不具有跨平台性。

链接:

链接是一个复杂的过程,需要将一堆文件链接在一起才能生成可执行程序。

链接包括分配地址,分配空间,符号决议,重定位,等步骤。

链接解决的是一个项目中多文件多模块互相调用的问题,比如一个C语言的项目中有两个.c文件(test.c add.c)

extern int Add(int, int);//声明外部函数
extern int g_val;//声明外部全局变量
int main()
{int a = 10, b = 20;int sum = Add(a, b);printf("%d ", sum);printf("g_val = %d ", g_val);return 0;
}
int g_val  = 2024;
int Add(int x,int y)
{return x + y;
}

test.c 经过编译器处理生成了test.o文件,Add.c经过编译器处理生成了Add.o文件,通过关键字extern我们在test.c文件里面使用了函数Add 和 全局变量g_val,但是每一次使用这两个外部符号的时候必须确切的知道Add g_val的地址,因为编译器是单独编译的,所以编译器编译test.c文件的时候并不知道函数Add g_val的存在,所以暂时调用Add的指令的目标地址和g_val的地址搁置,等最后链接的时候根据引用的符号Add在其他模块寻找Add函数的地址,最后修正test.c文件里面引用到的Add的地方,使目标地址成为真正的函数Add的地址,对于全局变量亦是如此,这个修正的过程叫做重定义

2)运行环境:

运行环境就没什么好介绍的了:
程序运行的时候必须载入到内存里面,在有操作系统的环境下,一般都是由操作系统完成,独立的环境下,程序的载入必须通过手工安排。因为程序运行的时候操作系统会为程序开辟函数栈帧,调用堆栈,所以载入内存是必须的。

最后就是终止程序了,可能是main函数顺利读取到了最后一行,也可能是意外终止,比如按下F11的时候调试到一般关闭程序,这时候程序就会显示返回值是-1,也就是意外终止了。


感谢阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/452868.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go-redis hash slot 之旅

搭建redis 集群 创建一个网桥 docker network create -d bridge --subnet192.168.148.0/24 --gateway192.168.148.1 -o parenteno1 redis-net通过docker 文件创建redis 集群, 这里注意要不要使用redis 7以上的版本,不然会出问题 version: "3&quo…

ArcGIS学习(三)数据可视化

ArcGIS学习(三)数据可视化 1.矢量数据可视化 需要提前说明的是,在ArcGIS中,所有的可视化选项设置都是在“图层属性”对话框里面的“符号系统”中实现的。 对于矢量数据的可视化,主要有四种可视化方式: 按“要素”可视化按“类别”可视化按“数量”可视化按“图表”可视…

最近宣布的NIST后量子密码学标准的3个关键要点

当今世界依赖于许多保护措施,即使您没有注意到这一点。从手机和智能技术到网站,从支付交易到城市基础设施,人们经常与之互动的一切,都通过保护和检查技术来保护。量子计算机能够快速轻松地打破这些保护措施,这是政府和…

django+flask网上购物商城系统的设计与实现python-vue

全球经济在快速的发展,中国更是进步飞速,这使得国内的互联网技术进入了发展的高峰时期,这让中外资本不断转向互联网这个大市场[3]。在这个信息高度发达的现在,利用网络进行信息管理改革已经成为了人们追捧的一种趋势。“网上购物系…

01-Datahub是什么?

Datahub是LinkedIn开源的基于现代数据栈的元数据管理平台,原来叫做WhereHows 。经过一段时间的发展datahub于2020年2月在Github开源。 官网地址为:A Metadata Platform for the Modern Data Stack | DataHub 源码地址为:GitHub - datahub-p…

stable-diffusion | v1-5-pruned.ckpt和v1-5-pruned-emaonly.ckpt的区别

https://github.com/runwayml/stable-diffusion?tabreadme-ov-file#reference-sampling-script 对于 1.5 模型,其中可能包括四部分:标准模型、文本编码器、VAE模型、EMA模型。 标准模型:生成图片的核心模块,潜空间中的前向扩散和…

STM32F407移植OpenHarmony笔记9

继上一篇笔记,已经完成liteos内核的基本功能适配。 今天尝试启动OHOS和XTS兼容性测试。 如何启动OHOS? OHOS系统初始化接口是OHOS_SystemInit(void),在内核初始化完成后,就能调用。 extern void OHOS_SystemInit(void); OHOS_Sys…

sqli-labs-master靶场训练笔记(21-38|精英级)

2024.1.30 level-21 (cookie 注入数据加密) 从页面上就可以看出这次的数据被 baes64 加密了 中国有句古话:师夷长技以制夷 ,用base64加密后的数据即可爆出数据 加密前: admin and updatexml(1,concat(~,(select database()),~),1) and …

javaEE - 21( 15000字 Tomcat 和 HTTP 协议入门 -2)

一: HTTP 响应 1.1 认识 “状态码” (status code) 状态码表示访问一个页面的结果. (是访问成功, 还是失败, 还是其他的一些情况…),以下为常见的状态码. 1.1.1 200 OK 这是一个最常见的状态码, 表示访问成功. 抓包抓到的大部分结果都是 200 HTTP/…

Ps:文档窗口状态栏

状态栏 Status Bar位于每个文档窗口的底部,可显示诸如视图的缩放比例及文件相关的有用信息。 ◆ ◆ ◆ 缩放比例 显示当前视图的放大比例,例如 100% 表示实际大小。 有关视图的缩放,请参阅: 《Ps:缩放工具》 可以直接…

备战蓝桥杯---搜索(优化1)

显然&#xff0c;我们可以用BFS解决&#xff0c;具体实现与八数码类似&#xff1a; 下面是代码&#xff1a; #include<bits/stdc.h> using namespace std; #define N 3000000 string a,b; int hh,dis[N],cnt; struct node{string u,v; }bian[7]; map<string,int>…

ERP 系统架构的设计与实践总结

企业资源计划&#xff08;ERP&#xff09;系统是一种集成多个业务功能的综合性软件解决方案。在设计和实践 ERP 系统架构时&#xff0c;需要考虑诸多因素&#xff0c;以确保系统能够满足企业的需求&#xff0c;并提供高效、可靠、安全的服务。本文将介绍一些关键的设计原则和实…