Linux 编译器 gcc/g++
本文已收录至《Linux知识与编程》专栏!
作者:ARMCSKGT
演示环境:CentOS 7
目录
前言
正文
gcc/g++常用命令
自定义可执行程序名命令-o
预处理指令-E
编译指令-S
汇编指令-c
链接指令gcc
命令巧记口诀
链接库
动态库-动态链接
静态库-静态链接
动静态库对比
其他指令
声明与定义分离的编译指令
C99标准编译指令
gcc和g++的联系与区别
最后
前言
在Windows环境下,我们我们使用VS编译器可以写代码然后运行编译代码所成的程序,但在Linux系统下,我们写的C/C++代码需要通过gcc(C语言)和g++(C++语言)编译器才能生成可执行程序,所以学习gcc和g++是非常重要的!

正文
在实际的使用中,单纯的编译执行C和C++文件gcc和g++操作几乎相同,但是内部工作原理是截然不同的!所以在后面的讲解中会以gcc为例进行讲解,g++操作与之相同!
如果您在使用时系统报错:bash: gcc(或g++): command not found,这是因为你的Linux系统没有安装gcc或g++导致的,使用命令:
yum -y install gcc //安装gcc yum -y install g++ //安装g++一般Linux系统是安装了gcc的,但g++需要手动安装!
gcc/g++常用命令
我们在使用中,如果想利用对应文件生成可执行程序,命令是:
gcc [-选项] [.c文件] g++ [-选项] [.cpp文件]如果不加(除o)的其他选项,那么默认直接生成可执行程序,程序名为a.out,我们输入命令 ./a.out 就可以执行这个程序!
自定义可执行程序名命令-o
命令:
gcc [.c文件] -o [自定义名称] //建议写法 gcc -o [自定义名称] [.c文件] //这种写法也是可以的,但是不建议这里需要注意的是,-o选项后面紧跟的必须是自定义名称,可以想象:-o [自定义名称] 是固定组合,不能颠倒顺序乱写!
g++也可以通过-o选项生成自定义名称的可执行程序!
我们都知道源文件变成可执行程序会经过四个阶段:预处理->编译->汇编->链接库,gcc/g++编译时如果不加选项是直接执行这四步,如果我们想看其中一步执行后的文件,那么就需要对应的选项。
预处理指令-E
指令:
gcc -E [.c文件] -o [文件名].i预处理又称预编译,预处理后的文件其后缀我们默认是 .i ,而且在这里我们如果想获得预处理后的代码文件还需要指定一个文件名,如果不使用-o指定文件名,gcc会将预处理后的代码输出到屏幕上,只有指定文件名才能保存为文件!
代码的预处理会将头文件展开,替换宏,删除注释并执行条件编译等操作,这样才能生成一个纯C语言的代码文本方便后面继续转换!
使用vim打开后里面都是预处理后的代码 这里我们使用-E选项是让编译器执行完预处理就停下!
编译指令-S
指令:
gcc -S [.c文件/.i预处理文件] //默认生成的文件与编译前的文件名相同但是后缀为.s gcc -S [.c文件/.i预处理文件] -o [文件名].s //指定生成汇编代码的文件名这里如果我们不使用-o选项编译器会生成与被编译文件名一样的文件但后缀为.s,且这里既可以对.c代码文件编译,也可以对预处理文件.i进行编译,只不过对.c文件进行编译会先执行预处理然后再执行编译,执行完编译就停下,而预处理文件则是直接进行编译然后停止!
编译会对预处理代码进行语法词法并和语义分析,并进行符号汇总等,然后转换为汇编代码。
vim打开编译的文件里面是汇编代码和一些符号标记 汇编指令-c
指令:
gcc -c [.c文件/.i预处理文件/.s编译文件] //默认生成与被执行文件的文件名相同后缀为.o的二进制文件 gcc -c [.c文件/.i预处理文件/.s编译文件] -o [文件名].o这里如果我们不使用-o选项编译器会生成与被编译文件名一样的文件但后缀为.o,且这里既可以对.c代码文件,.i代码文件和.s汇编代码文件进行汇编,只不过对.c文件进行编译会先执行预处理然和编译,然后执行汇编后就停下;.i文件会先执行编译再执行汇编就停下,.s文件则直接进行汇编然后停下!
汇编是将汇编代码转换为二进制汇编文件且生成符号表,这里的二进制文件通过file指令查看是elf格式,通过vim打开会显示一片乱码!
我们如果想查看这个文件,需要通过指令:
readelf -a [二进制文件.o]
有需要的小伙伴如果缺失这个功能可以通过yum下载!指令:
yum -y install readelf链接指令gcc
指令:
gcc [.c/.i/.s/.o文件] //默认生成a.out可执行程序(可使用-o自定义名称)链接是形成程序的最后一步,如果前面缺少一步就会先执行没有进行的步骤!
链接会进行合并段表,将符号表进行合并和重定位等;然后会将程序与运行所需要的各种函数和库函数链接起来(编译器默认动态链接),生成可执行程序的格式是elf,也可以通过readelf指令查看!
命令巧记口诀
指令 ESc (键盘上的退出键),文件后缀 iso (镜像文件格式)
链接库
我们都知道,每种语言都有属于自己的库,比如C语言的stdio标准库等,C++有iostream库,当程序在在运行中调用库函数时就会通过地址去库中找这个函数进行调用!在Linux系统中,标准库在 /usr/include/ 目录下,在这个目录下,是Linux系统的各种C语言动态库,除了动态库的概念外,还有静态库的概念,我们慢慢介绍!
Linux系统下的各种库 库文件格式为:lib文件名.a/so,识别时去掉lib和后缀就是文件名!
动态库的文件格式为:lib文件名.so
静态库的文件格式为:lib文件名.a
在Linux系统中,指令也是可执行程序都是C语言写的依赖库!
动态库-动态链接
动态库又称共享库,动态库是动态链接的库,如果程序中有该库的函数和引用则会在调用位置留下一个链接,程序运行调用该函数时就会通过这个链接找到对应的库函数并执行!这样动态库只需要存一份代码就可以实现多个程序的调用!
链接就是将代码中使用的库函数与对应的库链接(将调用的库函数的文件地址拷贝到文件中)。
动态库一旦被删掉,那么所有依赖该库的程序就无法执行了;动态链接只是拷贝库的地址,执行时需要跳转到库中执行。
在Linux系统下gcc和g++链接是默认动态链接库的,如果我们想查看文件的链接方式,指令为:
ldd [文件/程序] //查看程序链接库方式打开后会显示各种链接状态且可以看到动态链接的文件后缀都是.so 通过file指令还可以查看可执行程序的链接情况! 这也说明Linux是默认动态链接的!动态链接的好处在于编译出来的程序体积小,但是跨平台能力差!
静态库-静态链接
静态库采用静态链接的方式,静态链接与动态链接不同之处在于,动态库在调用库函数时根据地址去库中寻找并调用,而静态链接则是将调用的库函数拷贝到自己的代码文件中,相当于本地存储,后续直接执行本地代码文件,不依赖任何动态库!
如果需要静态库编译代码,指令是:
gcc [-选项] [.c文件] -static可以在预处理-编译-汇编-链接这四个阶段选择静态链接,因为链接是最后一步!
Linux的静态库需要手动安装,指令是:
yum -y install glibc-static //下载静态库
ldd指令显示文件没有链接任何库!file指令显示可执行程序是静态链接!
而且静态库链接因为将库代码拷贝到了本地文件,其文件体积将会变得非常大!所以Linux中默认动态链接的方式!
动静态库对比
区别 动态库 静态库 库函数调用方式 通过链接去库中调用 在本地代码中调用 跨平台性与依赖性 需要依赖库运行,跨平台性差 不需要依赖库,跨平台性良好 空间占用 空间占用小 空间占用大 加载速度 需要根据链接去找库函数然后执行 直接执行本地库函数代码 优点 可以实现不同进程间的资源共享,对于函数的升级只需要替换动态库文件,不需要重新编译程序,可以控制是否加载动态库,不调用函数时就不加载
所需函数直接拷贝至程序中,运行速度快程序运行无需依赖库,便于移植和跨平台
缺点 需要调用函数,加载速度较慢,程序运行需要依赖动态库
对于函数的升级,需要重新进行编译同一份代码可能出现重复拷贝的情况,浪费空间
其他指令
声明与定义分离的编译指令
gcc [-选项] [头文件.h] [实现代码.c] [主函数.c]声明与定义分离,只需要将程序的所有相关文件列入gcc中,然后正常编译即可!
C99标准编译指令
gcc [-选项] [.c文件] -std=c99 //以C99标准编译代码当我们想要C99标准语法时可以使用该指令编译!
gcc和g++的联系与区别
gcc和g++都是GNU(一个组织)的编译器。
1、对于.c后缀的文件,gcc把它当做是C程序;g++当做是C++程序;2、对于.cpp后缀的文件,gcc和g++都会当做c++程序。
3、编译阶段,g++会调用gcc;
4、连接阶段,通常会用g++来完成,这是因为gcc命令不能自动和c++程序使用的库连接。
最后
Linux编译器gcc/g++的介绍到这里就结束了,相信学完的老铁肯定想动手写两个程序吧?gcc和g++如此强大的功能来自于GNU组织的开发,让我们可以在Linux上看到代码的底层知识!本节也介绍了动态库和静态库的区别和优缺点,相信大家以后能对库进行合理利用,开发出好的作品!
本次Linux编译器gcc/g++的基本知识就介绍到这里啦,希望能够尽可能帮助到大家。
如果文章中有瑕疵,还请各位大佬细心点评和留言,我将立即修补错误,谢谢!

