Linux 学习之路 -- 工具篇 -- gcc / g++

在 Linux 系统中,gccg++ 是两个常用的编译工具,分别用于编译 C 和 C++ 代码。下面我将介绍gcc、g++的一些基本用法

目录

一、简单的认识

二、简单了解一下编译的过程             

<1> 预处理阶段 

<2>编译

<3>汇编

<4>链接

三、分别介绍编译过程

<1>预处理                                                                 

<2>编译

<3>汇编

<4> 链接

<5>简单介绍一下动静态库


一、简单的认识

如果没有gcc / g++ ,用yum 安装一下即可。

下面先简单举个例子帮助理解

这里我先创建一个test.c文件(这里最好还是带后缀,不然gcc / g++是无法识别的)。

然后再退出vim , 通过gcc 命令编译该文件,形成一个新的可执行文件

这里系统会默认生成a.out的可执行文件,(如果想要修改可执行文件名,使用gcc -o 源文件 + 要生成的可执行文件名,这里gcc 后面的顺序是可以随意的,但是新的文件名要紧跟在 -o 后面)再用./a.out执行该命令。

(这里我忘记加换行符号,不好意思) ,如果我们用vim 打开这个可执行文件,会发现里面的东西我们看不懂,可执行文件是给cpu 执行的,而cpu 只认二进制的代码,所以我们的可执行文件就得是二进制的,我们的高级语言只是提高了编译的速度,并没有改变底层的原理。

另外一个需要注意的点就是,gcc 只能编译C语言的代码,g++可以编C语言跟C++的代码。             

二、简单了解一下编译的过程             

<1> 预处理阶段 

 1.头文件展开                                                                                                                                           头文件展开其实就是把 c / c++ 头文件中需要的部分拷贝到当前的文件当中。

2. 去注释

        顾名思义,就是去掉代码中的注释

3.宏替换

        将宏代码替换

4.条件编译

        把条件通过的代码进行编译

在预处理后,文件里的代码还是C或C语言

<2>编译

把C / C++ 转成汇编代码

<3>汇编

把汇编转成二进制文件,这个二进制文件又叫可重定位二进制文件,这个文件是不能被执行的

<4>链接

三、分别介绍编译过程

程序的翻译一次性就会把上述的所有动作完成,所以我们就要通过不同的选项进行编译,形成特定的文件。

<1>预处理                                                                 

这里我们可以使用-E选项编译文件,形成预处理完后的文件,(下面我选择的都是test.c 文件进行编译)

退出后,我们实行gcc -E test.c 命令,发现系统默认就会把预处理后文件内容全打印到屏幕上,这对于我们观察非常不方便,所以我们可以使用gcc -E test.c -o test.i 这里我们将test.c 预处理形成的文件打包形成一个test.i 的临时文件。一般来说,这里的临时文件一般就是把原文件名的后缀改成.i ,表示是预处理后形成的文件。

实行上述命令后,我们打开test.i 文件。我们可以发现文件多出来了很多的代码,这些代码其实就是stdio.h这个头文件里面的内容拷贝到test.i 这个文件里面,而这个过程就叫作头文件展开,包括一些注释也被去掉了,这里其实就是把去注释的过程。

这里我们再加入条件编译,看看预处理后的文件内容。

这里我们先写一段带条件编译的代码

然后我们退出去,用gcc -E a.cpp -o 1.cpp -D vscode2=2 (-D 其实就是定义一个宏,并且在编译器处理源代码之前处理,把这个宏插入进去)。打开1.cpp 这个临时文件,跳到最后几行

我们可以发现,只有条件编译通过的代码才被保留,其余的都被删除了,所以我们可以给编译器传不同的宏值,来对代码进行动态的裁剪。

<2>编译

编译过程其实就是把C语言代码转成汇编代码(其他语言也是差不多),我们可以用-S 选项,这个选项就是把从开始进行程序的翻译当编译工作做完,就停下来。这里我用test.i 这个文件来演示一下,我们可以用gcc -S test.i -o test.s  来形成一个test.s 的文件。

打开这里我们就可以看见,这里的代码全变成了汇编代码。

<3>汇编

就是把汇编的代码转成二进制文件,这里我们可以用-c 选项来实现该操作,这里我用 gcc -c test.s -o test.o 形成一个test.o文件(这里的o, 代表的是obj文件的缩写,也就是目标文件),这里我们运行一下命令,运行完后打开文件。

这里我们会发现,文件内容没法阅读,这是因为文件是二进制文件,但是vim是文本编辑器。所以会有这种情况的出现。正常来说文件内容已经是二进制,就应该能被执行,但是我们却执行不了(哪怕我们给它加上可执行权限)。

这是因为二进制文件里面有非常多的函数声明,我们必需要链接到库里面找到对应的函数,才能使文件变成可执行文件。

