当前位置: 首页 > news >正文

C语言第三十八弹---编译和链接

个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】

编译和链接

1、翻译环境和运行环境

2、翻译环境

2.1、预处理(预编译)

2.2、编译

2.2.1、词法分析

2.2.2、语法分析

2.2.3、语义分析

2.3、汇编

2.4、链接

3、运行环境

总结


1、翻译环境和运行环境

编译链接主流程如下图:


在ANSIC的任何⼀种实现中,存在两个不同的环境。

第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令(⼆进制指令)
第2种是执行环境,它用于实际执行代码。

2、翻译环境


那翻译环境是怎么将源代码转换为可执行的机器指令的呢?这里我们就得展开开讲解⼀下翻译环境所做的事情。


其实翻译环境是由编译链接两个大的过程组成的,而编译又可以分解成:预处理(有些书也叫预编译)、编译、汇编三个过程。

⼀个C语言的项目中可能有多个 .c 文件⼀起构建,那多个 .c 文件如何生成可执行程序呢?

• 多个.c文件单独经过编译器,编译处理生成对应的目标文件。
注:在Windows环境下的目标文件的后缀是 .obj ,Linux环境下目标文件的后缀是 .o
• 多个目标文件和链接库⼀起经过链接器处理生成最终的可执行程序。
• 链接库是指运行时库(它是支持程序运行的基本函数集合)或者第三方库。


如果再把编译器展开成3个过程,那就变成了下面的过程:


2.1、预处理(预编译)


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

gcc -E test.c -o test.i

预处理阶段主要处理那些源文件中#开始的预编译指令。比如:#include,#define,处理的规则如下:

• 将所有的 #define 删除,并展开所有的宏定义。
• 处理所有的条件编译指令,如: #if、#ifdef、#elif、#else、#endif 。
• 处理#include预编译指令,将包含的头文件的内容插入到该预编译指令的位置。这个过程是递归进行的,也就是说被包含的头文件也可能包含其他文件。
• 删除所有的注释
• 添加行号和文件名标识,方便后续编译器生成调试信息等。
• 或保留所有的#pragma的编译器指令,编译器后续会使用。


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

2.2、编译


编译过程就是将预处理后的文件进行⼀系列的:词法分析、语法分析、语义分析及优化,生成相应的汇编代码文件。


编译过程的命令如下:
 

gcc -S test.i -o test.s

对下面代码进行编译的时候,会怎么做呢?假设有下面的代码
 

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

2.2.1、词法分析


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

2.2.2、语法分析


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

2.2.3、语义分析


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

2.3、汇编
 

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

gcc -c test.s -o test.o

2.4、链接


链接是⼀个复杂的过程,链接的时候需要把⼀堆文件链接在⼀起才生成可执行程序。
链接过程主要包括:地址和空间分配,符号决议和重定位等这些步骤。
链接解决的是⼀个项目中多文件、多模块之间互相调用的问题。
比如:
在⼀个C的项目中有2个.c 文件( test.c 和 add.c ),代码如下:


test.c
 

#include <stdio.h>
//test.c
//声明外部函数
extern int Add(int x, int y);
//声明外部的全局变量
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
 

int g_val = 2022;
int Add(int x, int y)
{
return x+y;
}

我们已经知道,每个源文件都是单独经过编译器处理生成对应的目标文件。
test.c 经过编译器处理生成 test.o
add.c 经过编译器处理生成 add.o
我们在 test.c 的文件中使用了 add.c 文件中的 Add 函数和 g_val 变量。
我们在 test.c 文件中每⼀次使用 Add 函数和 g_val 的时候必须确切的知道 Add 和 g_val 的地
址,但是由于每个文件是单独编译的,在编译器编译 test.c 的时候并不知道 Add 函数和 g_val
变量的地址,所以暂时把调用 Add 的指令的目标地址和 g_val 的地址搁置。等待最后链接的时候由链接器根据引用的符号 Add 在其他模块中查找 Add 函数的地址,然后将 test.c 中所有引用到
Add 的指令重新修正,让他们的目标地址为真正的 Add 函数的地址,对于全局变量 g_val 也是类
似的方法来修正地址。这个地址修正的过程也被叫做:重定位


前面我们非常简洁的讲解了⼀个C的程序是如何编译和链接,到最终生成可执行程序的过程,其实很多内部的细节无法展开讲解。比如:目标文件的格式elf,链接底层实现中的空间与地址分配,符号解析和重定位等,如果uu有兴趣,可以看《程序的自我修养》⼀书来详细了解。


