news 2026/7/4 3:40:26

HoRain云--C++STL教程:从入门到精通

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HoRain云--C++STL教程:从入门到精通

🎬 HoRain 云小助手:个人主页

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

目录

⛳️ 推荐

📚 C++ STL 教程:从"能跑"到"不踩坑"

🎯 STL 三大件一句话

📦 六大容器家族速查

1️⃣ vector—— 动态数组(≈ Java ArrayList)

2️⃣ list—— 双向链表(≈ Java LinkedList)

3️⃣ deque—— 双端队列(Java 没有严格对等)

4️⃣ map—— 红黑树(≈ Java TreeMap)

5️⃣ unordered_map—— 哈希表(≈ Java HashMap)

6️⃣ set/ unordered_set—— 只存 key 不存 value

🔄 迭代器(C++ 独有概念,Java 只有 Iterator一种)

🛠️ 算法 (STL 的精华)

🧵 string—— 不是 STL 容器但像容器

⚠️ 迭代器失效(C++ 特有,Java 没有这坑)

🆚 跟 Java 集合对照表(你前面 Java LinkedList/String 都看过)

🧩 一段"能打"的综合示例

🎯 学习路线建议


📚 C++ STL 教程:从"能跑"到"不踩坑"

STL(Standard Template Library)是 C++ 的"武器库",你前面看完类/多态/动态内存,STL 是下一块——它跟 Java 集合框架(Collections Framework)能对上,但 C++ 多了"迭代器 + 算法分离"这套设计,是 C++ 特有的味道。

🎯 STL 三大件一句话

组件

干嘛的

类比 Java

容器(Containers)

存数据

ArrayList,HashMap...

算法(Algorithms)

操作数据(sort,find...)

Collections.sort(), Stream API

迭代器(Iterators)

容器和算法之间的胶水

Iterator

C++ 的设计哲学:容器只管存,算法只管算,迭代器把它们粘起来。Java 的ArrayList.sort()是把算法绑在容器上的,两套思路。


📦 六大容器家族速查

