『Linux升级路』基础开发工具——gcc/g++篇

🔥博客主页:小王又困了

📚系列专栏:Linux

🌟人之为学,不日近则日退 

❤️感谢大家点赞👍收藏⭐评论✍️


目录

一、快速认识gcc/g++

 二、预处理

📒1.1头文件展开 

📒1.2条件编译

二、编译

三、汇编

四、链接

📒4.1库的概念

📒4.2库的特点

📒4.3库的分类

📒4.4动态链接

📒4.5静态链接


🗒️前言:

    在前面的文章中我们学会了vim的用法,可以写一些代码,要想让我们的代码运行起来,还需要我们学会编译工具gcc、g++的使用。C语言既可以使用gcc,也可以使用g++;C++只能使用g++,它们的使用形式是相同的,今天以gcc为主,介绍它们的使用方法,带大家快速上手。

一、快速认识gcc/g++

     当我们写完一段代码,想要编译时可以在命令行输入:gcc code.c,会默认形成a.out的可执行程序。

在输入./a.out,程序就可以执行起来了。

     当我们不想形成默认的可执行,想让它形成指定名称的可执行,可以输入:gcc code.c -o mycode gcc -o mycode code.c

编译主要分为预处理、编译、汇编、链接四个过程,我们将详细讲解这四个过程,带大家学会gcc的使用。

 二、预处理

     此阶段处理以 .c .cpp 为扩展名的源文件,并执行预处理指令。预处理器的主要任务是头文件展开条件编译、展开宏定义、移除注释等。预处理指令都是以#开头的代码行。

  • 指令:gcc -E code.c -o code.i
  • -E:从现在开始进行程序的翻译过程,当预处理做完的时候就停止
  • -o:指目标文件,将当前编译结果写入到code.i文件中 
  •  .i 文件为经过预处理的C语言程序(还是C语言)

📒1.1头文件展开 

     头文件展开,就是在预处理的时候,将头文件拷贝到引用它的源文件中。通过上图我们可以看到,原本14行的代码经过预编译变成了850行。多出的这么多代码,就是把stdio.h文件中的内容插入到当前源文件中。/usr/include/目录是Linux下gcc/g++头文件的默认搜索路径,该路径下有许多和开发相关的头文件。

头文件的展开过程涉及到#include预处理指令。当预处理器遇到#include指令时,它会打开指定的头文件并将其内容插入到当前源文件的位置。这个过程可以分为两种类型的包含:

  • 系统头文件的包含:

使用尖括号<>包含系统头文件,例如:

#include <stdio.h>

预处理器会在系统头文件目录中查找并打开stdio.h文件,并将其内容插入到当前源文件中。

  •  用户头文件的包含:

 使用双引号 “ ” 包含用户定义的头文件,例如:

#include “test.h”

预处理器会在当前源文件所在目录以及指定的包含路径中查找并打开test.h文件,并将其内容插入到当前源文件中。

📒1.2条件编译

     条件编译就是处理条件编译指令,如#if#ifdef#ifndef#else#elif#endif等。根据条件判断是否编译特定代码块。例如:

#ifdef identifier// 代码块 A
#else// 代码块 B
#endif

如果已经定义了标识符identifier,则编译 // 代码块 A 部分,否则编译 // 代码块 B 部分。

     条件编译最重要的意义就是对头文件的保护,防止头文件被重复包含。

#ifndef HEADER_FILE
#define HEADER_FILE// 头文件内容#endif

在展开头文件时,预处理器会继续递归地处理被包含的头文件。这意味着如果一个头文件包含了另一个头文件,那么这个被包含的头文件也会被展开,以此类推,直到所有的头文件都被插入到源文件中。我们使用上面这段条件编译的代码就可以避免这种情况,如果没有定义HEADER_FILE,就执行下面的代码;如果定义了,就不会执行了。

📝条件编译的主要用途包括: 

  • 平台特定代码: 通过条件编译,可以根据不同的操作系统或硬件平台编写特定的代码。

  • 调试和发布版本: 可以使用条件编译来在调试版本和发布版本之间切换代码。

  • 特定功能的开关: 通过条件编译,可以选择性地包含或排除某些功能,以满足特定的编译需求。

  • 配置选项: 根据不同的配置选项选择性地包含或排除代码,以适应不同的编译环境

