从零开始:Linux 环境下的 C/C++ 编译教程

从零开始:Linux 环境下的 C/C++ 编译教程

个人主页:chian-ocean

文章专栏

前言:

GCC(GNU Compiler Collection)是一个功能强大的编译器集合,支持多种语言,包括 C 和 C++。其中 gcc 用于 C 语言编译,g++ 专用于 C++ 编译。
在这里插入图片描述

Linux GCC or G++的安装

安装 GCC

运行以下命令安装 GCC:

sudo yum install-r gcc 

安装完成后,可以再次检查版本:

gcc --version
在这里插入图片描述

安装G++

运行以下命令安装 GCC:

sudo yum install-r g++ 

安装完成后,可以再次检查版本:

g++ --version
在这里插入图片描述

Linux的代码编译

预处理(Preprocessing)

预处理的工作

  • 去掉注释
  • 展开头文件
  • 条件编译
  • 宏替换

C++代码执行

g++ -E code.cpp -o code.i # 可以生成与处理文件,生成.i文件
在这里插入图片描述

编译(Compilation)

编译器将预处理后的源代码转换为汇编代码(文本形式的机器指令)。

  • 生成汇编代码(通常是 .s 文件)。
  • 编译器会进行语法分析和语义检查。
g++ -S code.i -o code.s # 可以生成与处理文件,生成.s文件
在这里插入图片描述

汇编(Assembly)

汇编器将汇编代码(.s 文件)转换为二进制的目标代码(.o 文件)。

  • 汇编代码被转换为机器能够理解的指令。
  • 生成目标文件(通常是 .o.obj 文件)。
g++ -c code.s -o code.o # 可以生成与处理文件,生成.o文件 od filename # 可以进行查看
在这里插入图片描述

链接(Linking)

函数库(Library)简介

在编程中,函数库是指封装了一组可重用函数、类或其他代码模块的集合,目的是简化开发、提高代码复用性。函数库通常以静态库(*.a*.lib)或动态库(*.so*.dll*.dylib)的形式存在。

在这里插入图片描述
类型描述
静态库在编译时将库的代码嵌入到可执行文件中,生成的文件独立运行,不依赖外部库。
动态库在运行时加载库文件,节省空间和内存,可以被多个程序共享。

动态链接

动态库(Dynamic Library)是一种在运行时加载的库,可以被多个程序共享,以节省存储空间和内存。动态库的文件扩展名在不同操作系统中有所不同:

  • Linux: .so(Shared Object)
  • Windows: .dll(Dynamic Link Library)
  • macOS: .dylib
ldd #可以查看可执行程序所依赖的动态库

下面是code可执行文件所以来的动态库

在这里插入图片描述

静态链接

静态库是一种将一组目标文件(.o 文件)打包成单个文件(通常扩展名为 .a.lib)的技术,便于代码复用。静态库在编译时链接到可执行文件中,因此运行时不需要额外的库支持。

  • Linux: .a
  • Windows: .lib
g++ code.cpp -static-o code # -static 可以生成静态链接
在这里插入图片描述

动态VS静态

定义

链接方式定义
静态链接在编译阶段,将所需库的代码嵌入到可执行文件中,生成一个独立的可执行文件。
动态链接在运行时加载所需的库(动态库),可执行文件只包含对库的符号引用,库本身存储在外部文件中(如 .so)。

操作系统命名

操作系统静态库扩展名动态库扩展名
Linux.a.so
Windows.lib.dll
macOS.a.dylib

对比表

特性静态链接动态链接
生成的可执行文件大小较大(嵌入所有库代码)较小(仅包含对动态库的引用)
运行时依赖无需外部库,独立运行需要动态库文件
运行效率高(无需加载外部库,直接执行)稍低(运行时加载动态库)
内存使用每个程序独立占用库的代码和数据多个程序共享同一动态库
更新维护更新库后需重新编译程序更新库后程序无需重新编译
部署和兼容性部署简单,无需额外的动态库部署复杂,需要确保动态库存在并与程序兼容
符号冲突不易出现,因为库代码独立嵌入到每个可执行文件中可能出现多个库之间的符号冲突
和兼容性**部署简单,无需额外的动态库部署复杂,需要确保动态库存在并与程序兼容
符号冲突不易出现,因为库代码独立嵌入到每个可执行文件中可能出现多个库之间的符号冲突
适用场景嵌入式系统、小型独立工具、运行环境固定的场景大型系统、需要频繁更新库或共享库的场景

