Linux环境基础开发工具->gcc/g++

article/2025/9/6 20:30:21

引入:gcc/g++是什么?

在上篇博客我们知道,vim是一个编辑器,vim负责的是代码的编辑;而gcc/g++是一个编译器,负责的就是代码的编译!gcc负责C语言代码的编译,而g++负责c++代码的编译!

既然是编译,那就要先看这个链接一下编译器的工作分为哪几个步骤:编译链接的过程发生了什么?_编译链接 发生了什么-CSDN博客

注:本篇博客着重讲gcc,因为g++和gcc类似,不再赘述

一:快速使用gcc和g++

现在有一个.c文件,其内容如下:

我们对其进行gcc编译,生成了a.out:

对其进行执行:

以上就是使用gcc,非常的简单!

用起来非常简单,但其中的内容其实很多,只是我们gcc指令直接一步到位了,gcc是一个编译器,博主在此篇博客中介绍过编译的整个过程:编译链接的过程发生了什么?_编译链接 发生了什么-CSDN博客

总的来说在执行编译的时候一般有以下四个步骤


1)预处理(头文件展开、去注释、宏替换、条件编译)。
2)编译(C代码翻译成汇编语言)。
3)汇编(汇编代码转为二进制目标代码)。
4)链接(将汇编过程产生的二进制代码进行链接)。

每步对应的工作如下:

 

而gcc直接从一个.c文件 到了可执行文件,上面的这四步其隐式的执行了,所以我们要结合gcc的选项才能够才不同的时期停下来

二:gcc的选项

须知:

-o:将处理结果输出到指定文件,该选项后需紧跟输出文件名;所以-o也是gcc的选项,一般放在两个文件之中!

1:gcc -E(预处理)

用法:

gcc -E code.c -o code.i

解释:从现在开始对code.c文件进行翻译,当对code.c文件做完预处理工作的时候,就停下来,此时生成的文件我把他命名为code.i 。

如图:

此时我们vim进入code.i :会发现其有800多行

解释:预处理进行了多个工作,主要包括头文件展开、去注释、宏替换、条件编译等,而其中的头文件展开就是导致突然有800多行的原因;至于去注释、宏替换,可以自己在.c中写一个宏替换和注释,会发现预处理之后,注释被去掉了、宏被替换了!

至于条件编译的话,博主在上文提到的博客中没有说到,现在进行补充:

Q:条件编译是什么?

A:举个例子

现在我们创建了一个新的file.c,其内容如下:

此时直接gcc是会报错的,因为x是未定义的变量,但是却被使用,但是我们执行以下指令的时候:

gcc file.c -D x=1

解释:gcc 编译file.c文件并同时定义宏 x=1 ,所以我们现在就会生成一个a.out文件,我们对其执行一下,会发现其成功运行了:

这就是一种简单的条件编译,目前我们需了解条件编译的例子有两个:

①:在我们使用软件的时候,一些软件有专业版和社区版 ,本质就是条件编译起到的作用,让社区版的功能和专业版有所区别;

②:我们的头文件在写出来的时候 其实前后都是有条件编译的,一个头文件只有在第一次写的时候,才会被定义,后面在一个源文件中的重复包含头文件,均会被条件编译省略

2:gcc -S(编译)

用法:

gcc -S code.i -o code.s

解释:从现在开始对code.i文件进行翻译,当对其的编译工作做完的时候,就停下来。此时生成的文件我把他命名为code.s 

注意:可以对code.c进行操作,也可以对预处理之后的code.i进行操作,自由选择

如图:我们gcc -S后生成了code.s

此时我们vim进入code.s:

 

解释:编译这一步进行的工作是->首先检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,将代码翻译成汇编语言所以我们vim进入看见的都是会汇编语言!


 

3:gcc -c(汇编)

用法:

gcc -c code.s -o code.o

解释: 从现在开始对code.s文件进行翻译,当对其的汇编工作做完的时候,就停下来。此时生成的文件我把他命名为code.o 

 

如图:

 

