C++STL教程

C++ STL 教程 – 编程小白也能懂

C++ 标准模板库(STL)教程

编程小白也能懂的STL知识点汇总 – 用通俗语言解释复杂概念

什么是STL?

STL (Standard Template Library) 是C++标准库的一部分,提供了一系列可重用的模板类和函数,用于实现常见的数据结构和算法。你可以把它想象成一个”编程工具箱”,里面装满了各种实用的工具。

STL的核心思想是代码复用泛型编程。它通过模板技术实现了与数据类型无关的通用编程。

为什么要学习STL?

  • 节省时间:不用重复造轮子,直接使用现成的数据结构
  • 提高效率:STL经过高度优化,性能通常比自己实现的更好
  • 代码简洁:大大减少代码量,提高可读性和可维护性
  • 标准化:所有C++程序员都懂STL,便于团队协作
STL的五大核心组件

1. 容器(Containers)

用来存放数据的”箱子”,就像现实中的书架、衣柜一样,每种容器有不同的特性和用途。

2. 算法(Algorithms)

对容器中的数据进行操作的函数,比如排序、查找、计数等。

3. 迭代器(Iterators)

类似于指针,用于遍历容器中的元素,是容器和算法之间的桥梁。

4. 函数对象(Functors)

行为类似函数的对象,可以像函数一样被调用。

5. 适配器(Adapters)

改变容器或函数对象的接口,使其具有不同的行为。

简单记忆法:数据放容器里,迭代器像手指,算法处理数据,函数对象定规则,适配器改接口。
STL基本使用步骤

三步使用法:

  1. 包含头文件:#include <相关头文件>
  2. 定义容器:容器类型<数据类型> 容器名称;
  3. 使用算法:算法函数(容器参数…);

简单示例:

#include <iostream>
#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组件都在std命名空间中,使用时要加上std::前缀

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
迭代器(Iterators)

迭代器可以理解为”智能指针”,提供了访问容器元素的方法。它就像书签一样,帮你记住容器中的位置。

迭代器分类:

  • 输入迭代器:只读,只能向前移动
  • 输出迭代器:只写,只能向前移动
  • 前向迭代器:读写,只能向前移动
  • 双向迭代器:读写,可向前向后移动(如list)
  • 随机访问迭代器:读写,可任意移动(如vector)

常用操作:

std::vector<int> v = {1, 2, 3, 4, 5};

// 获取迭代器
auto it = v.begin(); // 指向第一个元素
auto end = v.end(); // 指向最后一个元素的下一个位置

// 遍历容器
for (auto it = v.begin(); it != v.end(); ++it) {
  std::cout << *it << ” “; // 使用*解引用
}

// 修改元素
*it = 10; // 修改第一个元素
C++11引入了auto关键字,可以自动推断迭代器类型,简化代码
常用算法(Algorithms)

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 <algorithm>
#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表达式

函数对象(Functors)

函数对象是重载了函数调用操作符 operator() 的类对象,可以像函数一样被调用。

简单示例:

class Add {
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
// 使用greater进行降序排序
std::sort(v.begin(), v.end(), std::greater<int>());
Lambda表达式

C++11引入的匿名函数,用于快速创建小型函数对象,语法简洁。

基本语法:

[捕获列表](参数列表) -> 返回类型 { 函数体 }

使用示例:

// 简单的lambda表达式
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
Lambda表达式特别适合在算法中作为回调函数使用

这份C++ STL教程总结旨在帮助编程小白理解STL的核心概念和用法

记住:掌握STL是成为高效C++程序员的关键一步!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部