C++ 标准模板库(STL)教程
编程小白也能懂的STL知识点汇总 – 用通俗语言解释复杂概念
什么是STL?
STL (Standard Template Library) 是C++标准库的一部分,提供了一系列可重用的模板类和函数,用于实现常见的数据结构和算法。你可以把它想象成一个”编程工具箱”,里面装满了各种实用的工具。
为什么要学习STL?
- 节省时间:不用重复造轮子,直接使用现成的数据结构
- 提高效率:STL经过高度优化,性能通常比自己实现的更好
- 代码简洁:大大减少代码量,提高可读性和可维护性
- 标准化:所有C++程序员都懂STL,便于团队协作
1. 容器(Containers)
用来存放数据的”箱子”,就像现实中的书架、衣柜一样,每种容器有不同的特性和用途。
2. 算法(Algorithms)
对容器中的数据进行操作的函数,比如排序、查找、计数等。
3. 迭代器(Iterators)
类似于指针,用于遍历容器中的元素,是容器和算法之间的桥梁。
4. 函数对象(Functors)
行为类似函数的对象,可以像函数一样被调用。
5. 适配器(Adapters)
改变容器或函数对象的接口,使其具有不同的行为。
三步使用法:
- 包含头文件:#include <相关头文件>
- 定义容器:容器类型<数据类型> 容器名称;
- 使用算法:算法函数(容器参数…);
简单示例:
#include <vector>
#include <algorithm>
int main() {
// 1. 创建容器
std::vector<int> numbers = {3, 1, 4, 1, 5, 9, 2, 6};
// 2. 使用算法排序
std::sort(numbers.begin(), numbers.end());
// 3. 输出结果
for(int num : numbers) {
std::cout << num << ” “;
}
// 输出: 1 1 2 3 4 5 6 9
}
STL容器详解
容器是STL的核心,用于存储和管理数据集合。下面是常用的STL容器:
vector(动态数组)
类似于可以自动变长的数组,在尾部插入删除效率高
常用操作: push_back(), pop_back(), size(), []
list(双向链表)
每个元素存储位置不连续,任意位置插入删除效率高
常用操作: push_front(), push_back(), pop_front(), pop_back()
deque(双端队列)
前后两端都可高效插入删除,类似vector和list的结合
常用操作: push_front(), push_back(), pop_front(), pop_back()
set(集合)
不含重复元素,自动排序
常用操作: insert(), find(), erase()
map(映射)
存储键值对,按键自动排序,键不可重复
常用操作: operator[], insert(), find()
stack(栈)
后进先出(LIFO)结构,只能在一端操作
常用操作: push(), pop(), top()
queue(队列)
先进先出(FIFO)结构,一端进另一端出
常用操作: push(), pop(), front(), back()
priority_queue(优先队列)
元素按优先级排序,优先级最高的元素总是在队首
常用操作: push(), pop(), top()
- 需要随机访问 → vector
- 需要频繁在中间插入/删除 → list
- 需要快速查找 → set/map
- 需要先进先出 → queue
- 需要后进先出 → stack
迭代器可以理解为”智能指针”,提供了访问容器元素的方法。它就像书签一样,帮你记住容器中的位置。
迭代器分类:
- 输入迭代器:只读,只能向前移动
- 输出迭代器:只写,只能向前移动
- 前向迭代器:读写,只能向前移动
- 双向迭代器:读写,可向前向后移动(如list)
- 随机访问迭代器:读写,可任意移动(如vector)
常用操作:
// 获取迭代器
auto it = v.begin(); // 指向第一个元素
auto end = v.end(); // 指向最后一个元素的下一个位置
// 遍历容器
for (auto it = v.begin(); it != v.end(); ++it) {
std::cout << *it << ” “; // 使用*解引用
}
// 修改元素
*it = 10; // 修改第一个元素
STL提供了大约100个算法函数,都在 <algorithm> 头文件中
常用算法分类:
- 排序算法:sort, stable_sort, partial_sort
- 查找算法:find, find_if, binary_search
- 计数算法:count, count_if
- 修改算法:copy, fill, replace, transform
- 数值算法:accumulate, partial_sum
- 集合操作:set_union, set_intersection
- 堆操作:make_heap, push_heap, pop_heap
算法使用示例:
#include <vector>
std::vector<int> v = {5, 3, 1, 4, 2};
// 排序
std::sort(v.begin(), v.end());
// 查找元素
auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end()) {
// 找到元素
}
// 反转容器
std::reverse(v.begin(), v.end());
// 遍历并修改元素
std::for_each(v.begin(), v.end(), [](int &n) {
n *= 2; // 所有元素乘以2
});
函数对象(Functors)与Lambda表达式
函数对象是重载了函数调用操作符 operator() 的类对象,可以像函数一样被调用。
简单示例:
public:
int operator()(int a, int b) {
return a + b;
}
};
Add add;
int sum = add(3, 4); // 返回7
STL内置函数对象:
- 算术运算:plus, minus, multiplies, divides
- 关系运算:equal_to, not_equal_to, greater, less
- 逻辑运算:logical_and, logical_or, logical_not
std::sort(v.begin(), v.end(), std::greater<int>());
C++11引入的匿名函数,用于快速创建小型函数对象,语法简洁。
基本语法:
使用示例:
auto sum = [](int a, int b) { return a + b; };
int result = sum(3, 4); // 7
// 在算法中使用
std::vector<int> v = {1, 2, 3, 4, 5};
int count = std::count_if(v.begin(), v.end(),
[](int n) { return n % 2 == 0; }); // 计数偶数
捕获列表:
- []:不捕获任何外部变量
- [=]:按值捕获所有外部变量
- [&]:按引用捕获所有外部变量
- [a, &b]:按值捕获a,按引用捕获b