此时我们vim进入code.o:

解释:汇编阶段是把编译阶段生成的 .s 文件转成目标 .o 文件,此时的.o文件中内容都是汇编代码转化为的二进制目标代码了。

但是此时的.o文件虽然是一个目标文件,但是叫作可重定位目标二进制文件,其是不可执行的

 

验证其不可执行:

对.o文件进行./执行:

Q:虽然演示出了不可执行,但是这.o文件对于wtt1来说没有x权限,有x权限应该能执行了?

A:好的,对wtt1增加x权限:

 

还变绿了,感觉真的行哦~

 

解释:依旧不行!报错 :无法执行二进制文件,所以这就证明了汇编生成的目标文件不能执行,因为我们少了链接这一步!需要链接到库,才能够形成可执行文件!

4:链接

链接无选项,用法:

gcc code.o

这样默认生成的就是a.out的可执行文件,我们也可以用-o选项命名的选择:

gcc code.o -o code.out

 

如图:

 

 解释:

  • 链接的主要任务就是将生成的各个 .o 文件进行链接,生成可执行文件。
  • gcc/g++不带-E、-S、-c选项时,就默认生成预处理、编译、汇编、链接全过程后的文件。
  • 若不用-o选项指定生成文件的文件名,则默认生成的可执行文件名为a.out。

 

此时我们vim进入code.out:

解释: 链接后生成的也是二进制文件。因为计算机只认识二进制
 

Q:你这链接之后,我感受不到变化啊,有什么什么办法让我感受一下链接体现在哪?

A:要查看一个文件是否链接了,有ldd指令和file指令两种方法

①:ldd

ldd指令即可,ldd指令用于打印可执行文件或共享库所依赖的动态链接库(.so 文件)

对比一下code.out和code.o 对于ldd指令的区别:

解释:信息说明了我们的code.out文件的确是链接到了库!(图中的/lib64/libc.so.6就是当前云服务器当中的C标准库)。

②:file

解释:dynamically linked 意味着动态链接

那库有类别吗?难道还有静态链表吗?

三:动态库和静态库

1:库的类别及优缺点

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

①:静态库是指编译链接时,把库文件的代码全部加入到可执行文件当中,因此生成的文件比较大,但在运行时也就不再需要库文件了,静态库一般以.a为后缀。


②:动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件当中,而是在程序运行时由链接文件加载库,这样可以节省系统的开销,动态库一般以.so为后缀。

动态链接:
 优点:省空间(磁盘的空间,内存的空间),bin体积小,加载速度快。
 缺点:依赖动态库,程序可移植性较差。

静态链接:
 优点:不依赖第三方库,程序的可移植性较高。
 缺点:浪费空间。

2:动态链接

Q:那我们写的.c 和 .cpp文件进行连接的时候,是采取那哪一种?

A:file指令就能知道

 解释:dynamically linked 意味着动态链接

3:静态链接

我们还可以强行对code.o文件进行静态链接到库,指令:gcc -static

注:当然也可以直接对code.c进行强行的静态链接,自由选择即可

gcc code.o -o code.out_static -static

我们静态链接生成的可执行文件取名为 code.out_static,方便区别于code.out

此时我们就有两个可执行文件了:

解释:由静态链接的缺点可知,静态链接是把库文件的代码全部加入到可执行文件当中,所以这就是为什么我们的code.out_static的大小是861288,远远大于code.out的原因!

我们可以通过ldd来查看code.out_static是否真的被静态链接了:

解释: 信息告诉我们:这个程序是静态链接的,没有依赖任何动态库(.so 文件),因此无法列出动态库依赖关系;所以这正好说明了的确进行了静态链接

再通过file来看一下code.out_static:

解释:statically linked 意味着静态链接

总结:Linux中的编译器gcc和g++默认都是动态链接的!

四:一些细节

1:巧记选项后后缀

Q:你上面的-E -S -c 选项;和 -E生成的.i ,-S生成的.s,以及-c生成的.o 文件,怎么记忆?

