Linux编译器:gcc/g++的使用

我们在学习编译器时,我们不仅要只会使用编译器,还要理解程序的编译过程。一个程序存在两个不同的环境。第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令;第2种是执行环境,它用于实际执行代码。本篇文章将在讲解程序的翻译过程中来介绍gcc/g++的使用。

目录

1.语言的发展以及自举的过程

2. gcc如果完成各个翻译过程

2.1 预处理(进行宏替换)

2.2 编译(生成汇编)

2.3 汇编(生成机器可识别代码)

2.4 链接(生成可执行文件或库文件)

2.4.1 函数库一般分为静态库和动态库两种

2.4.2 动态链接与静态链接


程序的翻译过程:

  1. 预处理(进行宏替换)
  2. 编译(生成汇编)
  3. 汇编(生成机器可识别代码)
  4. 链接(生成可执行文件或库文件)

1.语言的发展以及自举的过程

为什么程序翻译要有怎么多过程,这里通过了解语言的发展以及自举或许可以理解。那么什么是自举呢,就是通过自己的语言实现自己的编译器。那么这时候就有问题:是先有语言还是编译器?我们这里慢慢解释。

最开始,计算机只能识别二进制,我们要向计算机传递信息时,只能通过穿孔纸带让CPU识别,也就是最初的第一代语言:机器语言。

但是于这种语言人类很难理解,为了更好的与计算机进行沟通,发展出了第二代语言:汇编语言,用助记符代替了操作码,用地址符号或标号代替地址码,这样就用符号代替了机器语言的二进制码。使用符号代替二进制码进行相关操作。

这里就可以使用汇编代码写软件了,但是既然可以使用汇编语言写软件,也就可以使用汇编语言写汇编语言的编译器,这里就实现了汇编语言的自举。很明显这里可得:是先规划的语言,再通过语言写的编译器。

后来人们认为汇编语言还是复杂,于是就发展有了第三代语言:高级语言C语言,是一种接近于人们使用习惯的程序设计语言。同汇编语言相同,所以高级语言也可以实现自举,但是这里就有一个问题了:高级语言是先将代码转换为汇编代码,再转换为二进制让机器识别,还是直接转换为二进制让机器识别?

首先我们要知道语言发展的每一步都是经历过很多困难的,二进制重写高级语言与汇编语言重写高级语言相比无疑是比较困难的,所以说用汇编代码写高级语言是更加合适的。

这里就可以理解为什么程序翻译过程中要有编译(生成汇编)和汇编(生成机器可识别代码)的过程了。理解这里之后我们继续讲解。

2. gcc如果完成各个翻译过程

格式 gcc [选项] 要编译的文件 [选项] [目标文件]

2.1 预处理(进行宏替换)

  • 预处理功能主要包括替换宏定义,文件包含(拷贝),条件编译,去注释等。
  • 预处理指令是以#号开头的代码行。
  • 实例: gcc –E hello.c –o hello.i
  • 选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
  • 选项“-o”是指定目标文件,“.i”文件为已经过预处理的C原始程序

通过vim编译code1.c文件,然后用 gcc 编译code1.c,如果这里没有加选项 -E,会将程序的翻译过程全部进行完,-E 就是让 gcc 预处理完就停下来,如果不加 -o 会将文件预处理完的内容直接打印到屏幕上。

这里可以用vs指令查看多个文件:

可以发现这里预处理后的 .i 文件比 .c 源文件多出了八百多行,多出的主要是包含头文件,也就是把 stdio.h 的内容拷贝了过来。还通过条件编译,实现了对代码的动态裁剪。宏常量M也被替换,注释也被去除。

这里条件编译就可以理解很多软件有免费版本和收费版本,但只需要维护一份代码。

2.2 编译(生成汇编)

  • 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
  • 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
  • 实例: gcc –S code.i –o code.s

 这里也可以直接通过gcc -S .c 文件,-S让文件翻译到编译结束后就停下来。

可以发现 .s 文件内部已经生成了汇编代码。 

2.3 汇编(生成机器可识别代码)

  • 汇编阶段是把编译阶段生成的“.s”文件转成目标文件
  • 读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了
  • 实例: gcc –c code.s –o code.o

-c 就是将文件翻译进行到汇编结束后就停下来,这里生成 .o 目标文件

通过vim打开文件,可以发现已经生成了我们看不懂的可重定位二进制文件。 

 可以使用od命令查看二进制文件,但也是看不懂的

gcc 指令记忆 -ESc ,与键盘上的退出键相同,但要注意大小写。

生成文件的后缀 -iso 

