LINUX入门篇【5】----程序的翻译过程解析

news2024/12/30 3:00:13

前言:

在C语言阶段我们已经讲过程序的翻译过程,我们知道程序是由预处理,编译,汇编,链接四部分组成的,但是,当时受到C语言编译器的限制,我们没法去深刻体会这个过程,所以,本次我们利用LINUX再一次更为详细的展现一下程序的翻译。

1.编译器:

不同的语言需要由不同的编译器来进行编译,我们一般使用gcc来编译C语言,g++来编译C++语言,且这个对应是不能混淆的,否则编译是无法通过的。
在这里补充一下C++文件的几种格式:.cpp,.cc,.cxx等,我们不能仅仅认识cpp后缀的叫C++文件,要知道C++后缀的文件不只一种
在LINUX中gcc是自带的,想要编译C++语言,需要我们下载一个g++编译器,在这里我们可以使用:
yum install gcc-c++,也就是利用我们上节课讲的yum软件搜索系统来下载
但是,说到这里,你或许会问,LINUX不是不看后缀么?
这个之前我是说过的,LINUX的确是不看后缀的,但是编译工具是看后缀的,所以我们规范文件名和代码还是很有必要的

2.程序的翻译过程详解:

先让我们复习一下程序的翻译的过程:预处理,编译,汇编,链接,**每经过一个阶段,我们所写的程序就被处理为一个不同的形式,但它的趋势是逐渐处理为我们看不懂而计算机硬件能看懂的过程。**这句话很关键,但为什么要这样去一步一步的去翻译呢?难道直接一步到位让计算机看懂不行么?
这就要谈一谈我们程序的发展过程了:
首先我们明白,计算机的本质是一堆硬件,只能处理二进制信息,不管是多么强大和先进的计算机,它都只能识别二进制的数据,因此,早期的科学家们使用打孔的方式打印计算机信息,后来经过发展,人们发明了一套编码负责专门处理这种二进制信息,这便是汇编语言,但是,就像我说过的,计算机只能看懂二进制信息,因此,需要专门把汇编语言翻译成二进制信息给计算机看,由此,便诞生了最早的编译器,汇编语言编译器,负责将汇编代码翻译成二进制语言交给计算机去理解。但是,即使是汇编语言依旧晦涩难懂,大部分人没法快速掌握语法和功能,由此,科学家们又以汇编语言为底层,开发出了更高级的语言—C语言!同时,C语言的编译器也应运而生,但和汇编编译器不同,C语言的编译器负责去将C语言的代码翻译成汇编语言,然后汇编语言再经过编译器变成二进制代码。从这之后,C++诞生了,但是其本质都不无承接C语言的做法,将其翻译成汇编语言。C/C++之后,又出现了一大批以C/C++为底层的解释性语言,JAVA python php他们的本质是解释代码的意思而不是编译,但是你可以理解为他们是将其代码解释成汇编代码,因此他们使用解释器而不是编译器。通过这个过程,我i们发现,语言的发展是一层接着一层去承接的,下一层把上一层当作底层来进行翻译,这个过程便是语言/编译器的自举过程。
在这里插入图片描述
这也就解释了为什么我们的计算机程序翻译是一步一步进行的而不是跨越,因为每一步都有对应的编译器,你总不能重新构建一个由C语言直接翻译为二进制代码的编译器吧,那样需要消耗大量的成本和时间,而且毫无意义,这样一层一层的编译,提高了效率也节省了成本。
由此,我们便先解开了为什么我们的计算机程序要一步一步去翻译的问题,下面就让我们一步一步去看:

1.预处理:

在预处理阶段,由C语言那篇文章我们知道,主要进行的是4个过程:
1.头文件展开
2.去掉注释
3.条件编译
4.宏替换

经过这4个过程,我们的程序代码就更加纯粹和简洁,我们以LINUX我写的这个代码为例子,来讲一讲。
在这里插入图片描述

