【C++指南】解锁C++ STL:从入门到进阶的技术之旅
💓 博客主页:倔强的石头的CSDN主页
📝Gitee主页:倔强的石头的gitee主页
⏩ 文章专栏:《C++指南》
期待您的关注
目录
一、STL 是什么
二、STL 的核心组件
2.1 容器(Containers)
2.2 算法(Algorithms)
2.3 迭代器(Iterators)
2.4 其他组件
三、STL 的优势
3.1 高效开发
3.2 高性能
3.3 泛型与可扩展性
3.4 代码简洁与可维护性
3.5 跨平台兼容性
四、结语
一、STL 是什么
STL,即标准模板库(Standard Template Library) ,是 C++ 标准库的重要组成部分,是一个具有工业强度的、高效的 C++ 程序库。
它包含了诸多在计算机科学领域常用的基本数据结构和基本算法,为 C++ 程序员们提供了一个可扩展的应用框架,高度体现了软件的可复用性。
- 从逻辑层次来看,STL 体现了泛型化程序设计的思想,将大部分基本算法抽象、泛化,使其独立于与之对应的数据结构,能以相同或相近的方式处理各种不同情形。
- 从实现层次看,整个 STL 是以类型参数化的方式实现的,基于模板,这使得 STL 能够适用于各种不同的数据类型 。
在 C++ 编程中,STL 就像是一个强大的工具箱,里面装满了各种各样实用的工具。
- 比如在数据存储方面,它提供了 vector(动态数组)、list(链表)、map(映射)、set(集合)等多种容器,每种容器都有其独特的特性和适用场景,就像不同类型的工具适用于不同的工作一样。
- 在算法方面,它包含了排序(sort)、查找(find)、拷贝(copy)等常用算法,这些算法经过了高度优化,性能出色。迭代器则像是连接容器和算法的桥梁,通过它可以方便地遍历和操作容器中的元素 。
举个简单的例子:
当我们需要存储一组整数并对其进行排序时,如果不使用 C++中的STL,我们可能需要自己编写数组操作代码和排序算法,(在C语言中就是这样)这不仅繁琐,而且容易出错。但有了 STL,我们只需要使用 vector 来存储整数,然后调用 sort 算法,就能轻松实现排序功能,大大提高了开发效率 。
二、STL 的核心组件
2.1 容器(Containers)
容器是 STL 中用于存储数据的数据结构,就像是一个个不同类型的 “盒子”,可以用来存放各种数据。它主要分为序列容器、关联容器和容器适配器 。
序列容器
序列容器中的元素按线性顺序存储,就像一排整齐摆放的物品,常见的有 vector、list 和 deque。
- vector 如同一个动态数组,它的底层是连续的内存空间,支持快速随机访问,就像我们可以快速找到数组中某个下标的元素一样。在尾部插入和删除元素的效率也很高,比如往数组末尾添加一个元素很容易。但如果在中间或头部插入、删除元素,就需要移动大量元素,效率较低,就好比在一排摆放整齐的物品中间插入或拿走一个,需要挪动其他物品 。
- list 是双向链表,每个元素都有指向前一个和后一个元素的指针,这使得它在任意位置插入和删除元素都非常高效,就像在一条链子上添加或取下一个环很方便。但由于它的内存空间不连续,不支持随机访问,想要访问某个特定位置的元素,需要从链表头或链表尾开始逐个遍历 。
- deque 是双端队列,它既可以在头部也可以在尾部高效地插入和删除元素,同时也支持随机访问,不过随机访问的性能略逊于 vector 。
关联容器
关联容器通过键值对来存储和访问元素,能提供快速的查找功能,仿佛是一个智能的索引库。
- set 存储的是不重复的元素,并且会自动对元素进行排序,比如我们要存储一组不重复的整数,并且希望它们是有序的,就可以使用 set 。
- map 则是存储键值对,通过键来快速查找对应的值,就像一个字典,通过单词(键)可以快速找到释义(值) 。
容器适配器
容器适配器是对其他容器进行封装,提供特定的接口和行为。
- stack 是后进先出(LIFO)的数据结构,就像一个栈,最后放进去的元素最先取出来,常用于实现函数调用栈等 。
- queue 是先进先出(FIFO)的数据结构,类似排队,先到的先处理,常用于实现任务队列等 。
2.2 算法(Algorithms)
算法是 STL 中用于操作容器中数据的函数模板,它是解决各种问题的 “工具”。
STL 算法通过迭代器来访问容器中的元素,从而实现对不同容器的通用操作,这使得算法与容器解耦,同一个算法可以应用于多种容器类型,大大提高了代码的复用性 。
常见的算法有很多,比如
- sort 算法用于对容器中的元素进行排序。假设有一个 vector ,我们可以使用 sort 函数对其内部的整数进行排序,让杂乱无章的数字变得有序 。
- find 算法用于在容器中查找指定的元素,返回指向该元素的迭代器,如果未找到则返回容器的结束迭代器。例如在一个存储学生成绩的 vector 中查找某个特定的成绩,就可以使用 find 算法 。
需要注意的是,不同的算法对容器和迭代器有不同的要求:
一些算法可能需要容器支持随机访问迭代器,而另一些算法则对容器的插入、删除操作性能有要求。在使用算法时,要确保容器和迭代器满足算法的要求,否则可能会导致编译错误或运行时错误
2.3 迭代器(Iterators)
迭代器是连接容器和算法的桥梁,它的作用类似于指针,提供了一种统一的方式来访问容器中的元素,而无需了解容器的内部实现细节。通过迭代器,我们可以逐个遍历容器中的元素,就像使用指针遍历数组一样 。
迭代器有多种类型,包括输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器:
- 输入迭代器只能向前移动,用于读取容器中的元素;
- 输出迭代器只能向前移动,用于向容器中写入元素;
- 前向迭代器可以向前移动,并支持读写操作;
- 双向迭代器可以向前和向后移动,并支持读写操作;
- 随机访问迭代器功能最为强大,不仅可以向前和向后移动,还可以像数组下标一样进行跳跃式访问
在使用迭代器时,要特别注意迭代器失效的问题:当容器的结构发生改变,比如插入或删除元素时,可能会导致迭代器失效。
例如,在一个 vector 中删除某个元素后,指向该元素以及该元素之后的迭代器可能就不再有效了
2.4 其他组件
除了容器、算法和迭代器这三个核心组件外,STL 还包含函数对象、适配器和分配器等组件 :
函数对象,也称为仿函数,是一种行为类似函数的对象,它通过重载函数调用操作符 “()” 来实现。函数对象可以作为算法的参数,为算法提供不同的策略或行为。
例如,在使用 sort 算法时,可以传入一个自定义的函数对象来定义排序的规则,比如按照元素的绝对值大小进行排序
适配器用于修改或扩展其他组件的功能。容器适配器如 stack 和 queue,它们基于底层容器(如 deque)提供特定的接口,改变了容器的访问方式和行为 。
迭代器适配器可以将一种迭代器转换为另一种迭代器,例如 reverse_iterator 可以实现反向遍历容器 。函数适配器则可以修改函数对象的行为 。
分配器负责管理内存的分配和释放,它为容器提供内存空间。STL 提供了默认的分配器,也允许用户自定义分配器,以满足特殊的内存管理需求 。在实际应用中,大多数情况下使用默认分配器即可,但在一些对内存管理要求较高的场景,如大规模数据处理或内存受限的环境中,自定义分配器可以提高内存使用效率 。
三、STL 的优势
3.1 高效开发
STL 对常用的数据结构和算法进行了封装,极大地简化了开发过程,显著提高了开发效率。
以排序功能为例,在没有 STL 时,我们可能需要自己编写复杂的排序算法,如冒泡排序、快速排序等 。
// 自己实现的冒泡排序
void bubbleSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}
这段代码实现了冒泡排序算法,通过两层循环比较相邻元素并交换,从而实现排序。但使用 STL 的 sort 函数,只需简单一行代码就能实现同样的功能 。
#include <iostream>
#include <algorithm>
#include <vector>int main() {std::vector<int> vec = {5, 2, 9, 1, 3};std::sort(vec.begin(), vec.end());for (int num : vec) {std::cout << num << " ";}return 0;
}
在这个例子中,我们使用了 STL 的 vector 容器来存储整数,然后调用了 algorithm 头文件中的 sort 函数对其进行排序。sort 函数的第一个参数是容器的起始迭代器,第二个参数是容器的结束迭代器,它会对这两个迭代器之间的元素进行排序 。
3.2 高性能
STL 中的算法和容器都经过了精心的优化设计,具有出色的性能表现。
以 vector 容器为例,它的底层是基于连续的内存空间实现的,这使得它在随机访问时效率极高,时间复杂度为 O (1) ,就像我们可以快速定位数组中某个下标的元素一样。在尾部插入和删除元素时,平均时间复杂度也接近 O (1) ,因为通常情况下只需要在连续内存的末尾进行操作 。不过,当 vector 的容量不足时,需要重新分配内存并复制原有元素,这个过程的时间复杂度为 O (n) ,但由于这种情况并不频繁发生,所以整体上 vector 在尾部操作的性能依然很优秀 。
再看 map 容器,它的底层是基于红黑树实现的。红黑树是一种自平衡的二叉搜索树,这使得 map 在插入、删除和查找元素时都具有较高的效率,时间复杂度均为 O (log n) 。例如,在一个包含大量键值对的 map 中查找某个特定的键,map 能够快速定位到对应的节点,而不需要像在无序数组中那样逐个遍历元素 。
3.3 泛型与可扩展性
STL 是基于模板的泛型设计,这使得它具有高度的通用性和可扩展性。
模板允许我们编写与具体数据类型无关的代码,从而实现代码的复用。
以 sort 函数为例,它不仅可以对 int 类型的容器进行排序,还可以对其他各种类型的容器进行排序,只要这些类型支持比较操作 。
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>int main() {std::vector<int> intVec = {5, 2, 9, 1, 3};std::sort(intVec.begin(), intVec.end());for (int num : intVec) {std::cout << num << " ";}std::cout << std::endl;std::vector<std::string> stringVec = {"banana", "apple", "cherry"};std::sort(stringVec.begin(), stringVec.end());for (const std::string& str : stringVec) {std::cout << str << " ";}return 0;
}
在这段代码中,我们首先使用 sort 函数对 int 类型的 vector 进行排序,然后又对 string 类型的 vector 进行排序。sort 函数的模板特性使得它能够适应不同的数据类型,无需为每种类型单独编写排序函数 。
同时,STL 的这种泛型设计也方便我们进行扩展。我们可以根据自己的需求,编写自定义的容器和算法,只要遵循 STL 的接口规范,就可以与 STL 的其他组件无缝配合使用
3.4 代码简洁与可维护性
STL 提供了统一的接口和标准化的命名模式,使得代码更加简洁、易读和可维护
在 STL 中,各种容器和算法的操作都有明确的定义和规范,这使得程序员在使用时能够快速上手,并且代码的风格更加一致 。
以在容器中插入元素为例,vector、list、deque 等容器都提供了 push_back 函数用于在容器尾部插入元素,这种统一的接口设计使得我们在切换不同容器时,代码的改动量最小 。
#include <iostream>
#include <vector>
#include <list>int main() {std::vector<int> vec;vec.push_back(1);vec.push_back(2);vec.push_back(3);std::list<int> lst;lst.push_back(1);lst.push_back(2);lst.push_back(3);return 0;
}
从这段代码可以看出,虽然 vector 和 list 是不同的容器,但其插入元素的操作方式是一致的,这大大减少了代码的冗余,提高了代码的可读性 。
当代码中出现问题时,由于 STL 的标准化和一致性,我们更容易定位和解决问题,从而提高了代码的可维护性 。
3.5 跨平台兼容性
STL 作为 C++ 标准库的一部分,具有良好的跨平台兼容性
无论我们使用的是 Windows、Linux 还是 Mac OS 等操作系统,只要编译器支持 C++ 标准,就可以使用 STL 。
这意味着我们基于 STL 编写的代码可以在不同的平台上运行,无需进行大量的修改。
例如,一个使用了 STL 的 vector 和 sort 函数的 C++ 程序,在 Windows 系统下使用 Visual Studio 编译运行正常,那么在 Linux 系统下使用 GCC 编译时,也能正常运行,只需要确保 GCC 的版本支持相应的 C++ 标准即可 。
这种跨平台兼容性使得我们能够更高效地开发跨平台应用程序,减少了因平台差异带来的开发成本和维护成本 。
四、结语
STL 作为 C++ 标准库的重要组成部分,为 C++ 编程带来了诸多便利和强大的功能。
其核心组件容器、算法和迭代器相互协作,提供了高效的数据存储和处理方式 。通过使用 STL,我们能够显著提高开发效率,减少重复劳动,编写出更加简洁、高效、可维护的代码 。
对于想要深入学习 C++ 编程的开发者来说,掌握 STL 是必不可少的一步。建议大家通过阅读相关书籍、文档,以及动手实践来加深对 STL 的理解和运用能力 。
可以尝试使用 STL 解决一些实际问题,如实现数据处理、算法优化等功能,在实践中不断积累经验,提升自己的编程水平 。
希望本文能帮助大家对 STL 有一个初步的认识,开启高效 C++ 编程之旅
本文完
相关文章:

