『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.hqwc.cn/news/213883.html

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

相关文章

【深度学习】CNN中pooling层的作用

1、pooling是在卷积网络&#xff08;CNN&#xff09;中一般在卷积层&#xff08;conv&#xff09;之后使用的特征提取层&#xff0c;使用pooling技术将卷积层后得到的小邻域内的特征点整合得到新的特征。一方面防止无用参数增加时间复杂度&#xff0c;一方面增加了特征的整合度…

【Element】el-switch开关 点击弹窗确认框时状态先改变----点击弹窗取消框失效

一、背景 需求&#xff1a;在列表中添加定期出账的开关按钮&#xff0c;点击开关时&#xff0c;原来的状态不改变&#xff0c;弹出弹窗&#xff1b;点击弹窗取消按钮&#xff1a;状态不改变&#xff0c;点击弹窗确定按钮&#xff1a;状态改变&#xff0c;并调取列表数据刷新页…

机器学习算法——聚类算法

目录 1. 概述2. K-MEANS算法2.1 工作流程2.2 代码实践2.3 Mini Batch K-Means2.4 存在问题2.5 K-MEANS可视化 3. DBSCAN算法3.1 基本概念3.2 工作流程3.3 代码实践3.4 DBSCAN算法可视化 1. 概述 聚类算法是一种无监督学习方法&#xff0c;用于将数据集中的对象分组或聚集成具有…

Camera Raw v16.0.0(PS Raw增效工具)

Camera Raw 16是一款允许摄影师处理原始图像文件的软件PS增效工具。原始图像文件是未经相机内部软件处理的数码照片&#xff0c;因此包含相机传感器捕获的所有信息。Camera Raw 为摄影师提供了一种在将原始文件转换为更广泛兼容的格式&#xff08;如 JPEG 或 TIFF&#xff09;之…

低代码时代,如何运用JVS低代码表单组件单选与多选组件提升业务效率?

在现代化的数字界面中&#xff0c;组件是不可或缺的一部分。无论是在问卷调查、投票&#xff0c;还是在购物车等场景中&#xff0c;单选和多选组件都扮演着重要角色。它们让用户能够在一系列选项中做出决定&#xff0c;从而提高交互的效率和用户体验。 JVS低代码表单组件中提供…

数据黑洞,正在悄悄吞噬你的门店业绩

互联网兴起以来&#xff0c;线下门店的数字化程度始终落后于线上。一个重要的原因是&#xff1a;线下信息不像线上那样简单、集中、易于统计。很多重要数据隐藏于「黑洞」之中&#xff0c;收集和分析成本极为高昂。这极大束缚了门店业绩的提升。 而反过来看&#xff0c;线下场景…

工作流引擎架构设计

一个应用MIS的系统的架构离不开工作流引擎&#xff0c;具有流程引擎思维的架构人员设计系统的时候就有流程的思维&#xff0c;他区别于过程思维&#xff0c;过程思维开发出来的系统&#xff0c;用户面对的是菜单、模块。而流程思维设计出来的系统就是发起、待办、在途、查询、近…

解决Spring Boot应用在Kubernetes上健康检查接口返回OUT_OF_SERVICE的问题

现象 在将Spring Boot应用部署到Kubernetes上时&#xff0c;健康检查接口/healthcheck返回的状态为{"status":"OUT_OF_SERVICE","groups":["liveness","readiness"]}&#xff0c;而期望的是返回正常的健康状态。值得注意的…

APP软件外包开发需要注意的问题

在进行APP软件开发时&#xff0c;有一些关键问题需要特别注意&#xff0c;以确保项目的成功和用户满意度。以下是一些需要注意的问题&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 清晰的需求定义&a…

2023年中国数字疗法行业研究报告

第一章 行业概况 1.1 定义 数字疗法&#xff08;Digital Therapeutics&#xff0c;简称DTx&#xff09;正日益成为医疗保健行业的革命性力量&#xff0c;其定义和范畴根据国际数字疗法联盟&#xff08;Digital Therapeutics Alliance&#xff0c;DTA&#xff09;的阐述&#…

自监督LIGHTLY SSL教程

Lightly SSL 是一个用于自监督学习的计算机视觉框架。 github链接&#xff1a;GitHub - lightly-ai/lightly: A python library for self-supervised learning on images. Documentation&#xff1a;Documentation — lightly 1.4.20 documentation 以下内容主要来自Documen…

成为AI产品经理——模型评估指标

目录 一、模型评估分类 1.在线评估 2.离线评估 二、离线模型评估 1.特征评估 ① 特征自身稳定性 ② 特征来源稳定性 ③ 特征成本 2.模型评估 ① 统计性评估 覆盖度 最大值、最小值 分布形态 ② 模型性能指标 分类问题 回归问题 ③ 模型的稳定性 模型评估指标分…