c语言 编译与链接

编译与链接

  • 翻译环境和执行环境
    • 翻译环境
      • 1.1预编译
      • 1.2编译
      • 1.3汇编(ASM)
      • 2.链接
  • 执行环境
    • 最后给大家附上一张关于本节知识内容的图供大家更好理解~ ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/522d488885ba44d99aa504d6b21c88d5.png)

在这里插入图片描述
😀欢迎来到小庄代码世界~
😁 喜欢的小伙伴记得一键三连哦 ૮(˶ᵔ ᵕ ᵔ˶)ა


引言:我们平常写代码是否思考过在我们按下运行时c程序会发生些什么过程呢?
事实上存在翻译和执行环境,这篇文章让博主来分享分享,请放心食用!

翻译环境和执行环境

在ANSIC的任何⼀种实现中,存在两个不同的环境
1.翻译环境 我们知道计算机看懂的是二进制这个环境就是用来将我们的源代码翻译成可执行的二进制指令
2.执行环境 该环境用于实际执行代码
具体如下图

在这里插入图片描述
接下来让博主对翻译环境进行详细讲解´༥`

翻译环境

翻译环境是如何将源代码转换成二进制指令呢?其实翻译环境由编译和链接两大板块组成;而编译又细分为预处理(预编译),编译,汇编三个阶段૮(˶ᵔ ᵕ ᵔ˶)ა

一个项目由多个源文件构成,这些源文件经过编译阶段和编译器(cl.exe)处理生成对应的目标文件,接着对应的目标文件在链接阶段经过连接器(link.exe)生成对应的可执行程序xx.exe文件,这就是大致的翻译环境的流程。

在这里插入图片描述

1.windows系统目标文件的后缀为.obj,而linux下为.o
2.链接库:链接库指的是将库文件编译后打包为一个二进制文件,这些文件在调用的时候会加载到内存中。实际上一个或多个源文件转换为目标文件后,这个文件所引用的外部符号需要通过链接来找缺失的地址,这里我们做个小铺垫~ 我们可以将它理解为我们要借用的大哥的力量,比如标准库函数等。

接下来我们先来了解翻译环境所拆分的三个阶段(以linux环境gcc编译器为例)
在这里插入图片描述
注:对于.i和.s的中间文件他们是临时的用完会删除

1.1预编译

在预处理阶段,源⽂件和头⽂件会被处理成为.i为后缀的⽂件。
在 gcc 环境下想观察⼀下,对 test.c ⽂件预处理后的.i⽂件,命令如下:

gcc -E test.c -o test.i

预编译阶段主要是对预处理指令进行处理,#开头的都是预处理指令他们都是在这个阶段处理的比如#include #define,该阶段特点是替换,将预处理指令替换成它实际指向的内容!

让我们来了解下他的替换规则

1.头文件的包含:处理#include预编译指令,将包含的头⽂件的内容插⼊到该预编译指令的位置。这个过程是递归进⾏的,也就是说被包含的头⽂件也可能包含其他⽂件。
2.#define:它会将所有#define删除并展开它的定义。
3.注释:所有注释都会被替换成空格
4.处理所有的条件编译指令,如: #if、#ifdef、#elif、#else、#endif
5.或保留所有的#pragma的编译器指令,编译器后续会使⽤。

预编译
经过预处理后的.i⽂件中不再包含宏定义,因为宏已经被展开。并且包含的头⽂件都被插⼊到.i⽂件
中。所以当我们⽆法知道宏定义或者头⽂件是否包含正确的时候,可以查看预处理后的.i⽂件来确认

最后我们总结一下:预处理主要特点就是将预处理指令指向的实际内容进行替换⌯’▾’⌯

1.2编译

在编译这个阶段主要进行的是符号汇总(先来个铺垫)和将预处理后的⽂件进⾏⼀系列的:词法分析、语法分析、语义分析及优化,⽣成相应的汇编代码⽂件

编译过程的命令如下:

gcc -S test.i -o test.s

🏠 词法分析
词法分析完成的工作主要是识别记号,将源代码程序被输⼊扫描器,扫描器的任务就是简单的进⾏词法分析,把代码中的字符分割成⼀系列的记号(关键字、标识符、字⾯量、特殊字符等)

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

上面的代码经过扫描后得到如下16个记号:
在这里插入图片描述
🏠 语法分析
识别出记号后接下来语法分析器,将对扫描产⽣的记号进⾏语法分析,从⽽产⽣语法树。这些语法树是以表达式为节点的树
在这里插入图片描述
🏠 语义分析
由语义分析器来完成语义分析,即对表达式的语法层⾯分析。编译器所能做的分析是语义的静态分
析。静态语义分析通常包括声明和类型的匹配,类型的转换等。这个阶段会报告错误的语法信息

联系我们之前的知识,我们有链接错误,运行错误,编译错误。编译错误大多是语法错误就是从这而来,由编译阶段来检查

经过3个阶段后所生成就是我们的汇编指令,生成.s后缀文件
在这里插入图片描述
总结:在编译阶段完成工作是将c语言源代码转换成汇编指令,通过词法分析,语法分析,语义分析更好地理解代码。

1.3汇编(ASM)

汇编器是将汇编代码转转变成机器可执⾏的指令,每⼀个汇编语句⼏乎都对应⼀条机器指令。就是根
据汇编指令和机器指令的对照表⼀⼀的进⾏翻译,也不做指令优化。

总结:汇编阶段的工作是将汇编代码翻译成二进制指令,生成对应的目标文件

2.链接

链接是一个比较复杂的过程,链接的时候需要把⼀堆⽂件链接在⼀起才⽣成可执⾏程序。链接过程主要包括:地址和空间分配,符号决议和重定位*等这些步骤。链接解决的是⼀个项⽬中多⽂件、多模块之间互相调⽤的问题

你是否一脸雾水( ͡° ʖ̯ ͡°),让博主来给你细细道来

🏠 符号汇总
你是否记得我们在讲编译时有讲到符号汇总这个工作?
所谓符号就是程序中的变量名、函数名,在编译阶段我们会把出现的符号给汇总到一起

🏠 形成符号表
什么是符号表?

符号表是一种供编译器用于保存有关源程序构造的各种信息的数据结构。通俗讲就是存放我们符号属性信息(比如它的存储位置,类型和其他相关信息等)符号表通常需要支持同一符号在一个程序的多重声明。

🏠 符号决议和重定位
我们先上图说话
在这里插入图片描述
这个过程就是符号决议了,概括起来就是只要每个目标文件所引用符号都能在其目标文件中找到唯一定义整个链接过程就是正确的

通过了符号决议后就是进行重定位了修改唯一正确的属性信息

在这里插入图片描述

执行环境

前面的翻译官帮我们翻译完后,计算机就能看懂一系统二进制指令了便可以开始执行程序了

  1. 程序必须载⼊内存中。在有操作系统的环境中:⼀般这个由操作系统完成。在独⽴的环境中,程序
    的载⼊必须由⼿⼯安排,也可能是通过可执⾏代码置⼊只读内存来完成。
  2. 程序的执⾏便开始。接着便调⽤main函数
  3. 开始执⾏程序代码。这个时候程序将使⽤⼀个运⾏时堆栈(stack),存储函数的局部变量和返回
    地址。程序同时也可以使⽤静态(static)内存,存储于静态内存中的变量在程序的整个执⾏过程
    ⼀直保留他们的值.
    4.终⽌程序。正常终⽌main函数;也有可能是意外终⽌。

最后给大家附上一张关于本节知识内容的图供大家更好理解~
在这里插入图片描述

本次知识分享官就体验结束啦〃•ω‹〃,小伙伴们喜欢的话支持小庄给俺点个关注点个收藏来个评论,你们的支持是我更新的强大动力!!

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

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

相关文章

【FastAPI】路径参数(二)

预设值 如果你有一个接收路径参数的路径操作,但你希望预先设定可能的有效参数值,则可以使用标准的 Python Enum 类型。 导入 Enum 并创建一个继承自 str 和 Enum 的子类。通过从 str 继承,API 文档将能够知道这些值必须为 string 类型并且能…

交友系统程序开发,前后端源码交付,允许二开,UI配色新颖,APP小程序H5随心搭配!

在开发设计与测试阶段,主要包括了程序开发、测试和上线运营等环节。根据产品经理确定的功能需求,开发团队开始进行具体的编程和开发工作。这个过程中需要考虑到不同设备、不同系统和不同版本的需求,确保软件可以在不同平台上稳定运行。 测试是…

WiNGPT2突破:国产140亿参数医疗AI模型

模型介绍 WiNGPT2是基于GPT架构开发的医疗垂直领域大模型,其主要目标是将医学知识、医疗信息和数据进行深度融合,以提供智能化的医疗服务。该模型拥有70亿和140亿两种参数规模的版本,使其能够处理更复杂的医疗场景和需求。 Huggingface模型下…

【Docker】Docker基础教程

🦖我是Sam9029,一个前端 🐱‍🐉🐱‍🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,求收藏,求评论,求一个大大的赞!👍 基…

嵌入式学习-网络编程-Day4

思维导图 广播通信模型 #include <myhead.h> int main(int argc, char const *argv[]) {int rfd socket(AF_INET,SOCK_DGRAM,0);if(rfd-1){perror("socket error");return -1;}//填充地址信息结构体struct sockaddr_in rin;rin.sin_familyAF_INET;rin.sin_por…

2024年甘肃省职业院校技能大赛信息安全管理与评估 样题一 模块二

竞赛需要完成三个阶段的任务&#xff0c;分别完成三个模块&#xff0c;总分共计 1000分。三个模块内容和分值分别是&#xff1a; 1.第一阶段&#xff1a;模块一 网络平台搭建与设备安全防护&#xff08;180 分钟&#xff0c;300 分&#xff09;。 2.第二阶段&#xff1a;模块二…

安泰功率信号源设计方法有哪些

在电子系统中&#xff0c;功率信号源是一个关键的组成部分&#xff0c;用于提供稳定、可靠的电能。这篇文章将详细介绍功率信号源的设计方法&#xff0c;包括选择功率源类型、设计电源拓扑结构、提高效率和管理电磁干扰等方面。 1.功率源类型的选择 选择适当的功率源类型是功率…

MSSQL-识别扩展extended event(扩展事件)中的时间单位

经常使用sqlserver extended event(扩展事件)&#xff0c;但是总是忘记扩展事件使用的时间单位&#xff0c;不确定它们是 秒、毫秒、还是微秒&#xff1f; 以下下代码能够从 相关DMV中提取description字段内容来识别时间单位&#xff1a; SELECT [p].[name] [package_name],[o…

07. 面向对象编程(一)

目录 1、前言 2、类和对象 2.1、定义类 2.2、定义方法 2.3、创建对象 2.4、访问控制 2.4.1、公共变量 2.4.2、私有变量 2.4.3、保护成员 2.4.4、总结 3、封装 4、继承 5、多态 6、小结 1、前言 在Python中&#xff0c;面向对象编程&#xff08;Object-Oriented …

vuex的初步使用-1

1. 介绍 Vuex 是一个 Vue 的 状态管理工具&#xff0c;状态就是数据。 简单讲&#xff1a;Vuex 就是一个插件&#xff0c;可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。相对于一个仓库&#xff1a;存放组件共享的数据。 2. 安装 vuex 安装vuex与vue-router类似&…

基于Mapbox的Mvt矢量瓦片集成实践

目录 前言 一、数据说明 1、基本数据 2、属性数据 二、Mapbox集成Mvt矢量瓦片 1、关于访问令牌 2、定义html 3、初始地图 4、加载矢量瓦片 5、效果展示 总结 前言 熟悉矢量瓦片的朋友一定知道&#xff0c;在Webgis当中&#xff0c;矢量瓦片的格式除了pbf的格式&#x…

docker:环境安装

系列文章目录 docker&#xff1a;环境安装 文章目录 系列文章目录前言一、Debian安装1.镜像下载2.VM安装3.Debian安装 二、docker安装1.Debian12换源2.docker安装3.docker测试4.docker换源 总结 前言 因为CentOS7确定停服时间为6月30日&#xff0c;虽然对我这种小虾米没啥影响…

dubbox框架

1、dubbox介绍 Dubbo(读音[ˈdʌbəʊ])是阿里巴巴公司开源的一个基于Java的高性能RPC&#xff08;Remote Procedure Call&#xff09;框架&#xff0c;使得应用可通过高性能的 RPC 实现服务的输出和输入功能&#xff0c;可以和 Spring框架无缝集成。后期阿里巴巴停止了该项目…

HashMap集合万字源码详解(面试常考)

文章目录 HashMap集合1.散列2.hashMap结构3.继承关系4.成员变量5.构造方法6.成员方法6.1增加方法6.2将链表转换为红黑树的treeifyBin方法6.3扩容方法_resize6.3.1扩容机制6.3.2源码resize方法的解读 6.4 删除方法(remove)6.5查找元素方法(get)6.6遍历HashMap集合几种方式 7.初始…

vue安装组件报错In most cases you are behind a proxy or have bad network settings.

解决办法 步骤1 npm config get proxy npm config get https-proxy 如果2个返回值不为null&#xff0c;请执行下面代码&#xff0c;重置为null。否则&#xff0c;直接执行步骤2。 npm config set proxy null npm config set https-proxy null 步骤2 npm config set regis…

cv 不能正常读取中文路径

之前一直以为是PyQT的getOpenFileNames方法不能读取中文路径的。多次尝试后发现不是&#xff0c;是OpenCV的问题。 self.selected_imgPaths, _ QtWidgets.QFileDialog.getOpenFileNames(self, "打开图片", "./pending_images", "*.jpg;;*.JPG;;*.png…

【Windows取证篇】Window日志分析基础知识(一)

【Windows取证篇】Window日志分析基础知识&#xff08;一&#xff09; Windows系统审计是对系统中有关安全的活动进行记录、检查以及审核&#xff0c;一般是一个独立的过程。Window自带的事件查看器并没有提供删除特定日志的功能&#xff0c;我们在系统审计取证分析时&#xf…

基于Java+SSM志愿者服务管理系统详细设计和实现【附源码】

基于JavaSSM志愿者服务管理系统详细设计和实现【附源码】 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系…

九、Qt C++ 数据库开发

《一、QT的前世今生》 《二、QT下载、安装及问题解决(windows系统)》《三、Qt Creator使用》 ​​​ 《四、Qt 的第一个demo-CSDN博客》 《五、带登录窗体的demo》 《六、新建窗体时&#xff0c;几种窗体的区别》 《七、Qt 信号和槽》 《八、Qt C 毕业设计》 《九、Qt …

Vue-23、Vue收集表单数据

1、效果 2、代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>收集表单数据</title><script type"text/javascript" src"https://cdn.jsdelivr.net/npm/vue2/dist/vue.js…