【C++指南】解锁C++ STL:从入门到进阶的技术之旅
💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《C指南》 期待您的关注 目录 一、STL 是什么 二、STL 的核心组件 2.1 容器(Containers) 2.2 算法&…...
LeetCode刷题---字符串---859
亲密字符串 859. 亲密字符串 - 力扣(LeetCode) 题目: 给你两个字符串 s 和 goal ,只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果,就返回 true ;否则返回 false 。 交换字母的定义是&…...

数据处理中多线程功能的设计逻辑,及python的多线程实现
数据处理中多线程功能的设计逻辑主要是通过并发编程模型来提高程序的执行效率和响应速度。多线程允许在同一进程中创建多个线程,每个线程独立执行任务,同时共享进程的资源(如内存空间)。这种机制特别适用于I/O密集型任务ÿ…...
DeepSeek-R1技术革命:用强化学习重塑大语言模型的推理能力
引言:低成本高性能的AI新范式 在2025年1月,中国AI公司DeepSeek发布了两个标志性模型——DeepSeek-R1-Zero与DeepSeek-R1,以仅600万美元的训练成本实现了与OpenAI O1系列(开发成本约5亿美元)相当的推理性能,…...
python中的深度学习框架TensorFlow 和 PyTorch 有什么区别?
TensorFlow 和 PyTorch 是目前最流行的两个深度学习框架,它们在设计理念、使用方式和社区支持等方面存在一些显著的区别。以下是它们的主要区别: 1. 设计理念 TensorFlow: 静态计算图:TensorFlow 使用静态计算图,即在运行模型之前需要先定义整个计算图。这使得 TensorFlo…...