3、运行环境

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

总结


本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!

相关文章:

C语言第三十八弹---编译和链接

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 编译和链接 1、翻译环境和运行环境 2、翻译环境 2.1、预处理&#xff08;预编译&#xff09; 2.2、编译 2.2.1、词法分析 2.2.2、语法分析 2.2.3、语义分…...

无人售货奶柜:开启便捷生活的新篇章

无人售货奶柜&#xff1a;开启便捷生活的新篇章 在这个快节奏的现代生活中&#xff0c;科技的革新不仅为我们带来了前所未有的便利&#xff0c;更在不经意间改变着我们的日常。其中&#xff0c;无人售货技术的出现&#xff0c;尤其是无人售货奶柜&#xff0c;已经成为我们生活…...

STM32为什么不能跑Linux?

STM32是一系列基于ARM Cortex-M微控制器的产品&#xff0c;它们主要用于嵌入式系统中。而Linux则是一个开源的类Unix操作系统&#xff0c;主要面向的是桌面电脑、服务器等资源丰富的计算机。虽然理论上可以将Linux移植到STM32上运行&#xff0c;但是由于两者之间存在着很多技术…...

Dubbo 3.x源码(18)—Dubbo服务引用源码(1)

基于Dubbo 3.1&#xff0c;详细介绍了Dubbo服务的发布与引用的源码。 此前我们学习了Dubbo的服务导出的源码&#xff0c;在DubboBootstrapApplicationListener#startSync方法中&#xff0c;在调用了exportServices方法进行服务导出之后&#xff0c;立即调用了referServices方法…...

设计模式:工厂模式和抽象工厂模式的区别

定义 工厂模式(Factory Pattern)通常指的是工厂方法模式(Factory Method Pattern),它定义了一个创建对象的方法,由子类决定要实例化的类。工厂方法让类的实例化推迟到子类。 抽象工厂模式(Abstract Factory Pattern)提供了一个接口,用于创建相关或依赖对象的家族,而…...

python面试题(36~50)

36、如何取一个整数的绝对值? 这可以通过abs函数来实现。 abs(2) #> 2 abs(-2) #> 2 37、如何将两个列表组合成一个元组列表? 可以使用zip函数将列表组合成一个元组列表。这不仅仅限于使用两个列表。也适合3个或更多列表的情况。 a [a,b,c] b [1,2,3] [(k,v) fo…...

Vue 样式技巧总结与整理[中级局]

SFC&#xff08;单文件组件&#xff09;由 3 个不同的实体组成&#xff1a;模板、脚本和样式。三者都很重要&#xff0c;但后者往往被忽视&#xff0c;即使它可能变得复杂&#xff0c;且经常导致挫折和 bug。 更好的理解可以改善代码审查并减少调试时间。 这里有 7 个奇技淫巧…...

cesium加载.tif格式文件

最近项目中有需要直接加载三方给的后缀名tif格式的文件 <script src"https://cdn.jsdelivr.net/npm/geotiff"></script> 或者 yarn add geotiff npm install geotiff 新建tifs.js import GeoTIFF, { fromBlob, fromUrl, fromArrayBuffer } from geotif…...

分布式全闪占比剧增 152%,2023 年企业存储市场报告发布

近日&#xff0c;IDC 发布了 2023 年度的中国存储市场报告。根据该报告&#xff0c;在 2023 年软件定义存储的市场占比进一步扩大&#xff0c;分布式全闪的增长尤其亮眼&#xff0c;其市场份额从 2022 年的 7% 剧增到 2023 年的 17.7%&#xff0c;增长了 152%。 01 中国企业存…...

LeetCode 707. 设计链表(单链表、(非循环)双链表 模板)

你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。 如果是双向链表&#xff0c;则还需要属性 prev 以指示链表中的上一个节点…...

深入了解Flutter中Overlay的介绍以及使用

Flutter Overlay 介绍 在 Flutter 中&#xff0c;Overlay 是一种特殊的 Widget&#xff0c;它可以用来在应用程序的其他部分之上显示内容。Overlay 非常适合用于显示模态对话框、弹出菜单、工具提示等。 Overlay 的工作原理 Overlay 位于 Flutter 的渲染树之外&#xff0c;这…...

文本直接生成2分钟视频,即将开源模型StreamingT2V

Picsart人工智能研究所、德克萨斯大学和SHI实验室的研究人员联合推出了StreamingT2V视频模型。通过文本就能直接生成2分钟、1分钟等不同时间&#xff0c;动作一致、连贯、没有卡顿的高质量视频。 虽然StreamingT2V在视频质量、多元化等还无法与Sora媲美&#xff0c;但在高速运…...