A:Esc就是我们键盘上的返回键,对应的就是预处理,编译,汇编,只需记住c小写即可;而iso三个字母对应的就是预处理,编译,汇编生成的文件后缀,我不喜欢ios系统,所以它叫iso

2:指定输出文件的重要性

注意:

-E一定会生成一个.i文件,所以我们一般指定写生成的.i文件的前缀,.s 文件和 .o 文件也是类似的道理!但其实其中的-E预处理比较特殊:

  • 如果不指定输出文件,预处理后的代码会直接输出到 标准输出(屏幕),而 不会自动生成 .i 文件

而其余的编译,汇编都会直接生成文件,而不是输出到标准输出(屏幕)!

3:gcc对后缀的要求

我们平时使用gcc,一般是对文件直接编译成可执行文件,但需要注意的是,我们编译的文件一定要是.c文件!

gcc hello.txt  # 默认会失败,因为 GCC 根据后缀名调用处理工具


http://www.hkcw.cn/article/JLdXdHapeA.shtml

相关文章

云原生与DevOps融合实践:加速企业数字化转型的加速器

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:为什么“云原生DevOps”是当下最强组合? 在传统软件交付模式逐步被淘汰的当下,越来…

孙颖莎王曼昱出战WTT美国站女双 拉斯维加斯再携手

2025年WTT美国大满贯将于7月3日至13日在拉斯维加斯奥尔良体育馆及美高梅大酒店会议中心举行。孙颖莎和王曼昱将搭档出战女双正赛。在不久前结束的多哈世乒赛女单决赛中,孙颖莎以4比3的大比分险胜王曼昱,成功卫冕。责任编辑:zx0176

基于51单片机和8X8点阵屏、独立按键的射击消除类小游戏

目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、8X8点阵屏2、独立按键3、定时器04、定时器1 四、主函数总结 系列文章目录 前言 使用的是普中A2开发板。 【单片机】STC89C52RC 【频率】12T11.0592MHz 【外设】8X8点阵屏、独立按键 效果查看/操作演示&#x…

ubuntu22.04安装docker

