【Linux学习】(6)编译器gcc/g++

前言

本节重点:掌握gcc/g++编译器的使用,并了解其过程,原理

一、Linux编译器-gcc/g++使用

1. gcc/g++的基本使用

  1. 在前面我们学习了vim,知道如何在Linux中编写代码。
  2. 但又是如何编译代码的?——在Linux中我们编译代码使用的是gcc/g++。
  3. gcc只能用来编译C语言,g++即可编译C也可编译C++(C++兼容C)。
  4. 虽然g++也可以编译C,但是一般C语言编译,我们比较推荐gcc。
  5. gcc/g++他们对应的选项几乎一模一样,所以这里我们学习gcc即可,g++的使用直接平替gcc的使用。
  6. gcc的基本使用:gcc xx.c ——》gcc编译C源文件,如果不加任何选项,默认直接生成可执行程序a.out(tip:代码如果有语法错误等,gcc也会有编译报错。)
  7. g++的基本使用:g++ xx.cpp ——》g++编译C/C++源文件,如果不加任何选项,默认也直接生成可执行程序a.out
  8. 可以通过 -o 选项来自定义输出文件的名称,-o后面紧跟的永远是你自定义命名的目标文件。

示例:

在这里插入图片描述

#gcc编译C源文件,如果不加任何选项,默认直接生成可执行程序a.out
gcc xx.c
#g++编译C/C++源文件,如果不加任何选项,默认也直接生成可执行程序a.out
g++ xx.cpp
#如果想自定义命名目标生成的可执行文件,使用-o选项
#-o选项用于指定编译后的输出文件名
gcc xx.c -o xx.exe(推荐写法)/ gcc -o xx.exe xx.c

2. gcc编译程序的四个阶段

文本的C源代码编译成计算机可以认识的二进制程序它需要经过如下四个阶段:

  1. 预处理(进行宏替换,去注释,头文件展开,条件编译等)
  2. 编译(生成汇编)
  3. 汇编(生成机器可识别的二进制代码)
  4. 链接(生成可执行文件或库文件)

(1)预处理阶段

  1. 预处理指令是以#号开头的代码行
  2. 预处理功能主要包括宏替换、头文件展开、条件编译、去注释等
    • 宏替换:只做简单的宏替换,不做类型检查,因为在编译阶段才会做语法检查
    • 头文件展开:把头文件的内容拷贝到源文件的行为叫做头文件展开
    • 条件编译:条件编译可以在编译前对代码进行条件判断和处理,从而实现代码的选择性编译
    • 去注释:注释是帮助我们理解代码的,计算机并不需要,所以在预处理阶段就将注释去掉
  3. 预处理阶段指令格式:gcc -E xx.c -o xx.i
  4. -E选项:告诉gcc,从现在开始进行程序的翻译,将预处理工作做完就停下来,不要往后走了!
  5. -o xx.i:预处理之后产生的结果都放在xx.i文件中(tip:不带-o选项,默认把输出结果打印到显示器上)
  6. “.i”文件为已经预处理的C原始程序,还是C语言。

示例:

在这里插入图片描述
加油站:

  1. 我们为什么可以在Windows或者Linux上进行C/C++或者其他形式的开发?

    答:我们的系统一定提前或者后续安装了,C/C++开发相关的头文件、库文件。编译型语言,安装开发包,必定是下载安装对应的头文件+库文件。
  2. 在Linux中开发相关的头文件,一般在/usr/include/这个目录下。在这里插入图片描述
  3. /usr/include/这个目录是我们Linux系统中gcc/g++编译器,默认搜索头文件时的搜索路径。
  4. 条件编译:条件编译可以在编译前对代码进行条件判断和处理,从而实现代码的选择性编译
    • #ifdef:如果定义了某个宏,则编译随后的代码块
    • #else:如果前面的#ifdef条件不满足,则编译#else后面的代码块
    • #endif:结束条件编译块,每一个完整的条件编译语句都需要#endif来收尾
    • 使用场景:特性开关——根据是否定义了某个宏来启用或禁用某些功能在这里插入图片描述
  5. 条件编译的宏通常在编译命令中通过 -D 选项定义,格式:gcc xx.c -D宏名字在这里插入图片描述
gcc -E xx.c -o xx.i -DDEBUG
# -E:告诉gcc,从现在开始进行程序的翻译,将预处理工作做完就停下来,不要往后走了
# -o xx.i:把预处理结果放到xx.i文件中
# -D:在gcc命令行中可通过选项-D定义宏

