C++的STL

  1. 1. 一、STL核心组成(新手先掌握这3个)
  2. 2. 二、最常用STL组件的具体用法
    1. 2.1. 1. 序列式容器:vector(最常用,动态数组)
    2. 2.2. 2. 关联式容器:map(键值对存储)
    3. 2.3. 3. 算法(Algorithms):通用操作函数
  3. 3. 三、新手使用STL的注意事项
  4. 4. 总结
  5. 5. STL常用容器及核心操作总览
  6. 6. 完整示例代码(覆盖所有容器核心操作)
  7. 7. 代码运行说明
  8. 8. 各容器核心操作总结
  9. 9. 总结

C++ STL(Standard Template Library,标准模板库)是C++标准库的核心部分,它提供了一系列通用的、高效的模板类和函数,涵盖了容器、算法、迭代器、函数对象、适配器等核心组件,能极大提升编程效率。下面我会从新手视角,用通俗易懂的方式讲解STL的核心用法。

一、STL核心组成(新手先掌握这3个)

  1. 容器(Containers):用于存储数据的模板类(如数组、链表、集合),分为:
    • 序列式容器:vectorlistdeque(按顺序存储)
    • 关联式容器:mapset(按键/值有序存储)
    • 无序容器:unordered_mapunordered_set(哈希存储,查询更快)
  2. 迭代器(Iterators):遍历容器的”工具”,类似指针,统一了不同容器的遍历方式。
  3. 算法(Algorithms):通用的操作函数(如排序、查找、遍历),通过迭代器操作容器数据。

二、最常用STL组件的具体用法

1. 序列式容器:vector(最常用,动态数组)

vector是动态扩容的数组,随机访问速度快,适合频繁读取、尾部增删的场景。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
// 必须包含对应容器的头文件
#include <vector>
// 算法头文件(如排序、查找)
#include <algorithm>

using namespace std; // 新手可先用,避免写std::前缀

int main() {
// 1. 创建vector
vector<int> vec; // 空的int类型vector
vector<int> vec2(5, 10); // 初始化5个元素,每个值为10

// 2. 新增元素
vec.push_back(1); // 尾部添加元素(核心操作)
vec.push_back(3);
vec.push_back(2);

// 3. 访问元素
cout << "第一个元素:" << vec[0] << endl; // 下标访问(无越界检查)
cout << "第二个元素:" << vec.at(1) << endl; // at访问(有越界检查,更安全)
cout << "尾部元素:" << vec.back() << endl; // 获取尾部元素

// 4. 遍历元素(3种方式)
// 方式1:下标遍历
cout << "下标遍历:";
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " ";
}
cout << endl;

// 方式2:迭代器遍历(STL通用方式)
cout << "迭代器遍历:";
// vector<int>::iterator 是迭代器类型,begin()指向第一个元素,end()指向最后一个元素的下一位
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " "; // *it 解引用获取元素值
}
cout << endl;

// 方式3:范围for(C++11及以上,最简洁)
cout << "范围for遍历:";
for (int num : vec) {
cout << num << " ";
}
cout << endl;

// 5. 常用操作
cout << "vector大小:" << vec.size() << endl; // 实际元素个数
cout << "vector容量:" << vec.capacity() << endl; // 已分配内存能存储的元素数
vec.sort(vec.begin(), vec.end()); // 排序(升序)
cout << "排序后:";
for (int num : vec) cout << num << " ";
cout << endl;

vec.pop_back(); // 删除尾部元素
vec.clear(); // 清空所有元素
cout << "清空后大小:" << vec.size() << endl;

return 0;
}

2. 关联式容器:map(键值对存储)

map<key, value>键值对存储数据,key唯一且自动排序(升序),适合通过key快速查找value。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <map>
#include <string>

using namespace std;

int main() {
// 1. 创建map:key为string,value为int
map<string, int> scoreMap;

// 2. 插入元素
scoreMap["张三"] = 90; // 直接赋值(推荐)
scoreMap.insert(pair<string, int>("李四", 85)); // 用pair插入
scoreMap.insert({"王五", 95}); // C++11简化写法

// 3. 访问元素
cout << "张三的分数:" << scoreMap["张三"] << endl;
// 查找元素(避免访问不存在的key导致自动插入空值)
map<string, int>::iterator it = scoreMap.find("赵六");
if (it != scoreMap.end()) {
cout << "赵六的分数:" << it->second << endl;
} else {
cout << "赵六不存在" << endl;
}

// 4. 遍历map(迭代器)
cout << "所有成绩:" << endl;
for (auto iter = scoreMap.begin(); iter != scoreMap.end(); iter++) {
// iter->first 是key,iter->second 是value
cout << iter->first << ":" << iter->second << endl;
}

// 5. 常用操作
cout << "map大小:" << scoreMap.size() << endl;
scoreMap.erase("李四"); // 删除指定key的元素
scoreMap.clear(); // 清空

return 0;
}