这是一个很简单的C语言程序,在这里包括条件编译,宏,条件编译,注释,让我们看看经过预处理阶段后程序会变成什么样子呢?
我们wq退出程序,然后我们输入指令gcc -E 文件名 -o 新的文件名
这条指令的意思就是:从现在开始进行程序的翻译,到预处理完就停下来,并将预处理完的结果放入我们后面的文件中,如下:
在这里插入图片描述
我将文件放入到code.i文件中,现在让我们打开文件:
在这里插入图片描述
是的,你会发现宏被替换后消失了,同时条件编译直接保留条件编译要执行的程序部分,其他部分全部剪切掉,同时注释被取消,这样,我们的代码就变得更加简洁。
条件编译为我们提供了一个很好的思路:
通过条件编译,我们是可以实现代码的动态裁剪的,比如,就如同我们玩的游戏有时会有不同的版本切换,不同的版本或许只是几个数值上的改变,游戏的机制和操作方式没有任何区别,这种不同版本的维护,对应的源代码其实都是一份,而通过条件编译,就可以实现利用一份源代码去维护两个或者多个版本

2.编译:

下一个过程就是编译,即是将代码经过编译器编译成汇编语言,为下一步汇编进一步翻译成二进制码做准备,我们的指令为:
gcc -S code.i -o code.s
文件如下:
在这里插入图片描述
在这里便是汇编代码的内容,为下一步做准备

3.汇编:

指令如下:
gcc -c code.s -o code.o
在这里插入图片描述
到这里,已经变成能由计算机看懂的二进制代码了。

4.链接:

所谓的链接,其实本质上讲是我们的.o文件完成后,同系统库链接,从而最终形成可执行程序的过程。
链接还是很好理解的,不过在这里我们谈到了库,由此便让我们先讲一讲何为库:

1.动态库,静态库概念和理解:

我们现在所写的代码,包括一些可以直接使用的函数,都是前人写好的,我们都是直接拿来用。
那么,这些函数存储他们的库在哪里呢?我们可以用下面的指令来查看:
ldd +可执行程序文件如下:
在这里插入图片描述
我们的ldd指令就可以查看我们所写的可执行程序都链接了哪些库,在这里你会看见三个,由此我们先引入库的分类:

1.库的分类:

库主要分为两种:
1.动态库:
.库类别为.so的即为动态库,这是在LINUX,在windows中为xxxx.dll
2.静态库:
库类别为.a的即为静态库,这是在LINUX,在windows中为xxx.lib
而在我们的LINUX系统中,是基本不会默认安装静态库的,而是动态库居多,至于这是为什么,我们先把这条结论记住,之后等我们分析优缺点的时候,不用我说,你自然就知道原因了。

2.库命名:

一个常见的库的命名如下:
在这里插入图片描述
一个库的真正名字实际上就是去掉lib,类别,版本号剩下的,在这里就是C即为它的名字。

3.动静态链接的理解:

我们应该怎样理解链接呢?我用这样一张图去体现链接的过程,图片如下:
在这里插入图片描述
我们前面知道,LINUX系统中默认的库都是动态库,所以如果你删除了动态库,LINUX系统相当于直接用不了了,要重新装。
根据上面的图,我们来明确一下动静态库,动静态链接的概念:
动态库:是C/C++或者其他第三方提供的所有方法的集合,被所有程序以链接的方式关联起来。
动态链接:库中的所有函数,都有其对应的入口地址,所谓的动态链接,其实就是把链接的库中的函数的入口地址拷贝到我们的可执行程序的特定位置,方便程序执行时可以到对应地址的位置调用函数.(注意,由于程序没有实际执行,也就是说,程序没有实际上在内存空间中占用位置,故在这里我们的入口地址都是逻辑地址而非物理上的地址)
静态库:是C/C++或者其他第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码拷贝到自己的可执行程序中。
静态链接:以拷贝的形式,直接把所需要的函数代码拷贝到程序当中

在这里,我们就很清楚动静态链接的差别所在了:动态链接是拷贝地址,而静态链接是拷贝代码,就像我上面的图所示的,静态相当于直接把代码放到自己的身边,而动态的代码依旧在原来的位置

4.动静态链接的优缺点:

动态链接:
优点:形成的可执行程序体积比较小,比较节省资源
缺点:由于涉及到根据地址调用的过程,因此要慢一些,并且强依赖动态库,一旦动态库没了,所有依赖这个库的程序都没法执行了
静态链接:
优点:即使库被销毁,由于程序代码已经被拷贝到程序中,因此可以独立运行
缺点:体积太大,浪费资源