(2)编译阶段

  1. 在编译阶段,gcc首先要检查代码的规范性、是否有语法错误等,在检查无误后,gcc把代码翻译成汇编语言
  2. 实例:gcc -S mycode.i -o mycode.s
  3. -S选项:从现在开始进行程序的翻译,将编译工作做完,就停下来在这里插入图片描述

(3)汇编阶段

  1. 汇编阶段是把编译阶段生成的“.s”文件转成目标文件
  2. 实例:gcc -c mycode.s -o mycode.o
  3. -c选项:从现在开始进行程序的翻译,将汇编工作做完,就停下来
  4. mycode.o:可重定位目标二进制文件,简称目标文件,.obj文件不可以独立执行,虽然已经是二进制了,但需要经过链接(库)才能执行在这里插入图片描述
  5. 注意vim是文本编辑器,所以打开的二进制文件显示是乱码!
  6. 二进制查看工具:od 二进制文件

(4)连接

  1. 在成功编译之后,就进入连接阶段
  2. 连接:将可重定位目标二进制文件和库进行连接形成可执行程序
  3. 实例:gcc mycode.o -o mycode.exe在这里插入图片描述

问题:程序翻译的四个过程中,连接没有选项,但是预处理、编译、汇编都有选项,我们有什么技巧可以帮助我们记忆吗?

答案是,有的,如下:

  • 预处理、编译、汇编的选项按照顺序,是ESc,我们可以看键盘的左上角【ESC】键帮助我们记忆
  • 预处理、编译、汇编文件的后缀顺序,是iso,镜像文件的后缀就是iso,所以我们可以通过镜像文件后缀帮助我们记忆
  • 虽然Linux系统中文件后缀没有意义,但是不代表Linux系统上运行的软件不需要后缀,就比如这里的gcc,所以建议我们一般带上正确的后缀

(5)重要概念:函数库

  • 重新理解函数,是个函数他就第一有定义,第二有声明,第三有调用
  • 在C语言中我们常常调用库函数来编程,但是在我们的程序中,并没有定义库函数的实现,且在预编译中包含的头文件中也只有该函数的声明,而没有定义库函数的实现,那么,是在哪里实现库函数的呢?
  • 答案是:库,库中给我们提供方法的实现
  • 因为我们用的是C语言,所以我们使用的就是C语言标准库,其本质是一个文件,有路径(C标准库在Linux系统中默认在/usr/lib64/libc.so*)在这里插入图片描述
  • 在不同的平台下库有不同的格式:
    • 在Linux下,以.so为后缀的是动态库,以.a为后缀的是静态库
    • 在Windows下,以.dll为后缀的是动态库,以.lib为后缀的是静态库
  • 库有自己的命名规则,以lib为前缀,以.so.xxx为后缀(xxx是版本号):libname.so.xxx
  • 在Linux系统中只会默认帮我们安装动态库,静态库默认是没有安装的


归纳标准库:

  1. 方法的实现就是在库中
  2. 库其实就是把源文件(.c),经过一定的翻译,然后打包——只给你提供一个文件即可,不用给你提供太多的源文件,也可以达到隐藏文件的目的
  3. 头文件提供方法的声明,库文件提供方法的实现(不让我们做重复工作,站在巨人的肩膀)+你的代码 = 你的软件

(6)函数库一般分为静态库和动态库两种

  • 静态库:静态库是指编译连接时,把库文件的代码全部拷贝到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
  • 动态库:动态库与之相反,在编译链接时并没有把库文件的代码拷贝到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”。
  • 帮助理解:
    • 动态库我们可以将其比作网吧,当我们想玩游戏的时候,就可以去网吧玩。(动态库即共享库,所以我们的网吧只有一个)但是当有一天网吧被查封了,我们就不能玩了(动态库不能缺失,一但对应的动态库缺失,影响的不止一个程序,可能导致很多程序都无法进行正常运行!)
    • 静态库我们将其比作电脑销售商,我们买了电脑之后,没有网吧和电脑销售商倒闭了,也可以有自己的电脑可以玩游戏(静态库在链接的时候,会把自己拷贝到目标程序中,所以该程序可以独立运行)
  • 库有动态库和静态库两种,自然我们的.o和库的链接方式也有两种:
    • 动态链接:在Linux中,编译形成可执行程序,默认采用的就是动态链接——提供动态库
    • 静态链接:在Linux中,如果要按照静态链接的方式,形成可执行程序,需要添加-static选项——
      提供静态库
    • 注意:动态链接只能使用动态库,静态链接只能使用静态库
    • 验证:ldd指令可查看一个可执行程序所依赖的动态库在这里插入图片描述
    • 补充:file指令也可查看一个可执行程序使用了什么链接方式在这里插入图片描述
  • 我们的Linux系统一般只默认安装了动态库,静态库需要我们自己安装
  • 如果我们没有静态库,就不能-static静态链接在这里插入图片描述
  • 安装静态库:
