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函数;也有可能是意外终⽌。

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLaMa2 Chat gpt 大模型本地部署初体验

一直想在自己电脑或者测试环境随便找台服务器尝试部署一下“大模型”,但“大模型”对于内存和GPU的要求令人望而却步,层出不穷的各种术语也令人困惑,有点难以下手。 经过一段时间,在百度千帆大模型平台、讯飞星火大模型平台、魔搭…

【期末考试】网络综合复习宝典

相关链接 网络复习思维导图(HCIP)https://www.edrawsoft.cn/viewer/public/s/038e2370897928 详述循环冗余校验CRC码https://blog.csdn.net/liht_1634/article/details/124328005?app_version6.2.6&codeapp_1562916241&csdn_share_tail%7B%22…

【送书活动七期】CMeet系列 技术生态沙龙:技术人职业交流会·杭州场-转鸿蒙 对应用开发来说是否是职业发展新机会

CSDN致力于促进城市区域内尖端新兴技术开发者交流,提供开放自由的切磋平台。在近期热议的话题中,“华为鸿蒙系统不再兼容安卓应用”的消息成了程序员们广泛关注并引发思考的问题。 因此便有了我们此次的活动探讨议题! 目录 题外话开场简单介绍活动主办方介绍活动话题讨论升职加…

IDEA连接Github⭐️使用Git工具上传本地文件到远程仓库

环境准备 已安装IDEA开发工具,Git版本管理工具,已注册GitHub账号 需要先准备好这些环境,可以自行搜索教程,下面的安装是基于这里的环境上操作的 目录 一、需要提供SSH公钥 ​二、Github配置SSH公钥 ​三、IDEA配置连接 四、连…

C++ 多条件比较的几种实现方式

文章目录 1 sort()使用自定义比较器1.1 在类内部定义比较器 -- 声明为静态成员函数1.2 在函数内部定义比较器 -- lamda表达式1.3 全局函数比较器 2 重载运算符<2.1 在结构体中重载运算符<2.2 在类中重载运算符< 3 重写仿函数bool operator()4 使用pair排序5 priority_…

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

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

Mysql 安装通过mysql installer安装+配置环境+连接可视化工具

注意&#xff1a;不适合纯小白&#xff0c;小白建议移步别的大佬MySQL详细安装教程 目录 注意&#xff1a;不适合纯小白&#xff0c;小白建议移步别的大佬MySQL详细安装教程 前言 准备工作 一、Mysql下载 二、MySQL installer 安装以及系统环境配置 三、检验MySQL 四、可…

CleanMyMac X .4.14.7如何清理 Mac 系统?

细心的用户发现苹果Mac电脑越用越慢&#xff0c;其实这种情况是正常的&#xff0c;mac电脑用久了会产生很多的缓存文件&#xff0c;如果不及时清理会影响运行速度。Mac系统在使用过程中都会产生大量系统垃圾&#xff0c;如不需要的系统语言安装包&#xff0c;视频网站缓存文件&…

宝塔发布网站问题汇总和记录

1、添加网站站点后打不开 解决办法&#xff0c;关闭防跨站攻击2 2、laravel项目部署到linux的时候出现The stream or file "/home/www/storage/logs/laravel.log" could not be opened in append mode 给目录加权限 chmod -R 777 storage 3、Class "Redis"…

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

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

在线录屏-通过Web API接口轻松实现录屏

在线录屏是指在互联网上进行屏幕录制的过程。它允许用户通过网络连接&#xff0c;将自己的屏幕活动记录下来&#xff0c;并可以在需要时进行播放、共享或存档。在线录屏常用于教育、培训、演示、游戏等场景&#xff0c;可以帮助用户展示操作步骤、解决问题、分享经验等。通常&a…

MySQL运维篇(三)分库分表

一、介绍 1. 问题分析 随着互联网及移动互联网的发展&#xff0c;应用系统的数据量也是成指数式增长&#xff0c;若采用单数据库进行数据存储&#xff0c;存在以下 性能瓶颈&#xff1a; &#xff08;1&#xff09;IO瓶颈&#xff1a;热点数据太多&#xff0c;数据库缓存不足&…

Redis的事务

一、Redis中事务的定义 1) Redis事务是一个单独的隔离操作&#xff1a;事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中&#xff0c;不会被其他客户端发送来的命令请求所打断 2) Redis事务的主要作用就是串联多个命令防止别的命令插队。 二、multi 、exe…

高精度算法笔记·····························

目录 加法 减法 乘法 除法 高精度加法的步骤&#xff1a; 1.高精度数字利用字符串读入 2.把字符串翻转存入两个整型数组A、B 3.从低位到高位&#xff0c;逐位求和&#xff0c;进位&#xff0c;存余 4.把数组C从高位到低位依次输出 1.2为准备 vector<int> A, B, …

vite 打包优化

✨专栏介绍 在当今数字化时代&#xff0c;Web应用程序已经成为了人们生活和工作中不可或缺的一部分。而要构建出令人印象深刻且功能强大的Web应用程序&#xff0c;就需要掌握一系列前端技术。前端技术涵盖了HTML、CSS和JavaScript等核心技术&#xff0c;以及各种框架、库和工具…

消息中间件面试题

目录 一.为什么使用消息队列 二.RabbitMQ 1.RabbitMQ如何保证消息不丢失 2.RabbitMQ消息的重复消费问题 3.RabbitMQ延迟队列 4.RabbitMQ消息堆积 5.RabbitMQ高可用机制 三.Kafka 1.Kafka如何保证消息不丢失 2.Kafka如何保证消费消息的顺序性 3.Kafka高可用机制 4.Ka…

GitLab Runner 实现项目 CI/CD 发布

Gitlab Runner简介 Gitlab实现CICD的方式有很多&#xff0c;比如通过Jenkins&#xff0c;通过Gitlab Runner等&#xff0c;今天主要介绍后者。Gitlab在安装的时候&#xff0c;就默认包含了Gitlab CI的能力&#xff0c;但是该能力只是用于协调作业&#xff0c;并不能真的去执行…

PLSQL去除一个字符串中的数字

PLSQL去除一个字符串中的数字 SQL Select regexp_replace(abc1234ABC678aaad590AAA, [0-9], ) As 去数字后From dual;效果

Web开发介绍

1 什么是web开发 Web&#xff1a;全球广域网&#xff0c;也称为万维网(www World Wide Web)&#xff0c;能够通过浏览器访问的网站。 所以Web开发说白了&#xff0c;就是开发网站的&#xff0c;例如下图所示的网站&#xff1a;淘宝&#xff0c;京东等等 那么我们知道了web开发…

【Linux】Linux 系统编程——touch 命令

文章目录 1.命令概述2.命令格式3.常用选项4.相关描述5.参考示例 1.命令概述 在**Linux 中&#xff0c;每个文件都与时间戳相关联&#xff0c;每个文件都存储了上次访问时间、**上次修改时间和上次更改时间的信息。因此&#xff0c;每当我们创建新文件并访问或修改现有文件时&a…