时序预测 | Matlab实现SOM-BP自组织映射结合BP神经网络时间序列预测

时序预测 | Matlab实现SOM-BP自组织映射结合BP神经网络时间序列预测 目录 时序预测 | Matlab实现SOM-BP自组织映射结合BP神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现SOM-BP自组织映射结合BP神经网络时间序列预测&#xff08;完整源码…...

FPGA高端图像处理开发板-->鲲叔4EV:12G-SDI、4K HDMI2.0、MIPI等接口谁敢与我争锋?

目录 前言鲲叔4EV----高端FPGA图像处理开发板核心板描述底板描述配套例程源码描述配套服务描述开发板测试视频演示开发板获取 前言 在CSDN写博客传播FPGA开发经验已经一年多了&#xff0c;帮助了不少人&#xff0c;也得罪了不少人&#xff0c;有的人用我的代码赢得了某些比赛、…...

linux练习-交互式传参

在shell脚本中&#xff0c;read 向用户显示一行文本并接受用户输入 #!/bin/bash read -p 依次输入你的姓名、年龄、家乡 name age home echo 我是$name,年龄$age,我来自$home...

【数据结构(一)】初识数据结构

❣博主主页: 33的博客❣ ▶文章专栏分类: Java从入门到精通◀ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你学更多数据结构知识 目录 1.前言2.集合架构3.时间和空间复杂度3.1算法效率3.2时间复杂度3.2.1大O的渐进…...

前端三剑客 —— CSS (第六节)

目录 内容回顾&#xff1a; 弹性布局属性介绍 案例演示 商品案例 布局分析 登录案例 网格布局 内容回顾&#xff1a; 变量&#xff1a;定义变量使用 --名称&#xff1a;值&#xff1b; 使用变量&#xff1a; 属性名&#xff1a;var&#xff08;--名称&#xff09;&a…...

MyBatis 解决上篇的参数绑定问题以及XML方式交互

前言 上文:MyBatis 初识简单操作-CSDN博客 上篇文章我们谈到的Spring中如何使用注解对Mysql进行交互 但是我们发现我们返回出来的数据明显有问题 我们发现后面三个字段的信息明显没有展示出来 下面我们来谈谈解决方案 解决方案 这里的原因本质上是因为mysql中和对象中的字段属性…...

Rust语言之属性宏(Attribute Macro)derive

文章目录 Rust语言之属性宏&#xff08;Attribute Macro&#xff09;derive Rust语言之属性宏&#xff08;Attribute Macro&#xff09;derive 属性宏是一种基于属性的宏&#xff0c;用于修改、扩展或注解 Rust 代码。它们通常用于为函数、结构体、枚举、模块等添加元数据或自…...

[技术闲聊]我对电路设计的理解(六)-原理图封装

电路设计的直观体现就是完整的原理图&#xff0c;绘制电路图阶段的第一步&#xff0c;绘制原理图封装库。 封装库一共有两种&#xff0c;一种是原理图封装库&#xff0c;一种是PCB封装库&#xff0c;如下图所示。 原理图封装和PCB封装之间的唯一关联就是 引脚位号&#xff0c;…...

算法(滑动窗口四)

1.串联所有单词的子串 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如&#xff0c;如果 words ["ab","cd","ef"]&#xff…...

学习记录:bazel和cmake运行终端指令

Bazel和CMake都是用于构建软件项目的工具&#xff0c;但它们之间有一些重要的区别和特点&#xff1a; Bazel&#xff1a; Bazel是由Google开发的构建和测试工具&#xff0c;用于构建大规模的软件项目。它采用一种称为“基于规则”的构建系统&#xff0c;它利用构建规则和依赖关…...

蓝桥杯刷题--python-37-分解质因数

3491. 完全平方数 - AcWing题库 nint(input()) res1 i2 while i*i<n: if n%i0: t0 while n%i0: n//i t1 if t%2: res*i i1 if n>1: res*n print(res) 4658. 质因数个数 - AcWing题库…...

Delphi编写的图片查看器

UNIT Unit17;INTERFACEUSESWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,Vcl.StdCtrls, Vcl.ExtDlgs, Vcl.ExtCtrls, Vcl.Imaging.jpeg; //注意&#xff1a;要加入jpej 否侧浏览图…...

Swing中的FlowLayout/WrapLayout在打横排列时候如何做到置顶对齐