二、编译

     在这个阶段,预处理后的源代码(通常是.i文件)被翻译成汇编语言。gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。生成的汇编代码描述了程序的控制流、数据等信息。

  • 指令:gcc -S code.i -o code.s
  • -S:从现在开始进行程序的翻译过程,当编译工作做完的时候就停止

三、汇编

     在这个阶段,汇编器将汇编代码(通常是.s文件)翻译成机器码或可重定位的机器码。它将汇编代码转换成二进制目标文件,其中包含特定于处理器体系结构的指令。这个二进制文件也被叫做可重定位目标二进制文件,简称目标文件。但是它不能被执行。

  •  指令:gcc -c code.s -o code.o
  • -c:从现在开始进行程序的翻译过程,当汇编工作做完的时候就停止

📝目标文件为什么不能执行?

     目标文件通常没有定义程序的入口点,即程序的起始地址。可执行文件需要一个明确定义的入口点,从这个点开始执行程序。单独的目标文件可能包含了未解决的符号引用,无法独立执行。可执行文件需要在操作系统上运行,而操作系统提供了运行时支持,包括内存管理、文件操作、进程调度等。没有这些支持,程序很难在操作系统上正确运行。所以,我们还要通过链接来解决这些问题,让目标文件与其他目标文件或库文件进行链接,形成最终的可执行文件。

四、链接

     在这个阶段,链接器将一个或多个目标文件(通常是.o文件)与所需的库文件结合,创建可执行文件。链接的主要任务包括符号解析、地址解析、重定位等,以确保所有部分正确地组合在一起。

  • 指令:gcc  code.o -o mycode

📒4.1库的概念

     库通常指的是包含可重用代码和资源的集合,目的是为了帮助开发者完成特定任务。库可以包含函数、类、变量、子例程等,提供了一组API(应用程序接口)或者工具,使得开发者能够更轻松地完成常见的编程任务,而无需从头开始编写所有的代码。

     我们的C程序中,并没有定义printf的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现printf函数的呢? 答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc会到系统默认的搜索路径/usr/lib下进行查找,会默认找到C的标准库,它会把我们写的源代码经过编译得到的目标文件与库文件进行链接,也就是链接到 libc.so.6 库函数中去,这样就能实现函数printf了,而这也就是链接的作用。

  •  libc.so.6 就是C语言的标准库。 

📒4.2库的特点

  1. 可重用性: 库中的代码可以在不同的程序中被重复使用,从而减少了代码的冗余,提高了开发效率。

  2. 封装性: 库提供了一个封装的接口,隐藏了内部实现的细节,使得开发者可以专注于使用功能而不必关心底层的实现。

  3. 模块化: 库通常被组织成模块,每个模块负责一个特定的功能。这种模块化的设计有助于提高代码的可维护性和可扩展性。

  4. 标准化: 一些库成为了编程的标准,被广泛接受和使用。这样的库通常提供了一些通用的解决方案,被广泛认可并得到社区的支持。

📒4.3库的分类

     库分为两类:动态库静态库。其中Linux环境下,动态库的后缀是.so,静态库的后缀是.a。在Windows环境下,动态库的后缀是.dll,静态库的后缀是.lib。所有的库文件,都遵守相同的命名规则,即:libname.后缀.xxx

  • 静态库(Static Library): 在编译时被链接到程序中,程序在运行前就包含了库的代码。这意味着库的代码被复制到了程序的可执行文件中。

  • 动态库(Dynamic Library): 在运行时被加载到内存中,程序在运行时可以调用库的函数。这样可以减小程序的大小,因为多个程序可以共享同一个库的实例。

 常见的库包括标准库(如C标准库、C++标准库)、图形界面库(如Qt、GTK+)、数学库(如NumPy)、网络库(如libcurl)、以及许多其他领域的专用库。

📒4.4动态链接

     动态链接是一种在程序运行时将代码和数据库链接到程序中的技术。把库中要用到的库函数的地址写到在我们代码中调用这个函数的地方,就是动态链接。

  • 指令ldd 可执行程序,可以查看一个可执行程序所依赖的动态库。

gcc的默认行为是动态链接 

🎀动态链接的优点:

  • 节省内存: 多个程序可以共享同一份库的实例,从而节省内存。
  • 易于更新: 更新库时,不需要重新编译所有依赖于该库的程序。只需替换库的新版本即可。
  • 灵活性: 可以在程序运行时动态加载和卸载库,使得程序更加灵活。