3. 算法(Algorithms):通用操作函数

STL算法是独立的函数,通过迭代器操作容器,无需关心容器具体类型,下面是最常用的算法示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric> // 数值算法头文件

using namespace std;

int main() {
vector<int> vec = {5, 2, 8, 1, 9};

// 1. 排序:sort(升序)
sort(vec.begin(), vec.end());
cout << "升序排序:";
for (int num : vec) cout << num << " "; // 输出:1 2 5 8 9
cout << endl;

// 降序排序(用greater函数对象)
sort(vec.begin(), vec.end(), greater<int>());
cout << "降序排序:";
for (int num : vec) cout << num << " "; // 输出:9 8 5 2 1
cout << endl;

// 2. 查找:find
auto it = find(vec.begin(), vec.end(), 5);
if (it != vec.end()) {
cout << "找到5,位置:" << it - vec.begin() << endl; // 输出:2
}

// 3. 计数:count
int cnt = count(vec.begin(), vec.end(), 8);
cout << "8的个数:" << cnt << endl; // 输出:1

// 4. 求和:accumulate(需要numeric头文件)
int sum = accumulate(vec.begin(), vec.end(), 0); // 0是初始值
cout << "总和:" << sum << endl; // 输出:25

// 5. 反转:reverse
reverse(vec.begin(), vec.end());
cout << "反转后:";
for (int num : vec) cout << num << " "; // 输出:1 2 5 8 9
cout << endl;

return 0;
}

三、新手使用STL的注意事项

  1. 头文件必须包含:使用哪个容器/算法,就要包含对应的头文件(如vector对应<vector>sort对应<algorithm>)。
  2. 迭代器的边界end()指向的是”最后一个元素的下一位”,遍历结束条件是it != end(),而非it < end()
  3. 避免越界访问vector[]操作无越界检查,新手优先用at()(会抛异常,便于调试)。
  4. 选择合适的容器
    • 频繁随机访问、尾部增删 → vector
    • 频繁中间增删 → list
    • 按key查找 → map/unordered_map(后者查询更快)。

总结

  1. STL核心是容器(存数据)+ 迭代器(遍历)+ 算法(操作数据),三者通过迭代器解耦,用法统一;
  2. 新手优先掌握vector(动态数组)、map(键值对)和常用算法(sort/find/reverse),覆盖80%的日常场景;
  3. 使用STL时需注意头文件包含、迭代器边界和容器的选择,避免越界和性能问题。

我会为你详细梳理C++ STL中所有常用容器的核心操作,并提供一份完整、可直接运行的示例代码,覆盖每个容器的创建、增删改查、遍历等核心场景。

STL常用容器及核心操作总览

先明确本次覆盖的容器范围(新手必掌握):

容器类型 名称 特点 核心适用场景
序列式容器 vector 动态数组,随机访问快 频繁读取、尾部增删
序列式容器 list 双向链表,中间增删快 频繁插入/删除(非尾部)
序列式容器 deque 双端队列,两端增删快 队列/栈场景
关联式容器 set 有序不重复集合 去重、有序查找
关联式容器 map 有序键值对(key唯一) 按key查找value
无序容器 unordered_set 哈希集合,查询O(1) 快速去重、查找
无序容器 unordered_map 哈希键值对,查询O(1) 高频按key查询
容器适配器 stack 栈(后进先出) 栈操作(push/pop/top)
容器适配器 queue 队列(先进先出) 队列操作(push/pop/front)

完整示例代码(覆盖所有容器核心操作)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <stack>
#include <queue>
#include <algorithm> // 算法头文件
#include <string>

using namespace std;

// 打印分隔线,方便区分不同容器的输出
void printSeparator(const string& containerName) {
cout << "\n=====================================" << endl;
cout << "【" << containerName << " 操作示例】" << endl;
cout << "=====================================\n" << endl;
}

