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

news2024/11/15 12:09:03

我们在学习编译器时,我们不仅要只会使用编译器,还要理解程序的编译过程。一个程序存在两个不同的环境。第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语言,其他操作是类似的。

本篇结束!

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

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

相关文章

第十八章 Swing程序设计

Swing用于开发桌面窗体程序,是JDK的第二代GUI框架,其功能比JDK第一代GUI框架AWT更为强大、性能更加优良。但因为Swing技术推出时间太早,其性能、开发效率等不及一些其他流行技术,所以目前市场上大多数桌面窗体程序都不是由Java开发…

day18_多线程

今日内容 零、 复习昨日 一、作业 二、线程安全的集合 三、死锁 四、线程通信 五、线程池 零、 复习昨日 见晨考 一、线程安全[重点] 1.0 线程不安全 当前线程的数据被其他线程修改 1.1 线程安全 临界资源:共享资源(同⼀个对象),一次只可以有一个线程操…

JS-项目实战-代码优化-事件动态绑定

1、鼠标悬浮和离开事件.js //当页面加载完成后执行后面的匿名函数 window.onload function () {//get:获取 Element:元素 By:通过...方式//getElementById()根据id值获取某元素let fruitTbl document.getElementById("fruit_tbl");//table.rows:获取这个表格…

【Maven】进阶

文章目录 1. 聚合2. 继承3. 属性变量定义与使用4. 版本管理5. 资源配置6. 多环境配置7. 跳过测试(了解) 1. 聚合 为了防止某个模块(dao)更新了,重新编译了,导致和其他模块不兼容,需要用一个roo…

使用boost库

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:…

tsmc12 nm boundary cell注意事项

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 往期文章导读: boundary cell添加失败问题整理 注意N/P的区别 针对上下两边的boundary cell,有N/P类型的区别,看版图衬底形状上下是不对称的,而且P

深入理解SqueezeSegV3点云分割

文章:Squeezesegv3: Spatially-adaptive convolution for efficient point-cloud segmentation 代码:https://github.com/chenfengxu714/SqueezeSegV3 一、摘要 激光雷达点云分割是许多应用中的一个重要问题。对于大规模点云分割,一般是投…

零代码数字孪生设计平台的功能特点

在当今数字化的时代,企业的转型已经成为必然的趋势。而在这个过程中,3D数字孪生无代码编辑工具正成为企业实现数字化转型的新价值点。客户可以无需任何专业知识和专业软件的支持,仅仅通过互联网和浏览器即可根据购买要求对自己的产品/设备/园…

vite => .env 文件配置和使用

.env.development .env.production VITE_API_BASE_URL /api # 开发环境代理地址 .env.development 是在开发环境中的代理地址 .env.production 是在线上的代理地址 ( 两个 .env 内部的变量都是一样的 vite 会在你开发环境和线上环境自动做切换 ) …

彩虹桥架构演进之路-性能篇

一、前言 一年前的《彩虹桥架构演进之路》侧重探讨了稳定性和功能性两个方向。在过去一年中,尽管业务需求不断增长且流量激增了数倍,彩虹桥仍保持着零故障的一个状态,算是不错的阶段性成果。而这次的架构演进,主要分享一下近期针对…

【华为内部资料】《高速数字电路设计教材》(可下载)

与数字技术或软件相比,模拟技术人才的培养和造就仍然需要一定的实践和时间,但无论数字技术发展到任何阶段将永远离不开模拟技术。 由于难度系数较大的原因,有时即便投入很多精力,如果缺乏耐心、毅力和必要的条件,投入…

猫罐头买什么牌子的?宠物店最受欢迎的5款猫罐头推荐!

有多少铲屎官为了让猫咪健康快乐的成长,在猫罐头上费尽心机。钱是砸进去了,但是自己猫胖的胖、瘦的瘦,甚至有的毛病多,出现身体各种问题。 作为一个经营宠物店7年的店长,某宝有大促的时候我总能捡漏,囤到一…

物联网AI MicroPython学习之语法 GPIO输入输出模块

学物联网,来万物简单IoT物联网!! GPIO 介绍 模块功能: GPIO通用输入输出。 接口说明 GPIO - 构建GPIO对象 函数原型:Pin(port, dir , pull)参数说明: 参数类型必选参数?说明portintY对应开发板的引脚号…

【论文精读】VOYAGER: An Open-Ended Embodied Agent with Large Language Models

Understanding LSTM Networks 前言Abstract1 Introduction2 Method2.1 Automatic Curriculum2.2 Skill Library2.3 Iterative Prompting Mechanism 3 Experiments3.1 Experimental Setup3.2 Baselines3.3 Evaluation Results3.4 Ablation Studies3.5 Multimodal Feedback from …

【MySQL】MVCC(多版本并发控制)详解

MVCC MVCC概述 MVCC,全称 Multi-Version Concurrency Control ,即多版本并发控制。MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。 MVCC就是在ReadCommitte…

金蝶云星空表单插件获取控件值

文章目录 金蝶云星空表单插件获取控件值获取主键获取文本获取日期获取数值获取基础资料 金蝶云星空表单插件获取控件值 获取主键 正确: this.View.Model.GetPKValue();错误: 获取文本 this.View.Model.GetValue("FBILLNO")获取日期 thi…

一题带你写出图论算法模板!!!

这题是道基础的图论算法题目 注释很重要!!!!!!! 在做这道题之前,我们先了解一下基础的图论算法吧!!! 1.floyd: 这样可以求出所有点…

了解一下知识付费系统的开发流程和关键技术点

知识付费系统的开发既涉及到前端用户体验,又需要强大的后端支持和复杂的付费逻辑。在这篇文章中,我们将深入探讨知识付费系统的开发流程和关键技术点,并提供一些相关的技术代码示例。 1. 需求分析和规划: 在着手开发知识付费系…

day21_mysql

今日内容 零、 复习昨日 第一阶段: Java基础知识(会编程,懂编程) 第二阶段: Web开发(前端,后端,数据库) 一、MySQL 一、引言 二、数据库 2.1 概念 ​ 数据库是“按照数据结构来组织、存储和管理数据的仓库。是一个长期存储在计算机内的、有组织的、有共享的、统一管理的数据集合…

搭建成功simulink-stm32硬件在环开发环境

本次实验所使用的软件版本和硬件平台参数如下: Matlab版本: 2021b STM32硬件平台:YF_STM32_Alpha 1R4(参考自STM32 Nucleo F103RB官方开发板) YF_STM32_Alpha开发板 STM32 Nucleo F103RB 开发板 2.1 STM32硬件支持包下载 读者朋友平时使用的是和谐版M…