🎀 动态链接的缺点:

  • 依赖性:对库的依赖性强 一旦库丢失,所有使用这个库的程序都无法运行

📒4.5静态链接

     静态链接是一种在程序编译时将所有代码和库链接到一个独立的可执行文件的过程。这意味着在程序运行之前,所有的代码和库已经被合并成一个单独的可执行文件。把库中的代码拷贝到我们的可执行程序中,就是静态链接。

在Linux中默认是没有静态库的,需要我们自己安装。

  • sudo yum install -y glibc-static 
  • gcc code.c -o mycode-static -static
  • 其中 -static表示执行静态链接

🎀静态链接的优点:

  • 独立性: 生成的可执行文件是完全独立的,不需要外部的依赖。这使得程序更容易分发和部署,因为用户只需要一个文件就可以运行程序。
  • 性能: 静态链接的程序在运行时无需进行额外的库加载,因此在一些情况下可能会稍微快于动态链接的程序。

🎀静态链接的缺点:

  • 占用空间: 由于每个可执行文件包含了所需的所有代码和库,因此静态链接的程序通常比动态链接的程序更大。
  • 更新困难: 如果库被更新,需要重新编译并重新分发整个可执行文件,而不仅仅是替换库文件。

本次的内容到这里就结束啦。希望大家阅读完可以有所收获,同时也感谢各位读者三连支持。文章有问题可以在评论区留言,博主一定认真认真修改,以后写出更好的文章。你们的支持就是博主最大的动力。

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

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

相关文章

java字符串的常见用法

java字符串的常见用法 Java中的字符串是一个非常常用的对象&#xff0c;它属于Java的内置类String类的实例。字符串在Java中是不可变的&#xff0c;即一旦创建了一个字符串对象&#xff0c;就不能修改它的值。 下面是一些关于Java字符串的详细用法&#xff1a; 1&#xff09;创…

从零开始,用Docker-compose打造SkyWalking、Elasticsearch和Spring Cloud的完美融合

&#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 "从零开始&#xff0c;用Docker-compose打造SkyWalking、Elasticsearch和Spring Cloud的完美融合 前言准备工作编写docker-compose.yml文件为什么使用本机ip为什么skywa…

代码随想录-刷题第六天

242. 有效的字母异位词 题目链接&#xff1a;242. 有效的字母异位词 思路&#xff1a;哈希法。利用数组来记录出现的字母个数&#xff0c;然后判断是否为字母异位词。 时间复杂度&#xff1a;O(n) class Solution {public boolean isAnagram(String s, String t) {int[] co…

【云备份】第三方库的认识与使用

文章目录 json库粗略认识详细认识writer 类reader类jsoncpp序列化实现jsoncpp反序列化实现 bundle文件压缩库简单认识bundle库实现文件压缩bundle库实现文件解压缩 httplib库Request类Response类Server类Client类 json库 粗略认识 json是一种数据交换格式&#xff0c;采用完全…

激光切割设备中模组的作用有哪些?

激光切割设备是一种高精度的自动化加工设备&#xff0c;用于对金属、非金属等材料进行精确切割。直线模组作为激光切割设备的重要组成部分&#xff0c;在激光切割设备中起着重要的作用&#xff0c;为设备的运动系统提供了高精度、高稳定性和高效率的运动控制。 1、高精度的位置…

excel单元格加背景颜色不生效?

如果在 Excel 中设置单元格背景颜色而发现不生效&#xff0c;可能有几个原因。以下是一些常见的解决方法&#xff1a; 1. **单元格锁定&#xff1a;** 检查所在单元格是否被锁定。如果单元格被锁定&#xff0c;并且工作表被保护&#xff0c;你可能无法更改其背景颜色。在工作表…

mysql 优化器的AST树是啥

from ChatGPT: MySQL中的优化器&#xff08;optimizer&#xff09;使用AST&#xff08;Abstract Syntax Tree&#xff0c;抽象语法树&#xff09;来表示查询的语法结构。AST是一种树状结构&#xff0c;它反映了查询语句的语法层次&#xff0c;是一个抽象表示&#xff0c;用于更…

Linux - 文件系统 - 理解目录 - 理解 软/硬链接

前言 在上篇博客当中&#xff0c;我们对 文件系统 和 inode 做了初步了解&#xff0c;本博客将在上篇博客的基础之上&#xff0c;对于 文件系统当中的目录进行进步一阐述。 Linux - 进一步理解 文件系统 - inode - 机械硬盘-CSDN博客 目录 一个文件有一个 inode&#xff0c;…