int main() {
// ===================== 1. vector(动态数组) =====================
printSeparator("vector");
vector<int> vec;
// 增
vec.push_back(10); // 尾部添加
vec.push_back(20);
vec.push_back(30);
vec.insert(vec.begin() + 1, 15); // 中间插入(位置:第2个元素前)
// 查
cout << "vector第1个元素:" << vec[0] << endl; // 下标访问(无越界检查)
cout << "vector第2个元素:" << vec.at(1) << endl; // at访问(有越界检查)
cout << "vector尾部元素:" << vec.back() << endl; // 尾部元素
cout << "vector大小:" << vec.size() << endl; // 元素个数
cout << "vector容量:" << vec.capacity() << endl; // 已分配内存大小
// 遍历
cout << "vector遍历:";
for (int num : vec) cout << num << " "; // 范围for
cout << endl;
// 改
vec[2] = 25; // 修改指定位置元素
cout << "修改后vector遍历:";
for (int num : vec) cout << num << " ";
cout << endl;
// 删
vec.pop_back(); // 删除尾部元素
vec.erase(vec.begin() + 1); // 删除指定位置元素
cout << "删除后vector遍历:";
for (int num : vec) cout << num << " ";
cout << endl;
vec.clear(); // 清空所有元素
cout << "清空后vector大小:" << vec.size() << endl;

// ===================== 2. list(双向链表) =====================
printSeparator("list");
list<string> lst;
// 增
lst.push_back("apple"); // 尾部添加
lst.push_front("banana"); // 头部添加
lst.insert(next(lst.begin()), "orange"); // 中间插入(需用next迭代器)
// 查
cout << "list头部元素:" << lst.front() << endl;
cout << "list尾部元素:" << lst.back() << endl;
cout << "list大小:" << lst.size() << endl;
// 遍历(list无下标,只能用迭代器/范围for)
cout << "list遍历:";
for (const string& s : lst) cout << s << " ";
cout << endl;
// 改(需先找到元素)
auto lstIt = find(lst.begin(), lst.end(), "orange");
if (lstIt != lst.end()) *lstIt = "grape";
cout << "修改后list遍历:";
for (const string& s : lst) cout << s << " ";
cout << endl;
// 删
lst.pop_front(); // 删除头部
lst.pop_back(); // 删除尾部
lst.erase(find(lst.begin(), lst.end(), "grape")); // 删除指定元素
cout << "删除后list遍历:";
for (const string& s : lst) cout << s << " ";
cout << endl;
lst.clear();

// ===================== 3. deque(双端队列) =====================
printSeparator("deque");
deque<int> dq;
// 增
dq.push_back(100); // 尾部添加
dq.push_front(200); // 头部添加
dq.insert(dq.begin() + 1, 150); // 中间插入
// 查
cout << "deque头部:" << dq.front() << endl;
cout << "deque尾部:" << dq.back() << endl;
cout << "deque第2个元素:" << dq[1] << endl; // 支持下标访问
// 遍历
cout << "deque遍历:";
for (int num : dq) cout << num << " ";
cout << endl;
// 删
dq.pop_front();
dq.pop_back();
cout << "删除后deque遍历:";
for (int num : dq) cout << num << " ";
cout << endl;
dq.clear();

// ===================== 4. set(有序不重复集合) =====================
printSeparator("set");
set<int> s;
// 增(自动去重、自动升序)
s.insert(5);
s.insert(2);
s.insert(8);
s.insert(2); // 重复元素,插入无效
// 查
cout << "set大小:" << s.size() << endl;
auto setIt = s.find(5); // 查找元素,返回迭代器
if (setIt != s.end()) cout << "找到元素:" << *setIt << endl;
// 遍历(默认升序)
cout << "set遍历(升序):";
for (int num : s) cout << num << " ";
cout << endl;
// 删
s.erase(2); // 删除指定值的元素
cout << "删除后set遍历:";
for (int num : s) cout << num << " ";
cout << endl;
s.clear();

// ===================== 5. map(有序键值对) =====================
printSeparator("map");
map<string, int> mp;
// 增
mp["张三"] = 90; // 直接赋值
mp.insert({"李四", 85}); // insert方式
mp.insert(pair<string, int>("王五", 95));
// 查
cout << "张三的分数:" << mp["张三"] << endl;
auto mapIt = mp.find("李四");
if (mapIt != mp.end()) cout << "李四的分数:" << mapIt->second << endl;
// 遍历(按key升序)
cout << "map遍历:" << endl;
for (const auto& pair : mp) {
cout << pair.first << ":" << pair.second << endl;
}
// 改
mp["张三"] = 92; // 修改value
// 删
mp.erase("王五"); // 按key删除
cout << "删除后map遍历:" << endl;
for (const auto& pair : mp) {
cout << pair.first << ":" << pair.second << endl;
}
mp.clear();

// ===================== 6. unordered_set(哈希集合) =====================
printSeparator("unordered_set");
unordered_set<string> uset;
// 增(无序、去重,查询比set快)
uset.insert("cat");
uset.insert("dog");
uset.insert("bird");
// 查
cout << "是否存在dog:" << (uset.find("dog") != uset.end() ? "是" : "否") << endl;
// 遍历(无序)
cout << "unordered_set遍历:";
for (const string& animal : uset) cout << animal << " ";
cout << endl;
uset.erase("cat");
uset.clear();

// ===================== 7. unordered_map(哈希键值对) =====================
printSeparator("unordered_map");
unordered_map<int, string> umap;
// 增(无序,查询比map快)
umap[101] = "语文";
umap[102] = "数学";
umap[103] = "英语";
// 查
cout << "102对应的科目:" << umap[102] << endl;
// 遍历(无序)
cout << "unordered_map遍历:" << endl;
for (const auto& pair : umap) {
cout << pair.first << ":" << pair.second << endl;
}
umap.erase(101);
umap.clear();

// ===================== 8. stack(栈,适配器) =====================
printSeparator("stack");
stack<int> stk;
// 增(只能尾部添加)
stk.push(1);
stk.push(2);
stk.push(3);
// 查(只能看栈顶)
cout << "栈顶元素:" << stk.top() << endl;
cout << "栈大小:" << stk.size() << endl;
// 删(只能删栈顶)
stk.pop();
cout << "出栈后栈顶:" << stk.top() << endl;
cout << "栈是否为空:" << (stk.empty() ? "是" : "否") << endl;
// 清空(无clear,需循环pop)
while (!stk.empty()) stk.pop();

// ===================== 9. queue(队列,适配器) =====================
printSeparator("queue");
queue<string> que;
// 增(尾部添加)
que.push("A");
que.push("B");
que.push("C");
// 查(看队首/队尾)
cout << "队首元素:" << que.front() << endl;
cout << "队尾元素:" << que.back() << endl;
// 删(队首删除)
que.pop();
cout << "出队后队首:" << que.front() << endl;
// 清空
while (!que.empty()) que.pop();

return 0;
}