2.4 链接(生成可执行文件或库文件)

  • 多个可重定位文件(二进制文件)合并成一个可执行文件,进行符号解析和重定位
  • 实例: gcc code.o –o code,这里gcc不加指令即可直接生成可执行程序。

在当先文件目录下是,直接 ./文件名 即可执行。因为执行一个程序需要找到它的位置,这里是相对路径,. 代表当前目录。

可执行文件是由我们的代码+头文件+库组成的,这里就涉及到的知识,我们下面讲解:

  1. 我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?
  2. 最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。lib表示是库文件,.so表示动态库,.6是版本号,所以这个库的名字是c,即c标准库。

2.4.1 函数库一般分为静态库和动态库两种

  1. 静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
  2. 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销,所谓的动态链接,就是把要链接库中的函数地址拷贝到我们可执行程序的特定位置。动态库一般后缀名为“.so”如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。 gcc code.o –o code
  3. gcc默认生成的二进制程序,是动态链接的。
  4. Windows下静态库后缀.lib,动态库后缀.dll

2.4.2 动态链接与静态链接

动态链接优缺点:

  • 优点:形成的可执行程序体积比较小,比较节省资源的
  • 缺点∶稍慢一些,强依赖动态库,动态库没了,所有的依赖这个库的程序都无法运行了

静态链接优缺点︰

  • 优点:无视库,可以独立运行
  • 缺点:体积太大,浪费资源

ldd指令查看可执行程序所依赖的库。gcc 后加-static 可以链接静态库

下面可以发现静态链接比动态链接生成的可执行程序体积要大很多。 

默认情况下,云服务器是没有安装c静态库的,只有动态库,安装方法:

  • C语言静态库:sudo yum install glibc-static
  • C++的静态库: sudo yum install -y libstdc++-static

g++ 可以编译C语言和C++,但是gcc只能编译C语言,其他操作是类似的。

本篇结束!

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

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

相关文章

Linux C 进程间通信

进程间通信 概述进程间通信方式管道概述管道函数无名管道 pipe有名管道 makefifo删除有名管道 rmove 有名管道实现 双人无序聊天 例子 信号信号概述信号处理过程信号函数传送信号给指定的进程 kill注册信号 signal查询或设置信号处理方式 sigaction设置信号传送闹钟 alarm 有名…

【ONE·Linux || 网络基础(三)】

总言 主要内容:HTTP和HTTPS工作方式简述。 文章目录 总言6、HTTP协议(应用层二)6.1、入门认识6.1.1、认识URL6.1.2、urlencode和urldecode 6.2、快速构建6.2.1、快速构建http请求和响应的报文格式6.2.2、http demo6.2.2.1、sock.hpp &&a…

vite环境变量相关

环境变量:根据环境的不同,灵活的自动读取相应的变量。避免了手动修改。 import path from path import postCssPxToRem from postcss-pxtorem import { defineConfig, loadEnv } from vite import createVitePlugins from ./vite/plugins import copy f…

【LeetCode刷题笔记】二叉树(三)

701. 二叉搜索树中的插入操作 解题思路: 1. 模拟 ,如果 根节点为空 ,就用 插入值创建根节点 直接返回。否则, cur 从 根节点 开始,比较 当前节点的值和插入值的大小关系 : 1)如果 插入值 < cur ,就

一张图系列 - “position_embedding”

关于位置编码&#xff0c;我感觉应该我需要知道点啥&#xff1f; 0、需要知道什么知识&#xff1f; multi head atten 计算 复数的常识 1、embedding 是什么&#xff1f; position embedding常识、概念&#xff0c;没有会怎样&#xff1f; 交换token位置&#xff0c;没有P…

vue手动搭建脚手架(保姆式教案)

目录 1.创建项目 1.node.js环境搭建 2.安装vue-cli 3.搭建项目 目录结构 1.创建项目 1.node.js环境搭建 下载安装node.js&#xff08;Download | Node.js&#xff09;&#xff0c;安装时不要安装在C盘Windowsr打开cmd管理工具开始输入命令检查node.js是否安装和版本号&a…

在IDEA中的DeBug调试技巧

一、条件断点 循环中经常用到这个技巧&#xff0c;例如&#xff1a;遍历1个List的过程中&#xff0c;想让断点停在某个特定值。 参考上图&#xff0c;在断点的位置&#xff0c;右击断点旁边的红点&#xff0c;会出来1个界面&#xff0c;在Condition这里填写断点条件即可&#…

QCustomPlot的下载和使用