Redis打包事务,分批提交

一、需求背景 接手一个老项目&#xff0c;在项目启动的时候&#xff0c;需要将xxx省整个省的所有区域数据数据、以及系统字典配置逐条保存在Redis缓存里面&#xff0c;这样查询的时候会更快; 区域数据字典数据一共大概20000多条,&#xff0c;前同事直接使用 list.forEach…

Windows安装MongoDB

1、下载MongoDB的zip&#xff0c;解压 2、创建目录 mkdir D:\JavaSoftware\Database\MongoDB\mongodb-win32-x86_64-windows-5.0.8\data\db mkdir D:\JavaSoftware\Database\MongoDB\mongodb-win32-x86_64-windows-5.0.8\data\log 3、创建一个配置文件mongod.cfg&#xff0c…

使用一个接口的结果作为第二个接口的参数并将两者的数据放置成下拉框的格式

背景 我使用下拉框实现选择id 但是只有两个接口 一个是所有的id 另一个是id对应的具体信息 我想把id传入另一个接口并且获取其name然后写成类似这样的数组 [ { value: 1, label: ‘名称1’ }&#xff0c; { value: 2, label: ‘名称2’ } { value: 3, label: ‘名称3’ } ] 然…

【PPspliT】ppt转pdf-保留过渡动画

网址 http://www.maxonthenet.altervista.org/ppsplit.php 下载安装 使用 再次打开ppt&#xff0c;就能在上方的选项栏里头看到了&#xff1a;

GEE生物量碳储量——利用红和近红外波段和OTSU大津法提取纯净森林面积

简介: 如何利用红和近红外波段和OTSU大津法提取纯净森林面积?本文的主要逻辑是利用特定时期的遥感影像的波段,提取指定范围的内的DN值,然后分别统计发生阈值变化的峰值区域,从而作为筛选森林的临界点,如果研究区较大的话则需要先进行影像分割,分割成为相同大小的区域,…

前端开发Java学习

注释&#xff1a; 单行注释 // 多行注释 /* */ 文件注释 /** */ 1 关键字 &#xff08;关键字一定是小写&#xff09; 2 常量 字符串常量"HelloWord","你好世界"整数常量12&#xff0c;-33小数常量3.14&#xff0c;22.1字符常量A&#xff0c;a &…

不是默认进入Linux|总是自动进入windows系统

问题描述 不是默认进入Linux系统无法主动出现boot引导自动进入windows系统 尝试无效 修复引导无效重装Grub无效重装系统无效 环境 Ubuntu 22.04 LST微星主板 解决方案 修改引导顺序&#xff1a; 开机狂按Del键&#xff0c;进入BIOS系统&#xff0c;左侧Settings 设置&…

src和href的区别

前言 持续学习总结输出中&#xff0c;src和href都是HTML中特定元素的属性&#xff0c;都可以用来引入外部的资源。两者区别如下&#xff1a; 1、作用 href 用于在当前文档和引用资源之间确立联系。 src 用于替换当前内容。 2、范围用途 src&#xff08;source&#xff09…

RabbitMQ基础教程

1.什么是消息队列 消息队列&#xff08;Message Queue&#xff09;&#xff0c;我们一般简称为MQ。消息队列中间件是分布式系统中重要的组件&#xff0c;具有异步性、松耦合、分布式、可靠性等特点。用于实现高性能、高可用、可伸缩和最终一致性架构。是大型分布式系统不可缺少…

Angular11 MSAL B2C登录实例 (一)

前言 因为项目需求&#xff0c;需要把Angular 11项目中登录方式改成B2C登录&#xff0c;所以在参考了一系列文档后&#xff0c;成功通过MSAL将项目的登录方式改成B2C登录。下面介绍了详细步骤及一些注意事项。 步骤&#xff1a; 1. 安装MSAL 在项目中安装msal npm i azure/…

BUUCTF [WUSTCTF2020]find_me 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 得到的 flag 请包上 flag{} 提交。 感谢 Iven Huang 师傅供题。 比赛平台&#xff1a;https://ctfgame.w-ais.cn/ 密文&#xff1a; 下载附件&#xff0c;得到一个.jpg图片。 解题思路&#xff1a; 1、得到一张图…