前言 最近在开发swing客户端时候碰到一个棘手的问题&#xff1a; Swing中的FlowLayout/WrapLayout在打横排列时候如何做到置顶对齐如果是vue或者react&#xff0c;一搜百度什么都出来了&#xff0c;swing的话&#xff0c;嗯。。。资料有点少而且大部分是stack overflow上面的…...

C# MES通信从入门到精通(8)——C#调用Webservice服务进行数据交互

前言 在上位机开发领域,使用webservice来访问客户的终端Mes系统是一项必备的技能,本文详细介绍了如何在c#中调用webservice服务,不仅介绍了使用添加服务引用直接调用webservice中的方法外还介绍了使用http的post方法调用webservice方法,过程详细且均为实战经验总结,对于初…...

day04-MQ

1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;但是你…...

神经网络汇聚层

文章目录 最大汇聚层平均汇聚层自适应平均池化层 最大汇聚层 汇聚窗口从输入张量的左上角开始&#xff0c;从左往右、从上往下的在输入张量内滑动。在汇聚窗口到达的每个位置&#xff0c;它计算该窗口中输入子张量的最大值或平均值。计算最大值或平均值是取决于使用了最大汇聚…...

2024.3.8力扣每日一题——找出美丽数组的最小和

2024.3.8 题目来源我的题解方法一 数学 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2834 我的题解 方法一 数学 经过分析&#xff0c;在target之前&#xff0c;取小于等于target/2的正整数才能使得和最小&#xff0c;并且满足条件3。 时间复杂度&#xff1a;O(n) 空…...

单例模式以及线程安全问题

单例模式的概念 单例模式是指的是整个系统生命周期内&#xff0c;保证一个类只能产生一个实例对象 保证类的唯一性 。 通过一些编码上的技巧&#xff0c;使编译器可以自动发现咱们的代码中是否有多个实例&#xff0c;并且在尝试创建多个实例的时候&#xff0c;直接编译出错。 …...

怎么做彩票网站代理/百度知道灰色词代发收录

本节书摘来自异步社区《Adobe Illustrator CS5中文版经典教程》一书中的第0课0.13节使用“外观”面板和效果&#xff0c;作者【美】Adobe公司,更多章节内容可以访问云栖社区“异步社区”公众号查看。 0.13 使用“外观”面板和效果Adobe Illustrator CS5中文版经典教程“外观”面…...

自己做的网站搜索不到/苹果要做搜索引擎

在判断一个网络的基本情况时&#xff0c;我们一般先在命令行下使用Ping命令&#xff0c;探测至目标地址的时延、丢包、MTU等情况。1、直接简单Ping测&#xff0c;可以查看时间和丢包情况2、使用-n参数&#xff0c;设置ping测包数量3、使用-t参数&#xff0c;一直Ping测&#xf…...

网站中弹出广告怎么做的/朋友圈广告30元 1000次

2019独角兽企业重金招聘Python工程师标准>>> 9月12日任务 2.6 相对和绝对路径 2.7 cd命令 2.8 创建和删除目录mkdir/rmdir 2.9 rm命令 2.6 、相对路径与绝对路径 绝对路径是以 / 开始的目录 例&#xff1a; [rootlocalhost ~]# ls /etc/passwd 相对路径…...

移动网站设计方案/长沙网络营销学校

随着6月份的美国E3电子娱乐游戏展览会的临近&#xff0c;高分辨率的视网膜屏幕的价值将会得到验证。即将推出的视网膜屏幕MacBook是非常有前景的&#xff0c;然而这种屏幕如果也能推广到普通电脑、客厅设备的话&#xff0c;我们的生活将提高一个档次。 我们为什么需要视网膜屏幕…...

wordpress 加广告位/宁波靠谱营销型网站建设

原因&#xff1a; 网络原因导致 dns解析失败。 解决方案&#xff1a; 方案一 &#xff1a; 1、查看你的服务器能否ping通外网&#xff0c;不过不行说明你的网络出了问题. &#xff08;我的情况是客户的应用服务器只能内网访问&#xff0c;所以是网络出问题了&#xff0…...

保定专业网站建设/开网店怎么推广运营

【实例简介】点击1显示按钮菜单&#xff0c;按第一个按钮出现物体并可以移动&#xff0c;在点击物体可以放下&#xff0c;放下后在物体上长按左键可以拖动【实例截图】【核心代码】shubiaomove└── shubiaomove├── Config│ ├── DefaultEditor.ini│ ├── Defaul…...