0.QCustomPlot介绍 QCustomPlot是一个基于Qt画图和数据可视化的C控件。在Qt下的绘图工具有Qwt、QChart和QCustomPlot&#xff0c;置于选择哪个绘图工具各有优缺点。 在绘制大量数据&#xff08;10万个点以上&#xff09;时选择QCustomPlot&#xff0c;在数据量比较小时&#x…

docker内更新显卡cuda cudnn

当前docker使用的cuda为10.2&#xff0c;为保证服务器环境使用相同的cuda版本&#xff0c;需对cuda版本进行升级&#xff0c;时间长了忘记如何操作&#xff0c;此处记录一下&#xff1a; *docker内使用的cuda版本低于容器外的显卡驱动版本即可&#xff0c;此处不对显卡驱动进行…

解决STM32F429烧录程序后还需复位才能植入程序的bug

1.打开魔术棒&#xff0c;打开debug 2.打开setting 3.打开Flas Download 4.开启Reset and Run 5.点进去Pack选项页面&#xff0c;去掉enable

springboot 2.1.0.RELEASE 项目加入swagger接口文档

Release v2.1.0.RELEASE spring-projects/spring-boot GitHub springboot 2.1.0.RELEASE发行日期是2018年10月30日&#xff08;Oct 30, 2018&#xff09; 不要使用过高的swagger版本&#xff0c;如SpringFox Boot Starter 3.0.0&#xff0c;否则报错&#xff1a; spring-…

MOS管体电极接源端版图layout画法

记录一个lvs一直跑不通的问题。 问题描述&#xff1a;lvs一直显示某几个MOS管的体电极连接问题。连线没有问题&#xff0c;版图中已经画了衬底。 原因&#xff1a; 图中四个管子的衬底接了源端&#xff0c;没接电源。 解决办法&#xff1a; 法1、源端接地 法2、将这四个管子…

msvcp140.dll丢失的解决办法,msvcp140.dll丢失会导致电脑出现哪些错误

msvcp140.dll丢失的解决办法都有哪些&#xff1f;如果电脑不及时将msvcp140.dll文件进行修复的话电脑可能会出电脑可会出现哪些错误&#xff1f;今天就和大家说说都有哪些解决办法有效的解决msvcp140.dll丢失的问题。 一.缺失msvcp140.dll会有什么问题 当电脑上缺少msvcp140.d…

67基于matlab图像处理,包括颜色和亮度调整、翻转功能、空间滤波和去噪、频域滤波和去噪、噪声添加,形态学操作、边缘检测及示波器集成的GUI图像处理。

基于matlab图像处理&#xff0c;包括颜色和亮度调整、翻转功能、空间滤波和去噪、频域滤波和去噪、噪声添加&#xff0c;形态学操作、边缘检测及示波器集成的GUI图像处理。数据可更换自己的&#xff0c;程序已调通&#xff0c;可直接运行。 67 matlab图像处理图像降噪 (xiaohon…

Python Web APP在宝塔发布

本地测试运行&#xff1a;uvicorn main:app --host 127.0.0.1 --port 8082 --reload 宝塔发布&#xff1a; 运行配置——>启动模式&#xff1a;worker_class uvicorn.workers.UvicornWorker

stable diffusion到底是如何工作的

stable diffusion简单入门 stable diffusion是一个文生图模型&#xff0c;主要由CompVis、Stability AI和LAION的研究者们创建。这个模型主要是在512X512分辨率的图像上训练的&#xff0c;训练数据集是LAION-5B&#xff0c;该数据集是目前可访问的最大的多模态数据集。 在这篇…

Spring6(四):JUnit、事务

文章目录 5. 单元测试&#xff1a;JUnit5.1 整合JUnit55.2 整合JUnit4 6. 事务6.1 JdbcTemplate6.1.1 准备工作6.1.2 实现CURD①装配 JdbcTemplate②测试增删改功能③查询数据返回对象④查询数据返回list集合⑤查询返回单个的值 6.2 事务6.2.1 编程式事务6.2.2 声明式事务 6.3 …

【数据结构】直接选择排序(你知道最不常用的排序算法有哪些吗?)

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;数据结构 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你有帮助…

AI创作系统ChatGPT网站源码+详细搭建部署教程+支持DALL-E3文生图/支持最新GPT-4-Turbo-With-Vision-128K多模态模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

OpenSign:安全可靠的电子签名解决方案 | 开源日报 No.76

microsoft/Web-Dev-For-Beginners Stars: 71.5k License: MIT 这个开源项目是一个为期 12 周的全面课程&#xff0c;由微软云倡导者团队提供。它旨在帮助初学者掌握 JavaScript、CSS 和 HTML 的基础知识。每一节都包括预习和复习测验、详细的书面指南、解决方案、作业等内容。…