Read more

C++迭代器全解析:从概念到实践,掌握STL的灵魂

C++迭代器全解析:从概念到实践,掌握STL的灵魂

引言:为什么需要迭代器? 在C++的世界里,数据容器千变万化——有连续存储的vector,有链式连接的list,还有树形结构的set。如果每种容器都要单独设计访问接口,那么算法的复用性将大大降低。这正是迭代器(Iterator)诞生的意义:提供一种统一的访问机制,让算法可以独立于具体容器而工作。 想象一下,如果没有迭代器,我们需要为每个容器单独实现sort()、find()、copy()等算法。而有了迭代器,一个std::sort()就能处理所有支持随机访问的容器。这就是STL(标准模板库)设计哲学的核心——泛型编程。 迭代器的本质:泛型指针 从概念上讲,迭代器是泛化的指针。普通指针能做的,迭代器基本都能做,而且更安全、更抽象。但并非所有迭代器都像指针那样强大,这正是STL将迭代器分为五种类别的原因。 // 原生指针本身也是迭代器 int arr[5] = {1, 2, 3, 4, 5}; int* ptr

By Ne0inhk
容器适配器深度解析:从STL的stack、queue到优先队列的底层实现

容器适配器深度解析:从STL的stack、queue到优先队列的底层实现

文章目录 * 容器适配器深度解析:从STL的stack、queue到优先队列的底层实现 * 1. 栈的介绍和使用 * 1.1 栈的介绍 * 1.2 栈的使用 * 最小栈实现 * 栈的弹出压入序列 * 逆波兰表达式求值 * 1.3 stack的模拟实现 * 2. 队列的介绍和使用 * 2.1 队列的介绍 * 2.2 queue的使用 * 2.3 queue的模拟实现 * 3. 优先队列的介绍和使用 * 3.1 priority_queue的介绍 * 3.2 priority_queue的使用 * 3.3 priority_queue的模拟实现 * 4. 容器适配器 * 4.1 什么是适配器 * 4.2

By Ne0inhk
【C++初阶】:C++入门相关知识(3):引用 & inline内联函数 & nullptr相关概念

【C++初阶】:C++入门相关知识(3):引用 & inline内联函数 & nullptr相关概念

🎈主页传送门:良木生香 🔥个人专栏:《C语言》 《数据结构-初阶》 《程序设计》《鼠鼠的C++学习之路》 🌟人为善,福随未至,祸已远行;人为恶,祸虽未至,福已远离 前言:在上一篇文章中,我们学习了C++的输入输出,缺省参数以及函数重载,这些都是C++入门必备的基础知识,那么在这篇文章中,我们就要来学习剩下C++其他的基础知识,那就是引用、inline、以及nullptr这些知识。 一、引用 1.1、引用的概念和定义 引用不是定义一个新变量,而是给已经存在的变量起一个别名,那么编译器就不会为别名重新开辟空间,它和引用变量共同使用同一块空间。就好比我们把土豆称为马铃薯,番茄称为西红柿一样,都是取了一个新的别名,但是东西是同一个东西,所以引用的语法如下: 类型& 别名 = 变量 使用方法如下: int a = 10; int&

By Ne0inhk
【C++初阶】C++入门相关知识(1):C++历史 & 第一个C++程序 & 命名空间

【C++初阶】C++入门相关知识(1):C++历史 & 第一个C++程序 & 命名空间

🎈主页传送门:良木生香 🔥个人专栏:《C语言》 《数据结构-初阶》 《程序设计》 🌟人为善,福随未至,祸已远行;人为恶,祸虽未至,福已远离 前言:我们在此之前已经学习了C语言和数据结构,明白了C语言的基本概念,同时也学习了初阶的数据结构,现在,我们已经具备了学习初阶c++的能力了,那么,从今天开始,我们就正式进入到C++的学习中了,本专栏会记录下小编的学习C++的历程,有什么讲的不对的地方还请大佬们指出错误,那么,现在我们就正式进入到C++的学习吧 本专栏介绍:在我们之前已经学习过的C语言和数据结构的基础上,我们将会在本C++专栏上继续学习C++语法、STL、以及高阶数据结构 目录 一、C++历史介绍 1.1、起源与诞生(1979~1983) 1.2、核心 1.3发展与完善(

By Ne0inhk