由此,让我们想想我之前问大家的那个问题?为什么LINUX支持的都是默认的动态文件,而不是静态的呢?
这正是因为静态库占用了过大的空间,浪费了更多的资源,我们可以拿这样一个例子来说明:
我们在gcc指令后面加上-static,就代表静态链接的意思,如下我们产生了这样的情况:
在这里插入图片描述
在这里插入图片描述
你会发现,861288是静态链接的可执行程序的大小,而8360是动态链接的,即使是一个很小的程序,就有这样的大小差距,现在我想,默认动态库不是没有道理的吧。
补充,有时我们-static没法执行:这个时候需要我们安装C的静态:
sudo yum install glibc-static
如果你需要C++的静态编译器,你可以安装:
sudo yum install -y libstdc+±static

5.引发思考,一款合格开发环境应该为我们做什么:

在这里我必须重新提一下VS,它确实称得上是一款十分优秀的开发平台,随着我自己配置编译器的过程,我逐渐意识到vs的强大之处,我们在VS可以直接调用库,可以调试,可以重新编译和卸载上一次的编译结果,可以查看汇编代码。
那在我看来,一个优秀的开发环境应该具备:
1.配置好了各种开发需要的库环境,例如lib 等
2.设置了合适的查找路径,方便调用
3.规定好我们形成的可执行程序的链接方式

总结:

本篇,我们进一步查看了程序是如何被翻译出来的,以及库的链接是如何进行的,同时我们也清楚的知道,我们所写的程序是多种库组合出来的结果,没有这些库,我们的函数就需要自己去构造,很麻烦,库进一步帮助我们提高了开发效率,同时,也让我们对开发环境的配置要求有了一个初步大概的认识。之后,我们将进一步配置完善我们的代码编写vim工具,并且可以在LINUX上实现我们的第一个有趣的程序。

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

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

相关文章

使用Navicat导出ER图详细教程

文章目录 打开Navicat,点击模型点击新建模型选择物理模型点击文件,选择从数据库导入选择要导入的数据库点击文件,选择导出的格式成品 打开Navicat,点击模型 点击新建模型 选择物理模型 点击文件,选择从数据库导入 选择…

springcloud图书借阅管理系统源码

开发说明: jdk1.8,mysql5.7,nodejs,idea,nodejs,vscode springcloud springboot mybatis vue elementui 功能介绍: 用户端: 登录注册 首页显示搜索图书,轮播图&…

windows安装linux双系统启动盘的制作与恢复

下载镜像 Index of /ubuntu-releases/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 制作启动盘 准备一个U盘,注意备份,启动盘的制作过程中是将ISO烧录到U盘中,会将U盘中的原内容覆盖掉在网上下载Win32DiskImager软件包烧录ISO…

Linux服务器配置信息查询命令

Linux服务器配置信息查询命令 一、查看CPU信息 查询系统的CPU的详细信息,包括每个处理器的型号、频率、缓存等级以及每个核心的数量。cat /proc/cpuinfo二、查看内存信息 查询系统的内存信息,包括可用内存、已用内存和缓存等。cat /proc/meminfo三、查…

第六章 :Spring Boot web开发常用注解(一)

第六章 :Spring Boot web开发常用注解(一) 前言 本章节知识重点:作者结合自身开发经验,以及觉察到的一个现象:Springboot注解全面理解和掌握的并不多,对注解进行了全面总结,共分两个…

力扣21:合并两个有序链表

力扣21:合并两个有序链表 **题目描述:**将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4] 示例 2&…

项目管理之如何出道(下)

前言 是谁用烛火照亮整个中国?是一伙伙行走在高压线上的电力工人; 是谁用水枪保护千家万户?是一组组穿梭于大街小巷的消防队伍; 是谁用身体捍卫国防边境?是一队队跋涉在高山深林的可爱战士。 那么作为IT业界的我们&…

Leetcode_3:Pow(x,n)

题目描述: 实现 pow(x, n) ,即计算 x 的整数 n 次幂函数。 示例 1: 输入:x 2.00000, n 10 输出:1024.00000示例 2: 输入:x 2.10000, n 3 输出:9.26100示例 3: 输入&…