sudo yum install -y glibc-static # 安装C静态库
sudo yum install -y libstdc++-static # 安装C++静态库
  • 如果我们没有动态库,只有静态库,gcc不带-static选项能找到静态库吗——能,gcc只是默认优先动态链接
  • -static的本质:改变链接的优先级,所有的链接要求全部变成静态链接(注:只适配一次)
  • 连接不一定是纯的全部动态链接或静态链接,混合的。
  • 动态库VS静态库:
    • 动态库因为是共享库,有效的节省资源(磁盘空间、内存空间、网络空间等)【优点】,动态库一但缺失,导致各个程序都无法运行【缺点】
    • 静态库,不依赖库,程序可以独立运行【优点】,但体积大、比较消耗资源【缺点】

(7)debug和release

  1. 源文件编译时有有两种模式,debug模式和release模式
  2. debug通常称为调试版本,它包含调试信息,并且不做任何优化,便于程序员调试程序(因为debug模式在形成可执行程序的时候,添加了debug信息,所以可以被追踪调试)
  3. release称为发布版本,它往往是进行了各种优化,是程序在代码大小和运行速度上都是最优的,以便用户很好的使用
  4. 在Linux系统上gcc形成的可执行程序,默认是release版本
  5. 如果想以debug形式编译,我们需要添加-g选项(-g生成调试信息)
  6. 验证:readelf -S指令可以读取可执行程序对应的二进制构成,再通过grep debug可以将debug信息过滤出来在这里插入图片描述

二、执行可执行程序

  • 为什么我们运行自己的可执行程序的时候,要在前面带./呢?

因为执行一个程序,你就必须要先找到这个程序

而要找到这个程序,其本质就是要定位这个程序的二进制文件在系统中的位置

./就是告诉我们的系统,当前我要执行的可执行程序在我的当前路径下

  • 重新理解路径

为什么要有路径——答案是:因为要定位文件

  • 系统命令也是一个可执行的二进制文件,为什么执行的时候就不用带./呢?

不带./并不代表不用找到,因为系统会默认帮我们找到(通过环境变量)

  • 总结:
  1. 在Linux系统中执行任何一个程序,都必须要找到这个程序对应的二进制文件
  2. 系统命令因为系统帮我们配了环境变量,系统自己找得到,所以系统命令不用带路径,直接就可以执行
  3. 而我们自己的程序,系统找不到,所以需要我们自己指定路径./,才能执行

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

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

相关文章

UDP(用户数据报协议)端口监控

随着网络的扩展,确保高效的设备通信对于优化网络功能变得越来越重要。在这个过程中,端口发挥着重要作用,它是实现外部设备集成的物理连接器。通过实现数据的无缝传输和交互,端口为网络基础设施的顺畅运行提供了保障。端口使数据通…

Linux中安装配置SQLite3,并实现C语言与SQLite3的交互。

前言 SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。本次实验介绍在Linux上实现C语言和SQLite3的交互,利用C语言编写相关语句,连接数据库、操作数…

【数据结构初阶】二叉树---堆

二叉树-堆的实现 一、树的概念(什么是树)二、二叉树的概念及结构2.1 二叉树的概念2.2 二叉树的性质2.3 二叉树存储结构 三、二叉树的顺序结构3.1 堆的概念及结构3.2 堆的向下调整算法3.3堆的创建 四、堆的代码实现4.1 堆的初始化4.2 堆的销毁4.3 堆的插入…

如何从iconfont中获取字体图标并应用到微信小程序中去?

下面我们一一个微信小程序的登录界面的制作为例来说明,如何从iconfont中获取字体图标是如何应用到微信小程序中去的。首先我们看效果。 这里所有的图标,都是从iconfont中以字体的形式来加载的,也就是说,我们自始至终没有使用一张…

jenkins 自动化部署Springboot 项目

一、安装docker 1.更新yum命令 yum -y update2.查看机器有残留的docker服务,有就卸载干净 查看docker 服务 rpm -qa |grep docker卸载docker sudo yum remove docker-ce docker-ce-cli containerd.io sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/contai…

linux下的进程等待(wait、waitpid)