代码运行说明

  1. 编译环境:支持C++11及以上的编译器(如GCC、Clang、MSVC);
  2. 编译命令(Linux/macOS):g++ -std=c++11 stl_container.cpp -o stl_container
  3. 运行./stl_container
  4. 输出:每个容器的操作会按顺序输出,包含增删改查、遍历的结果,便于你对照理解。

各容器核心操作总结

容器 核心新增操作 核心删除操作 核心访问方式 特殊点
vector push_back、insert pop_back、erase、clear []、at、front、back 支持随机访问,动态扩容
list push_back、push_front、insert pop_back、pop_front、erase front、back(无下标) 双向链表,中间增删快
deque push_back、push_front、insert pop_back、pop_front、erase []、front、back 双端队列,两端操作快
set insert erase、clear find(迭代器访问) 有序、去重,无修改操作
map []赋值、insert erase(按key)、clear []、find(->first/second) key唯一,有序
unordered_set insert erase、clear find 无序、哈希,查询O(1)
unordered_map []赋值、insert erase(按key)、clear []、find 无序、哈希,查询比map快
stack push pop top 后进先出,无遍历/下标
queue push pop front、back 先进先出,无遍历/下标

总结

  1. 序列式容器(vector/list/deque):核心关注”增删的位置”(尾部/头部/中间),vector支持随机访问,list适合中间增删,deque兼顾两端操作;
  2. 关联式/无序容器(set/map/unordered_*):核心是”按值/键操作”,set/map自动排序,unordered_*基于哈希查询更快;
  3. 容器适配器(stack/queue):操作受限(栈:仅栈顶;队列:仅队首/队尾),适合特定的先进后出/先进先出场景。

这份代码覆盖了每个容器的高频操作,你可以直接运行并修改参数,直观理解每个操作的效果,是新手入门STL容器的最佳实践模板。