阿里云99元的主机到底怎么样?

我是卢松松,点点上面的头像,欢迎关注我哦! 在云栖大会上,阿里云推出了一款绝对超级超值的99元云服务器,并号称是11月销量王。什么?云栖大会11月2号结束的,你就号称11月销量王,这是未卜先知啊。…

【MySQL进阶之路丨第十七篇(完结)】一文带你精通MySQL运算符

引言 在上一篇中我们介绍了MySQL函数;在开发中,对MySQL运算符的运用是十分重要的。这一篇我们使用命令行方式来帮助读者掌握MySQL中运算符的操作。 上一篇链接:【MySQL进阶之路丨第十六篇】一文带你精通MySQL函数 MySQL运算符 MySQL中的运…

Embedding技术与应用(3):Embeddings技术的实践应用

编者按: IDP开启Embedding系列专栏,力图详细介绍Embedding的发展史、主要技术和应用。 本文是《Embedding技术与应用系列》的第三篇,重点介绍 嵌入技术在生产环境中的应用效果到底如何。 文章作者认为,嵌入技术可以有效地表示用户…

Lua更多语法与使用

文章目录 目的错误处理元表和元方法垃圾回收协程模块面向对象总结 目的 在前一篇文章: 《Lua入门使用与基础语法》 中介绍了一些基础的内容。这里将继续介绍Lua一些更多的内容。 同样的本文参考自官方手册: https://www.lua.org/manual/ 错误处理 下…

Python开源项目CodeFormer——人脸重建(Face Restoration),模糊清晰、划痕修复及黑白上色的实践

无论是自己、家人或是朋友、客户的照片,免不了有些是黑白的、被污损的、模糊的,总想着修复一下。作为一个程序员 或者 程序员的家属,当然都有责任满足他们的需求、实现他们的想法。除了这个,学习了本文的成果,或许你还…

漏极开路/集电极开路OD/OC上拉电阻选型参数确定方法及应用场景经验总结

🏡《电子元器件学习目录》 目录 1,概述2,最小值2.1,饱和区2.2,逻辑低电平3,最大值3.1,驱动能力3.2,信号上升沿4,应用场景5,总结1,概述 如下图所示MOS管的集电极开路直接输出的形式被称为OD输出;如果使用的是三极管则被称为OC输出。在实际使用中OD或OC输出需要根据…

【Git】中Gui的使用和SSH协议的讲解及IDEA开发中使用git

目录 一、Gui使用 1. 使用 2. 功能 二、SSH协议 1. 讲解 2. 生成密钥 3. 远程仓库绑定公钥 三、IDEA使用 1. IDEA配置git 2. IDEA安装gitee 3. IDEA中登入Git 4. 项目分享 5. 克隆分享的项目 6. idea上传远程 一、Gui使用 (Gui) 是指图形用户界面,它…

半导体高加速应力测试及标准

半导体高加速应力测试及标准 随着电气和电子元件变得越来越密集,现在对零件和材料的高度加速应力测试的需求更大。 高加速应力测试系统(HAST 室)主要设计用于使用设定的施加电压和信号进行偏置测试。 控制功能可选择标准的不饱和控制和湿饱和…

SLAM从入门到精通(光源的控制)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面我们说过,图像在二维码、道路检测、故障物检测方面都有很重要的作用。但是,这里面就有一个前提,那就是图像…

月销破30万辆后,比亚迪整了波大的

最近乘联会公布了 2023 年 10 月新能源乘用车厂商销量榜单。 其中最为亮眼犹如鹤立鸡群的榜首,没错依然是我们熟悉的那个迪子! 单月销量超 30 万辆,相较去年同期暴涨 38.4%,创下了比亚迪有史以来新高。 同时也成为了国内首个月销…

秋招进入尾声了,还有哪些公司和岗位可以投递?

24届秋招基本已经进入尾声了,接下来就是秋招补录了,最近在微信群看到一些同学再问哪些公司还在招人的。 在这里跟大家分享一份2024届秋招信息汇总表,目前已更新2000家,不仅有互联网公司,还有外企、国企、各类研究所&am…

基于SSM的个人网站的设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…