1️⃣vector—— 动态数组(≈ JavaArrayList

最常用,没有之一。连续内存,随机访问 O(1),尾插 O(1) 均摊。

#include <vector> #include <iostream> std::vector<int> v = {1, 2, 3}; v.push_back(4); // 尾插 O(1) v.emplace_back(5); // 比 push_back 更高效(就地构造) std::cout << v[2]; // 3,不越界检查 std::cout << v.at(10); // 抛 std::out_of_range(慢一点但安全) // 遍历 for (int x : v) std::cout << x << " "; // range-for(C++11)

💡emplace_backvspush_backpush_back(T(val))是先构造临时对象再移动,emplace_back(val)直接在容器里构造,少一次拷贝/移动,对象重时明显。

2️⃣list—— 双向链表(≈ JavaLinkedList

#include <list> std::list<int> lst = {1, 2, 3}; lst.push_front(0); // 头插 O(1) lst.push_back(4); // 尾插 O(1) lst.reverse(); // 链表专属

list没有[]随机访问,要取第 i 个得std::advance(it, i)走 i 步 O(n)。

3️⃣deque—— 双端队列(Java 没有严格对等)

头尾插删都 O(1),比vector多一个头插能力,比list多随机访问。

#include <deque> std::deque<int> dq; dq.push_front(1); dq.push_back(2); std::cout << dq[0]; // 1,能随机访问

stack/queue底层默认用deque

4️⃣map—— 红黑树(≈ JavaTreeMap

按键有序,O(log n) 查插删。

#include <map> #include <string> std::map<std::string, int> scores = { {"Alice", 90}, {"Bob", 85} }; scores["Charlie"] = 95; // 插入/修改 int a = scores["Alice"]; // 90,不存在会插入默认值! // 安全查 if (scores.contains("Dave")) { // C++20 // ... } auto it = scores.find("Dave"); // C++11 起最佳做法 if (it != scores.end()) { // ... }

5️⃣unordered_map—— 哈希表(≈ JavaHashMap

无序,平均 O(1),比map快但要算 hash。

#include <unordered_map> std::unordered_map<std::string, int> um = { {"Apple", 10}, {"Banana", 5} }; um["Orange"] = 8; std::cout << um["Apple"]; // 10

📌 选型:要顺序/范围查询 →map;要纯 KV 查 →unordered_map。跟 Java 的TreeMapvsHashMap完全同逻辑。

6️⃣set/unordered_set—— 只存 key 不存 value

#include <set> std::set<int> s = {3, 1, 2}; s.insert(4); for (int x : s) std::cout << x << " "; // 1 2 3 4(有序)

🔄 迭代器(C++ 独有概念,Java 只有Iterator一种)

std::vector<int> v = {10, 20, 30}; // 经典写法 for (auto it = v.begin(); it != v.end(); ++it) { std::cout << *it << " "; } // C++11 range-for(底层就是迭代器) for (int x : v) { std::cout << x << " "; } // C++20 ranges(更爽,但先不展开)

迭代器分类(面试会问):

  • 输入 / 输出:单向,只读/只写

  • 前向:单向,可读写

  • 双向--it也能走(list,map,set

  • 随机访问it + 5,it1 - it2vector,deque,string

💡vector的迭代器就是指针,list的迭代器是节点指针包装——所以vector能随机访问,list不能。


🛠️ 算法<algorithm>(STL 的精华)

#include <algorithm> #include <vector> #include <iostream> std::vector<int> v = {3, 1, 4, 1, 5}; // 排序 std::sort(v.begin(), v.end()); // 升序 std::sort(v.begin(), v.end(), std::greater<int>()); // 降序 // 查找 auto it = std::find(v.begin(), v.end(), 4); // 返回迭代器 if (it != v.end()) std::cout << "found\n"; // 计数 int cnt = std::count(v.begin(), v.end(), 1); // 2 // 遍历修改(C++11 lambda) std::for_each(v.begin(), v.end(), [](int x) { std::cout << x << " "; }); // 变换到新容器 std::vector<int> doubled(v.size()); std::transform(v.begin(), v.end(), doubled.begin(), [](int x) { return x * 2; });

跟 Java 对比:std::sort(v.begin(), v.end())Collections.sort(list),但 C++ 的算法是独立于容器的——同一个sort能排vector/deque/ 原生数组,只要给随机访问迭代器。


🧵string—— 不是 STL 容器但像容器

你前面看了 JavaString(不可变),C++std::string是可变的,这点最容易被 Java 人搞混。

#include <string> std::string s = "hello"; s += ", world"; // ✅ 可变,Java 这步要 new s[0] = 'H'; // "Hello, world" // 常用 s.size(); // 长度 s.empty(); // 是否空 s.substr(0, 5); // "Hello"(左闭右开) s.find("world"); // 7,没找到返回 std::string::npos // C++14 起 string 也是连续存储,能当 `vector<char>` 用但语义更清楚

⚠️ C++std::string≠ JavaString:Java 不可变+常量池,C++ 可变+值语义+可reserve()。混着记会踩坑。


⚠️ 迭代器失效(C++ 特有,Java 没有这坑)

改容器结构可能导致迭代器作废——这是 STL 最容易翻车的地方。

std::vector<int> v = {1, 2, 3, 4, 5}; for (auto it = v.begin(); it != v.end(); ++it) { if (*it == 3) { v.erase(it); // ❌ it 已失效,下次 ++it UB } } // ✅ 正确:erase 返回下一个有效迭代器 for (auto it = v.begin(); it != v.end(); ) { if (*it == 3) { it = v.erase(it); // erase 返回下一个 } else { ++it; } }

各容器失效规则速记:

操作

vector

deque

list

map/set

unordered_*

尾插

尾 iter 可能失效

全有效

全有效

全有效

可能全失效(rehash)

中间删

被删及之后失效

被删及之后失效

只被删失效

只被删失效

只被删失效

一句话:vector最娇气,list/map最稳,unordered_*rehash 时全炸


🆚 跟 Java 集合对照表(你前面 Java LinkedList/String 都看过)

C++ STL

Java 集合

备注

vector

ArrayList

连续数组,随机访问

list

LinkedList

双向链表

deque

无严格对等

ArrayDeque接近但不支持随机访问

map

TreeMap

红黑树,有序

unordered_map

HashMap

哈希,无序

set/unordered_set

无直接对等

HashSetHashMap的马甲

sort()

Collections.sort()

C++ 算法独立于容器

string

String+StringBuilder

C++ 可变,Java String 不可变


🧩 一段"能打"的综合示例

#include <iostream> #include <vector> #include <unordered_map> #include <algorithm> #include <string> struct Student { std::string name; int score; }; int main() { std::vector<Student> students = { {"Alice", 90}, {"Bob", 85}, {"Charlie", 95} }; // 按分数降序 std::sort(students.begin(), students.end(), [](const Student& a, const Student& b) { return a.score > b.score; }); // 统计分数分布 std::unordered_map<int, int> dist; for (const auto& s : students) { dist[s.score / 10 * 10]++; // 90分段、80分段... } for (const auto& [range, cnt] : dist) { std::cout << range << "-" << range+9 << ": " << cnt << "\n"; } }

🎯 学习路线建议

STL 不用背全(一百多个算法没人全记得),容器会挑 + 迭代器懂失效 + 算法记sort/find/transform就够 80% 场景

顺着你这条线(类 → 抽象 → 多态 → 动态内存 → STL),下一块自然落到C++11 新特性(auto、lambda、范围 for、智能指针你已经看过一部分),或者STL 源码浅读(vector扩容 /unordered_map冲突)——前者偏"写代码爽",后者偏面试八股。要哪边?

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/4 3:39:22

Perplexity Ask:AI原生搜索如何重构技术信息获取范式

1. 这不是传统搜索&#xff0c;而是一次信息获取方式的重置Perplexity Ask 这个名字听起来像某个学术论文里的术语&#xff0c;但实际用起来&#xff0c;它彻底改变了我每天处理信息的习惯——不是“搜关键词→点链接→跳转→扫读→再搜”&#xff0c;而是“把问题自然说出来→…

作者头像 李华
网站建设 2026/7/4 3:39:11

Radeon 显卡加速开启指南,别让大模型跑在 CPU 上

为什么你的大模型跑得像 PPT&#xff1f; 最近不少朋友反馈&#xff0c;明明入手了搭载 Strix Halo 架构的新本&#xff0c;配置了 32GB 甚至 64GB 大内存&#xff0c;兴致勃勃地部署了本地大模型&#xff0c;结果生成速度却慢得让人怀疑人生。看着屏幕上一个个字往外“挤”&am…

作者头像 李华
网站建设 2026/7/4 3:38:34

光伏混合能源系统架构与MPPT优化设计

1. 光伏混合能源系统的核心架构解析 这套"光伏发电Boost储能双向DCDC并网逆变器"系统代表了当前分布式能源领域的前沿配置方案。作为从业12年的新能源电力电子工程师&#xff0c;我参与过数十个类似项目的落地实施&#xff0c;这种架构最大的优势在于实现了"光伏…

作者头像 李华
网站建设 2026/7/4 3:37:30

如何构建制造企业的大模型平台

构建制造企业的大模型&#xff08;LLM&#xff09;平台&#xff0c;不能照搬互联网或金融行业的模式。制造企业有着极强的物理世界属性&#xff08;如设备、工艺参数、供应链、安全红线&#xff09;&#xff0c;且数据往往碎片化、存在于不同的工业软件&#xff08;ERP, MES, P…

作者头像 李华