<4> 链接

我们先用gcc test.o -o  test 形成一个叫test的可执行文件,我们可以用ldd 文件来查看可执行文件所依赖的库。这里的库一般分为静态库和动态库,在不同的系统库文件后缀不同

Linuxwindows
动态库.so.dll
静态库.a.lib

这里我们用ldd 命令查看文件所依赖的库

这里我们依赖的库就是C标准库,这里我们的系统也是将C语言一些头文件和库下载好了,所以我们能就能再linux 中就能用C进行开发的原因 (安装环境其实也就是安装这些库跟头文件)。

用ls /lib64* 命令,查看当前系统下的相关库

<5>简单介绍一下动静态库

动静态库本质上也是文件,但是两者是有区别的(使用动态链接)

动态库就是被多个使用者共享使用,一旦缺失所有的用户都无法使用(使用静态链接)。

静态库就是把自己需要的文件拷到可执行文件中。

动态库静态库
优点比较节省资源,不会有很多的重复代码 -- 这里的资源包括磁盘资源,内存,网络等等不依赖库,同类型平台中可以直接运行使用
缺点对库的依赖性比较强,一但库丢失,所有使用这个库的文件都将无法运行可执行程序的体积较大,比较费资源

这里就不多介绍了,后面文件部分再详细介绍

以上就是全部内容,希望对各位读者有些许帮助。文中如有不当之处,还望各位大佬指正,谢谢!!!

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

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

相关文章

Redis慢日志

SLOWLOG 是用来读取和重置 Redis 慢查询日志的命令&#xff0c;Redis 2.2.12 版本开始支持 1.Redis 慢查询日志概述 客户端从发送命令到获取返回结果经过了以下几个步骤&#xff1a; 1. 客户端发送命令 2. 该命令进入 Redis 队列排队等待执行 3. Redis 开始执行命令 - Red…

飞天使-k8s知识点28-kubernetes散装知识点5-helm安装ingress

文章目录 安装helm添加仓库下载包配置创建命名空间安装 安装helm https://get.helm.sh/helm-v3.2.3-linux-amd64.tar.gztar -xf helm-v3.2.3-linux-amd64.tar.gzcd linux-amd64mv helm /usr/local/bin修改/etc/profile 文件&#xff0c;修改里面内容,然后重新启用export PATH$P…

嵌入式数据库-Sqlite3

阅读引言&#xff1a; 本文将会从环境sqlite3的安装、数据库的基础知识、sqlite3命令、以及sqlite的sql语句最后还有一个完整的代码实例&#xff0c; 相信仔细学习完这篇内容之后大家一定能有所收获。 目录 一、数据库的基础知识 1.数据库的基本概念 2.常用数据库 3.嵌入式…

在A中删除既在B表中出现又在C表中出现的元素

方法一&#xff08;感觉有点取巧&#xff0c;不太推荐&#xff0c;但是实现简单&#xff09;&#xff1a; 算法思想:保留La的头节点&#xff0c;并用pcur指针指向La链中的第一个结点&#xff0c;通过pcur指针遍历La中的每一个元素&#xff0c;并判断该元素是否在Lb和Lc链中出现…

优化选址问题 | 基于帝国企鹅算法求解工厂-中心-需求点三级选址问题含Matlab源码

目录 问题代码问题 "帝国企鹅算法"并不是一个广为人知的优化算法,可能是一个特定领域或者特定情境下提出的方法。不过,对于工厂-中心-需求点三级选址问题,它可能是一种启发式优化方法,用于在多个候选位置中选择最优的工厂、中心和需求点位置。 这类问题通常涉及…

HAL STM32 硬件I2C方式读取AS5600磁编码器获取角度例程

HAL STM32 硬件I2C方式读取AS5600磁编码器获取角度例程 &#x1f4cd;相关篇《STM32 软件I2C方式读取AS5600磁编码器获取角度例程》 ✨stm32使用硬件I2C去读取角度数据&#xff0c;通过STM32CubeMX工具配置工程&#xff0c;读取角度数据&#xff0c;只需要调用一个函数&#xf…

css3之动画animation

动画animation 一.优点二.定义和使用三.动画序列和解释四.常见属性及解释五.简写&#xff08;名字和时间不能省略&#xff09;&#xff08;持续时间在何时开始的时间前&#xff09;&#xff08;简写中无animation-play-state)六.例子1.大数据热点图2.奔跑的熊大&#xff08;一个…

大模型与数据分析:探索Text-to-SQL

当今大模型如此火热&#xff0c;作为一名数据同学&#xff0c;持续在关注LLM是如何应用在数据分析中的&#xff0c;也关注到很多公司推出了AI数智助手的产品&#xff0c;比如火山引擎数智平台VeDI—AI助手、 Kyligence Copilot AI数智助理、ThoughtSpot等&#xff0c;通过接入人…