用 Python 实现 DeepSeek R1 本地化部署
DeepSeek R1 以其出色的表现脱颖而出,不少朋友想将其本地化部署,网上基于 ollama 的部署方式有很多,但今天我要带你领略一种全新的方法 —— 使用 Python 实现 DeepSeek R1 本地化部署,让你轻松掌握,打造属于自己的 AI…...
Spreadjs与GcExcel
GcExcel VS SpreadJS 前言 报表系统前端化,释放后端压力,调高前端研发产能,但随着报表系统的数据量的增加,浏览器的限制,前端报表已达到瓶颈,用户使用体验逐渐不友好,为解决这一问题,找到新的解决方案,所以写下此篇对比 两者分别是什么? SpreadJS 是一款基于 HTML5…...
vue中使用lodash的debounce(防抖函数)
1、安装 npm i --save lodash.debounce2、引入 import debounce from lodash.debounce3、使用 <van-search v-model"searchValue" placeholder"输入姓名或工号" inputhandleInput />第一种: handleInput: debounce(function (val) {c…...
什么是耐环境环形光源
耐环境环形光源是一种专为工业视觉系统设计的光源,能够在恶劣环境下稳定工作。以下是其主要特点和应用: 特点 耐用性:外壳坚固,通常采用金属或高强度塑料,能承受冲击、振动和温度变化。 防护等级:具备高IP防…...

3dtiles——Cesium ion for Autodesk Revit Add-In插件
一、说明: Cesium已经支持3dtiles的模型格式转换; 可以从Cesium官方Aesset中上传gltf等格式文件转换为3dtiles; 也可以下载插件(例如revit-cesium插件)转换并自动上传到Cesium官方Aseet中。 Revit转3dtiles插件使用…...

Edge浏览器清理主页
我们都知道,Microsoft Edge浏览器是微软创造的搜索浏览器,Windows10、11自带。但是你可以看到,每次你打开Edge浏览器的时候都可以看到许多的广告,如图: 导致打开Edge浏览器的时候会遭受卡顿,广告骚扰&#…...
leetcode刷题第十天——栈与队列Ⅱ
本次刷题顺序是按照卡尔的代码随想录中给出的顺序 1047. 删除字符串中的所有相邻重复项 char* removeDuplicates(char* s) {int len strlen(s);char* tmp malloc(sizeof(char) * (len 1));int top -1, idx 0;while(idx < len) {if(top -1) tmp[top] s[idx];else {i…...
硬修复(hPPR)与软修复(sPPR)
什么是PPR? PPR(Post Package Repair)是一种内存修复技术,主要用于修复DRAM(包括LPDDR4、DDR4等)中的存储单元故障。它通过在封装后对内存芯片进行修复,提高良率和可靠性,减少因制造缺陷导致的内存失效。 想象一下,你买了一袋苹果,有些苹果表面可能有个小斑点或者磕…...
filebeat抓取nginx日志
目录 一、抓取普通的应用输出日志到elasticsearch 二、抓取nginx日志输出到ElasticSearch 2.1、nginx.conf设定日志输出为JSON格式 2.2、nginx.conf设定日志按天输出文件 2.3、抓取Nginx JSON到ElasticSearch配置 一、抓取普通的应用输出日志到elasticsearch - type: log…...

TLQ-CN10.0.2.0 (TongLINK/Q-CN 集群)部署指引 (by lqw)
文章目录 安装准备虚拟机部署部署zk集群安装zk集群启动zk集群初始化元数据(zk)关闭zk集群 部署BookKeeper集群安装BookKeeper集群初始化元数据(bk)启动BookKeeper停止 BookKeeper 部署Brokers集群安装Brokers集群启动 broker停止 …...

第 14 天:UE5 C++ 与蓝图(Blueprint)交互!
🎯 目标: ✅ 了解 C 与蓝图(Blueprint)交互的方式 ✅ 在 C 中调用蓝图函数 ✅ 让蓝图访问 C 变量和方法 ✅ 使用 UFUNCTION、UPROPERTY 进行蓝图暴露 ✅ 提高开发效率,让 C 和蓝图开发者高效协作 1️⃣ 为什么要让 C…...
小初高各学科教材,PDF电子版下载
链接:https://pan.quark.cn/s/7c2125f648e2 小初高中电子课本资料pdf合集 高中各科教材 (部分举例) - 语文:新人教版、旧人教版、苏教版等 - 数学:人教A版、沪教版、鄂教版等 - 英语:重大版、人教版…...
Trader Joe‘s EDI 需求分析
Trader Joes成立于1967年,总部位于美国加利福尼亚州,是一家独特的零售商,专注于提供高质量且价格合理的食品。公司经营范围涵盖了各类杂货、冷冻食品、健康食品以及独特的本地特色商品。 EDI需求分析 电子数据交换(EDIÿ…...
python class详解
在 Python 中,class 是用来创建新的数据类型,即对象的蓝图。类可以包含属性(变量)和方法(函数),它们定义了对象的状态和行为。以下是 Python 类的基本概念和用法的详细解释: 定义类…...

基于LVS负载均衡练习
对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,比较其各自的优势。 NAT模式,全称是网络地址转换模式。NAT模式下,负载均衡器(Director)会修改请求和响应的IP地址。客户端的请求先到达Director,Director将请…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...