目录 引言 进程等待的必要性 见见猪跑:是什么 怎么办 多个子进程时 阻塞等待 非阻塞轮询 参数一: 参数二 进程等待的原理 进程退出相关的宏 第三个参数option(设置等待的方式) 引言 在Linux操作系统中,进程…

Jmeter实际应用

环境准备 JDK1.8Jmeter 5.6.3 下载地址Jmeter 插件 下载地址 放到lib/ext下 常用命令 # 启动 sh jmeter# 集群模式下启动节点,不启动用不了集群 sh jmeter-server#生成ssl需要的证书, 这里会要求输入个密码,是要在jmeter中用的 keytool -import -ali…

Claude Financial Data Analyst:基于Claude的金融数据分析工具!免费开源!

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…

基于SSM+小程序的垃圾分类管理系统(垃圾2)

👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM小程序的垃圾分类管理系统实现了管理员及用户。 1、管理员功能结构图,管理员功能有个人中心,管理员管理,基础数据管理、论坛管理、垃圾信息管理…

钰泰ETA4553电压电平转换器IC

描述 ETA4553 是两位同相转换器,是一种双向电压电平转换器,可用于建立混合电压系统之间的数字开关兼容性。它使用两个独立的可配置电源轨,A 端口支持 1.65V 至 5.5V 的工作电压,同时跟踪 VCCA 电源,B 端口支持 2.3V 至…

QT QDialog::exec()调用时清除部件所有焦点

最近在做项目时,遇到一个问题:在统信UOS系统编写的QT程序,其中进入某些页面时,或者显示模态窗时,按钮都会有一个焦点框,这个是不允许的,于是乎,开始了清理焦点的旅途。 一、清理QDia…

高速自爆穿梭无人机技术详解

高速自爆穿梭无人机技术是一种结合了高速飞行与自爆式攻击能力的先进无人机技术。以下是对该技术的详细解析: 一、技术特点 1. 高速飞行: 高速自爆穿梭无人机通常具备极高的飞行速度,如部分型号的速度可达到174公里/小时,甚至更…

五,Linux基础环境搭建(CentOS7)- 安装Kafka

Linux基础环境搭建(CentOS7)- 安装Kafka 大家注意以下的环境搭建版本号,如果版本不匹配有可能出现问题! 一、Kafka下载及安装 Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高…

[ARC159D] LIS 2 题解

[ARC159D] LIS 2 题面: 题面翻译 给定 n n n 个操作,每次操作给出 l , r l,r l,r,并在 a a a 序列里依次添加 i ∈ [ l , r ] i\in[l,r] i∈[l,r]。 求最后 a a a 的最长上升子序列。 题目描述 数列 $ X $ があります。初め、$ X $ は空…

网络搜索引擎Shodan(1)

声明:学习视频来自b站up主 泷羽sec,如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址:shodan(1)_哔哩哔哩_bilibili 本文主要讲解网络搜索引擎Shodan的一些用法(host和search这两个命令)。 Shodan 是一个网络…

Matlab学习02-matlab中的数据显示格式及符号变量

目录 一,关系运算和逻辑运算 二,变量 三,数据显示格式 四,符号运算 1,创建符号变量 2,数值矩阵转换成符号矩阵 一,关系运算和逻辑运算 在matlab中,只要数值不是 &#xff0…

jenkins下拉参数联动

需要安装Active Choices插件,官网地址: https://plugins.jenkins.io/uno-choice/ 安装完插件以后会出现Active Choices选项: 第一个参数: return ["dubbo-op-all-deployment1", "dubbo-op-all-deployment2",…

合并数组的两种常用方法比较

在 JavaScript 中,合并数组的两种常用方法是使用扩展运算符 (...) 和使用 push 方法。 使用扩展运算符 this.items [...this.items, ...data.items]; 优点: 易于理解:使用扩展运算符的语法非常直观,表达了“将两个数组合并成一个…

基于vue框架的的高校消防设施管理系统06y99(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能:设备分类,设备信息,维修人员,报修信息,维修进度,院系,消防知识,培训记录,培训信息,备件信息,备件申请,派发信息,采购信息 开题报告内容 基于Vue框架的高校消防设施管理系统开题报告 一、项目背景与意义 随着高校规模的不断扩大和校园建…

基于Django+Python的房屋信息可视化及价格预测系统设计与实现(带文档)

项目运行 需要先安装Python的相关依赖:pymysql,Django3.2.8,pillow 使用pip install 安装 第一步:创建数据库 第二步:执行SQL语句,.sql文件,运行该文件中的SQL语句 第三步:修改源…