同一个主机配置多个SSH key

使用git时&#xff0c;我们可能一个git客户端使用多个git服务器&#xff0c;比如github&#xff0c;自建gitlab&#xff0c;gitee&#xff0c;为了防止提交混乱&#xff0c;所以需要一一对应生成公私钥。 第一步&#xff1a; 使用ssh-keygen生成多对密钥对&#xff0c;比如&…

深入理解SQLite:存储引擎、索引、事务与锁

文章目录 一、存储引擎二、索引的数据结构和类型2.1 B-Tree2.2 其他类型的索引2.3 小结 三、事务处理中的一致性问题3.1 脏读&#xff08;Dirty Read&#xff09;3.2 不可重复读&#xff08;Non-repeatable Read&#xff09;3.3 幻读&#xff08;Phantom Read&#xff09;3.4 小…

python实战之进阶篇(二)

一. python中的继承 二. 多继承 如果一个类继承了多个类, 多个父类中有相同的方法, 相同的方法则按照继承的顺序,继承第一个父类的 如果子类重写父类中继承的方法, 则子类中重写的方法生效 三. 继承与多态

数据结构03:栈、队列和数组 栈习题01[C++]

考研笔记整理~&#x1f95d;&#x1f95d; 之前的博文链接在此&#xff1a;数据结构03&#xff1a;栈、队列和数组_-CSDN博客~&#x1f95d;&#x1f95d; 本篇作为链表的代码补充&#xff0c;供小伙伴们参考~&#x1f95d;&#x1f95d; 第1版&#xff1a;王道书的课后习题…

ubuntu22.04@Jetson Orin Nano安装配置VNC服务端

ubuntu22.04Jetson Orin Nano安装&配置VNC服务端 1. 源由2. 环境3. VNC安装Step 1: update and install xserver-xorg-video-dummyStep 2: Create config for dummy virtual displayStep3: Add the following contents in xorg.conf.dummyStep 4: Update /etc/X11/xorg.con…

使用Flink实现MySQL到Kafka的数据流转换

使用Flink实现MySQL到Kafka的数据流转换 本篇博客将介绍如何使用Flink将数据从MySQL数据库实时传输到Kafka&#xff0c;这是一个常见的用例&#xff0c;适用于需要实时数据connector的场景。 环境准备 在开始之前&#xff0c;确保你的环境中已经安装了以下软件&#xff1a;…

再次加深理解Java中的并发编程

目录 一、线程、进程、程序 二、线程状态 三、线程的七大参数 四、lock与synchronized锁机制 一&#xff09;、lock与synchronized锁区别 二&#xff09;、synchronized锁原理 三&#xff09;、Lock锁原理 五、synchronized锁升级原理 一&#xff09;、锁升级基础知识 …

超文本传输协议HTTP

HTTP协议 在网络通信中&#xff0c;我们可以自己进行定制协议&#xff0c;但是也有许多已经十分成熟的应用层协议&#xff0c;比如我们下面说的HTTP协议。 HTTP协议简介 HTTP&#xff08;Hyper Text Transfer Protocol&#xff09;协议又叫做超文本传输协议&#xff0c;是一…

JAVAEE之网络编程

1.网络编程 网络编程&#xff0c;指网络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的方式实现网络通信&#xff08;或称为网络数据传输&#xff09;。 当然&#xff0c;我们只要满足进程不同就行&#xff1b; 所以即便是同一个主机&#xff0c;只要是不同进程&am…

算法学习——LeetCode力扣图论篇1

算法学习——LeetCode力扣图论篇1 797. 所有可能的路径 797. 所有可能的路径 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一个有 n 个节点的 有向无环图&#xff08;DAG&#xff09;&#xff0c;请你找出所有从节点 0 到节点 n-1 的路径并输出&#xff08;不要求按特…

elementui 导航菜单栏和Breadcrumb 面包屑关联

系列文章目录 一、elementui 导航菜单栏和Breadcrumb 面包屑关联 文章目录 系列文章目录前言一、elementui 导航菜单栏和Breadcrumb 面包屑怎么关联&#xff1f;二、实现效果三、实现步骤1.本项目演示布局2.添加面包屑2.实现breadcrumbName方法3.监听方法4.路由指配5.路由配置…

【C语言】Infiniband驱动mlx4_reset

一、注释 这个 mlx4_reset 函数负责重置 Mellanox 设备。它保存了设备的 PCI 头信息&#xff0c;然后重置了设备&#xff0c;之后还原保存的 PCI 头信息。请注意&#xff0c;该函数是用英文注释的&#xff0c;下面提供中文注释的版本。以下是该函数的流程&#xff1a; 1. 为保…