1. 准备工作 更新系统软件包索引 sudo apt update2. 卸载旧版本 Docker(可选) 清理旧版 Docker 及相关依赖 sudo apt-get remove docker docker-engine docker.io containerd runc3. 设置 Docker 仓库 安装依赖工具 (apt-transport-https, ca-certi…

burpsuit抓包完整示例

1.确保浏览器(这里使用的是火狐浏览器)和burpsuit配置完整(有需要留言),配置完整包括jdk安装,配置环境变量,下载burp,下载并导入证书,ip端口一致,代理能正常打开。 2.注意…

其他 | 边缘端应用的轻量级优化调研

1.调研目标 由于边缘计算场景的性能受限,无法提供与常规服务器相同或略低的环境,因此对我们的上层业务应用有着较高的资源要求。 目前我们的应用程序基于 Oracle JDK(开发者端)与 OpenJDK(生产环境)进行开…

Shell 脚本常用命令笔记

一、系统配置命令 1. 主机名设置 文件方式 修改文件:vim /etc/hostname,写入新主机名(如czg.easylee.org)。生效方式:需重新打开 Shell 或重启系统。 命令方式 即时生效命令:hostnamectl set-hostname 新…

不规则瀑布流布局拖拽重排序

因为业务,所以需要用flutter去实现一种不规则图形的瀑布流,但是同时需要支持拖拽并重新排序。效果类似如下。 查询过现有的插件,要么是仅支持同样大小的组件进行排序,要么就是动画效果不是很满意,有点死板,…

线程de安全性备忘

文章仅供学习参考 线程安全的本质定义 public class Counter {private int value 0; // 共享资源// 线程安全方法public synchronized void increment() {value; // 原子操作} }原子性(Atomicity):操作不可分割(如 synchroniz…

进行性核上性麻痹健康护理全指南:从症状管理到生活照护

进行性核上性麻痹(PSP)是一种罕见的神经退行性疾病,主要影响运动、平衡及眼球运动功能,常表现为步态不稳、吞咽困难、眼球上视受限、情绪改变等。由于目前尚无根治方法,科学的健康护理对延缓病情进展、提升患者生活质量…

[智能算法]蚁群算法原理与TSP问题示例

目录 ​编辑 一、生物行为启发的智能优化算法 1.1 自然界的群体智能现象 1.2 人工蚁群算法核心思想 二、算法在组合优化中的应用演进 2.1 经典TSP问题建模 2.2 算法流程优化 三、TSP问题实战:Python实现与可视化 3.1 算法核心类设计 3.2 参数敏感性实验 3.3 可视化…

安卓学习笔记-数据存储

阅读说明 本文是基于上一篇文章《安卓学习笔记-声明式UI》的后续。上篇文章实现了UI层以及业务逻辑层ViewModel的解耦。本篇关注的是数据存储层与业务逻辑层的解耦。 补充知识StateFlow 在 MVVM 架构中如何使用 Kotlin 协程的 StateFlow 来管理和暴露 UI 状态。 private va…

cutlass学习教程

一 接口 1.1 内存类 1.1.1 DeviceAllocation 1 位置 2 内置函数 (a)reset /// Deletes the managed object and resets capacity to zero void reset() {capacity 0;smart_ptr.reset(); } (b)get /// Returns a pointer to t…

自定义异常小练习

在开始之前,让我们高喊我们的口号: ​​​​​​​ 键盘敲烂,年薪百万! 目录 键盘敲烂,年薪百万! 异常综合练习: 自定义异常 异常综合练习: 自定义异常: 定义异常类写继承关系空参构造带参构造 自定…

计算机网络

OSI七层模型 应用层:直接为用户提供网络服务,例如网页浏览、邮件收发表示层:处理数据格式,如加密、解密、压缩、编码等会话层:利用传输层提供的服务,在应用程序之间建立和维持会话,并能使会话获…

【循环神经网络RNN第一期】循环神经网络RNN原理概述

目录 🧠 什么是循环神经网络(RNN)?🔁 RNN 的结构图🔄 RNN 的“记忆”与问题RNN梯度推导 🧬 LSTM:解决长期依赖问题🧱 LSTM 的核心结构LSTM总结 参考 人类在思考的时候&am…

自动驾驶与智能交通:构建未来出行的智能引擎

随着人工智能、物联网、5G和大数据等前沿技术的发展,自动驾驶汽车和智能交通系统正以前所未有的速度改变人类的出行方式。这一变革不仅是技术的融合创新,更是推动城市可持续发展的关键支撑。 一、自动驾驶与智能交通的定义 1. 自动驾驶(Auto…

5.3.1_2二叉树的层次遍历

遍历过程: 从根节点开始,从左到右一层一层遍历,如下:ABCDEFGHIJKL 初始化一个辅助队列,让根节点先入队,每次判断队列是否为空,不空则让队头节点出队访问该节点让该节点左右孩子入队尾(先左孩子…

Qt DateTimeEdit(时间⽇期的微调框)

使⽤ QDateEdit 作为⽇期的微调框. 使⽤ QTimeEdit 作为时间的微调框 使⽤ QDateTimeEdit 作为时间⽇期的微调框. 这⼏个控件⽤法⾮常相似, 我们以 QDateTimeEdit 为例进⾏介绍. QDateTimeEdit 核⼼属性 属性说明dateTime时间⽇期的值. 形如 2000/1/1 0:00:00date单纯⽇期…

NISCO里境全新VALUE系列合肥首店启幕,携手正反设计打造0压生活空间

2025年5月28日,NISCO里境全新VALUE系列全国首家旗舰店正式落子合肥,梦百合集团近三十位核心经销商代表齐聚,深度体验新系列门店的空间场景与创新产品矩阵。 作为品牌“双线并进”的重要布局,VALUE系列以高性价比为核心,聚焦二三线城市消费需求,通过沉浸式空间场景与革新性产品设…