🌟其他文章阅读推荐🌟
Linux基础指令-CSDN博客
Linux权限的基本知识-CSDN博客
Linux编辑器vim-CSDN博客
🌹欢迎读者多多浏览多多支持!🌹
相关文章:
Linux 编译器 gcc/g++
本文已收录至《Linux知识与编程》专栏! 作者:ARMCSKGT 演示环境:CentOS 7 目录 前言 正文 gcc/g常用命令 自定义可执行程序名命令-o 预处理指令-E 编译指令-S 汇编指令-c 链接指令gcc 命令巧记口诀 链接库 动态库-动态链接 静态库…...
2.Java基础【Java面试第三季】
2.Java基础【Java面试第三季】前言推荐2.Java基础01_字符串常量Java内部加载-上58同城的java字符串常量池面试code讲解intern()方法---源码解释02_字符串常量Java内部加载-下whyOpenJDK8底层源码说明递推步骤总结考查点03_闲聊力扣算法第一题字节跳动两数求和题目说明面试题解法…...
Java高级-多线程
本篇讲解java多线程 基本概念: 程序、进程、线程 **程序(program)**是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。 **进程(process)**是程序的一次执行过程,或是正在运行的一个程序。是一个动态的过程…...
mysql高级(事务、存储引擎、索引、锁、sql优化、MVCC)
文章目录1.事务1.1 四大特性ACID1.2 并发事务2.存储引擎2.1 InnoDB2.2 MyISAM2.3 Memory2.4 存储引擎特点2.5 存储引擎的选择3.性能分析3.1 查看执行频次3.2 慢查询日志3.3 profile3.4 explain4.索引4.1 索引结构B-TreeBTreeHash面试题4.2 索引分类思考题4.3 语法4.4 使用规则最…...
Java后端开发功能模块思路
文章目录前言一、查找接口及参数信息1.1 找访问路径1.2 参数及返回结果信息1.3 编写功能模块函数二、代码设计思路三、总结前言 对于正在学习Java后端开发的同学来说,对于Java后端功能模块的开发过程及思路要有一个整体清晰的流程。才能保证在开发过程中更加的顺畅…...
CAPL(vTESTStudio) - DoIP - TCP发送_05
TCP发送 参数定义 版本号:02 FD or 01 FE or 其他任意值数据类型:00 05 or 00 06 or 80 01 or其他任意值数据长度:想要发送的任意长度...
使用IntelliJ IDEA搭建datax-web开发环境
记录:372场景:使用IntelliJ IDEA搭建datax-web开发环境,以及datax-web基本使用。版本:JDK 1.8Python 2.7.5datax-web开源地址:https://github.com/WeiYe-Jing/datax-web1.配置Maven环境1.1安装目录目录:D:\…...
[SSD固态硬盘技术 14] GC垃圾回收太重要了
今天介绍臭名昭著的垃圾收集 过程(或“GC”),maybe 这是对JAVA 工程师而言。当遇到GC导致速度降低时候, 他们真的想跳脚。 我想到我的小孩打疫苗,哭的哇哇叫, 在他的眼里疫苗应该也是讨厌的吧, 但事实真的如此吗? 但首先,让我们考虑一下如果根本没有 GC,闪存系统会发…...
lamada表达式、stream、collect整理
lamada表达式格式 格式:( parameter-list ) -> { expression-or-statements } 实例:简化匿名内部类的写法 原本写法: public class LamadaTest { public static void main(String[] args) { new Thread(new Runnable() { …...
Nacos 入门微服务项目实战
Nacos 核心源码精讲 - IT贱男 - 掘金小册全方位源码精讲,深度剖析 Nacos 注册中心和配置中心的核心思想。「Nacos 核心源码精讲」由IT贱男撰写,375人购买https://s.juejin.cn/ds/BuC3Vs9/ Hi,大家好,欢迎大家来学习《Nacos 核心源…...
【c++】类和对象:让你明白“面向一个对象有多重要”:构造函数,析构函数,拷贝构造函数的深入学习
文章目录 什么是面向对象?一:类是什么? 1.类的访问限定符 2.封装 3.类的实例化 4.this指针二:类的6个默认成员函数 1.构造函数 2.析构函数 3.拷贝构造函数什么是面向对象? c语言是面向…...
职场IT老手教你3步教你玩转可视化大屏设计,让领导眼前一亮!
我是制造企业的IT中心的研发人员,平常工作就是配合业务部门出出报表,选型一些商业软件,并在内部负责实施运维。最近领导出去参观了一些数字化转型比较领先的工厂和制造企业,回来就甩给我几张图,问能不能我们也做几个这…...
【光伏功率预测】基于EMD-PCA-LSTM的光伏功率预测模型(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
大数据Kylin(二):Kylin安装使用
文章目录 Kylin安装使用 一、Kylin安装要求 二、Kylin安装 1、Kylin安装前环境准备...
我们的微服务中为什么需要网关?
说起 Spring Cloud Gateway 的使用场景,我相信很多小伙伴都能够脱口而出认证二字,确实,在网关中完成认证操作,确实是 Gateway 的重要使用场景之一,然而并不是唯一的使用场景。在微服务中使用网关的好处可太多了&#x…...
互联网医院源码 线上问诊 智慧医院源码 C#源码
互联网医院平台源码 智慧医院管理系统源码 开发环境:ASP.NET C# VS2019 SQL2008 依托于实体医院利用互联网技术对接院内业务信息系统,向患者提供基于线上问诊、预约挂号、缴费结算、医患互动、诊后随访、健康科普和复诊等全面的医疗健康互联网服务。…...
基于昇腾计算语言AscendCL开发AI推理应用
01 初始AscendCL AscendCL(Ascend Computing Language,昇腾计算语言)是昇腾计算开放编程框架,是对底层昇腾计算服务接口的封装,它提供运行时资源(例如设备、内存等)管理、模型加载与执行、算子…...
JS document.write()换行
换行效果: 通过传递多个参数,即可实现换行效果: document.write("<br>",ar) 效果: 示例源码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8&quo…...
Java高级-集合-Collection部分
本篇讲解java集合 集合 集合框架的概述 集合、数组都是对多个数据进行存储操作的结构,简称Java容器。 说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt,.jpg,.avi,数据库中…...
Android性能优化:getResources()与Binder交火导致的界面卡顿优化
欢迎:https://juejin.cn/post/7198430801851531324/ 欢迎:https://nasdaqgodzilla.github.io/2023/02/10/Android%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%EF%BC%9AgetResources-%E4%B8%8EBinder%E4%BA%A4%E7%81%AB%E5%AF%BC%E8%87%B4%E7%9A%84%E7%95%8C%E…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...














