正版资源网校 21天学通C++(第六版)-365资源论坛提供
《网校 21天学通C++(第六版)-365资源论坛提供》第20章 STL set与multiset【技能收获】学完可掌握:C/C++ 网络编程、Vue / 前端工程化。课程以实战为导向,覆盖从基础概念到完整项目落地的关键步骤,配套章节笔记便于课后复盘与面试前快速回顾。【学习建议】建议按目录顺序学习,先打基础再进入综合实战章节;每完成 2~3 节可结合笔记整理一份学习小结,最终尝试独立复现一套完整 Demo 写入个人作品集。【就业发展】可面向岗位:Linux 运维工程师、SRE、云计算工程师、DevOps 工程师。云原生与自动化运维仍是企业 IT 刚需方向,认证 + 实战项目组合能显著提升面试通
这套《21天学通C++(第六版)》的网校课程,定位不是"看完就会写C++"的速成班,而是一份可以边看边敲、按章节对照练习的工程化入门资料。它的价值集中在两点:一是把C++标准库的常用容器讲得足够细,二是给了可复用的章节笔记框架,方便回头查漏。下面按技术栈、结构、复用模块和自学路径拆开说。
这套资料的技术栈定位
课程主体是C++语言基础加标准模板库(STL)。从线索看,第20章专门讲STL的 set 与 multiset,说明后半程的落点放在容器与算法的实际使用上,而不是停留在语法罗列。set/multiset 属于关联式容器,底层通常实现为红黑树,插入、删除、查找都是对数复杂度,元素自动有序且 set 不允许重复、multiset 允许重复。这一章如果讲透,会顺带带出迭代器分类、仿函数比较器、自定义排序规则这些后续写工程代码绕不开的点。
需要说明的是,摘要里提到的网络编程、Vue 前端工程化、Linux 运维等方向,与本课程主题并不直接对应,更像是资料包在多个课程间混排的内容。真正能从中拿到的是C++语言本身和STL的动手能力,把它当成C++基础资料来用更准确。
项目结构与内容组织
课程按"21天"切分节奏,本质是章节化的进度安排。这种结构的工程意义在于:每一节对应一个可独立验证的知识点,学完就能写一小段代码跑通。前半段通常是变量、流程控制、函数、指针与引用、类与对象,后半段进入运算符重载、继承多态、模板,再到STL容器和算法。set/multiset 所在的第20章已经接近容器部分的收尾,前面的 vector、list、map 等应该已经铺过,学到这里更适合做横向对比:什么时候用 set 去重、什么时候用 multiset 统计频次、什么时候干脆用 unordered_set 换哈希性能。
可以复用的几个模块
- 容器对比表:把 vector / list / map / set / multiset 的底层结构、复杂度、典型场景整理在一张表里,写业务代码时直接查,比翻视频快。
- 自定义比较器:set 和 multiset 都支持传入比较规则,把"按结构体某字段排序去重"封装成独立仿函数或 lambda,是面试和工程里都常见的写法。
- 迭代器遍历模板:范围 for、迭代器自增、erase 时迭代器失效的处理,这几个坑单独记一份笔记,能省掉大量调试时间。
- 笔记复盘格式:按"概念—最小可运行示例—易错点—替代方案"四栏整理,每完成两三节写一份,考前和面试前直接翻。
自学路径与用法建议
建议按章节顺序推进,但不要只做"看"这一步。每看完一节,先合上视频自己默写一遍示例,再对照检查差异。进入STL部分后,刻意做容器替换练习:同一道去重题,分别用 vector + sort + unique、set、unordered_set 实现一遍,比较代码量和运行结果。第20章这类容器章节尤其适合这种横向练法,因为它本身知识点不复杂,难点在于选型和边界处理。
整体来看,这套资料适合拿来当C++入门的对照实践材料:看一节、写一段、留一份笔记。它不会替你建立完整的工程能力,但能帮你在容器使用、迭代器操作、代码组织习惯上打下一个可查、可复用的底子。配合自己写的练习代码一起推进,比单纯刷视频的留存率高得多。
第20章 STL set与multiset
课程推荐
《网校 21天学通C++(第六版)-365资源论坛提供》第20章 STL set与multiset【技能收获】学完可掌握:C/C++ 网络编程、Vue / 前端工程化。课程以实战为导向,覆盖从基础概念到完整项目落地的关键步骤,配套章节笔记便于课后复盘与面试前快速回顾。【学习建议】建议按目录顺序学习,先打基础再进入综合实战章节;每完成 2~3 节可结合笔记整理一份学习小结,最终尝试独立复现一套完整 Demo 写入个人作品集。【就业发展】可面向岗位:Linux 运维工程师、SRE、云计算工程师、DevOps 工程师。云原生与自动化运维仍是企业 IT 刚需方向,认证 + 实战项目组合能显著提升面试通过率,适合向中高级运维或架构岗进阶。 若你已有一定编程或运维基础,本课程可帮助你在现有技能栈上快速叠加热门方向能力,提升求职时的项目说服力与薪资谈判空间。
视频目录(453 节)
* 1.1 C++简史
* 1.1.1 解释器和编译器
* 1.1.2 不断变化的需求和平台
* 1.1.3 过程化编程、结构化编程和面向对象编程
* 1.1.4 面向对象编程(OOP)
* 1.1.5 C++和面向对象编程
* 1.2 C++的发展历程
* 1.3 应该先学习C语言吗
* 1.4 微软的C++托管扩展
* 1.5 ANSI标准
* 1.6 编程准备
* 1.7 开发环境
* 1.8 创建程序的步骤
* 1.8.1 用编译器生成对象文件
* 1.8.2 用链接器生成可执行文件
* 1.9 程序开发周期
* 1.10 HELLO.cpp:第一个C++程序
* 1.11 编译器初步
* 1.12 编译错误
* 2.1 一个简单程序
* 2.2 cout简介
* 2.3 使用标准名称空间
* 2.4 对程序进行注释
* 2.4.1 注释的类型
* 2.4.2 使用注释
* 2.4.3 有关注释的警告
* 2.5 函数
* 2.5.1 使用函数
* 2.5.2 方法和函数
* 3.1 什么是变量
* 3.1.1 将数据存储在内存中
* 3.1.2 预留内存
* 3.1.3 整型变量的大小
* 3.1.4 基本变量类型
* 3.2 定义变量
* 3.2.1 区分大小写
* 3.2.2 命名规则
* 3.2.3 关键字
* 3.3 确定变量类型占用的内存量
* 3.4 一次创建多个变量
* 3.5 给变量赋值
* 3.6 使用typedef创建别名
* 3.7 何时使用short和long
* 3.7.1 unsigned整型变量的回绕
* 3.7.2 signed整型变量的回绕
* 3.8 使用字符
* 3.8.1 字符和数字
* 3.8.2 特殊打印字符
* 3.9 常量
* 3.9.1 字面常量
* 3.9.2 符号常量
* 3.10 枚举常量
* 4.1 什么是数组
* 4.1.1 访问数组元素
* 4.1.2 在数组末尾后写入数据
* 4.1.3 护栏柱错误
* 4.1.4 初始化数组
* 4.1.5 声明数组
* 4.2 使用多维数组
* 4.2.1 声明多维数组
* 4.2.2 初始化多维数组
* 4.3 字符数组和字符串
* 4.4 使用方法strcpy()和strncpy()
* 4.5 string类
* 5.1 语句简介
* 5.1.1 使用空白
* 5.1.2 语句块和复合语句
* 5.2 表达式
* 5.3 使用运算符
* 5.3.1 赋值运算符
* 5.3.2 数学运算符
* 5.3.3 整数除法和求模
* 5.4 结合使用赋值运算符与数学运算符
* 5.5 递增和递减
* 5.6 理解运算符优先级
* 5.7 括号的嵌套
* 5.8 真值的本质
* 5.9 if语句
* 5.9.1 缩进风格
* 5.9.2 else语句
* 5.9.3 高级if语句
* 5.10 在嵌套if语句中使用大括号
* 5.11 使用逻辑运算符
* 5.11.1 逻辑AND运算符
* 5.11.2 逻辑OR运算符
* 5.11.3 逻辑NOT运算符
* 5.12 简化求值
* 5.13 关系运算符的优先级
* 5.14 再谈真和假
* 5.15 条件运算符(三目运算符)
* 6.1 什么是函数
* 6.2 返回值、参数和实参
* 6.3 声明和定义函数
* 6.3.1 函数原型
* 6.3.2 定义函数
* 6.4 函数的执行
* 6.5 确定变量的作用域
* 6.5.1 局部变量
* 6.5.2 作用域为语句块的局部变量
* 6.6 参数是局部变量
* 6.6.1 全局变量
* 6.6.2 有关全局变量的注意事项
* 6.7 创建函数语句时的考虑因素
* 6.8 再谈函数实参
* 6.9 再谈返回值
* 6.10 默认参数
* 6.11 重载函数
* 6.12 函数特有的主题
* 6.12.1 内联函数
* 6.12.2 递归
* 6.13 函数的工作原理
* 6.13.1 抽象层次
* 6.13.2 划分RAM
* 6.13.3 堆栈和函数
* 7.1 循环
* 7.1.1 循环的鼻祖:goto
* 7.1.2 为何避免使用goto语句
* 7.2 使用while循环
* 7.2.1 更复杂的while语句
* 7.2.2 continue和break简介
* 7.2.3 while(true)循环
* 7.3 实现do...while循环
* 7.4 使用do...while
* 7.5 for循环
* 7.5.1 高级for循环
* 7.5.2 空for循环
* 7.5.3 循环嵌套
* 7.5.4 for循环中声明的变量的作用域
* 7.6 循环小结
* 7.7 使用switch语句控制程序流程
* 8.1 什么是指针
* 8.1.1 内存简介
* 8.1.2 获取变量的内存地址
* 8.1.3 将变量的地址存储到指针中
* 8.1.4 指针名
* 8.1.5 获取指针指向的变量的值
* 8.1.6 使用间接运算符解除引用
* 8.1.7 指针、地址和变量
* 8.1.8 使用指针来操纵数据
* 8.1.9 查看地址
* 8.1.10 指针和数组名
* 8.1.11 数组指针和指针数组
* 8.2 为什么使用指针
* 8.3 栈和自由存储区(堆)
* 8.3.1 使用关键字new分配内存
* 8.3.2 使用关键字delete归还内存
* 8.4 再谈内存泄漏
* 8.5 在自由存储区上创建对象
* 8.6 删除自由存储区中的对象
* 8.7 迷途指针
* 8.8 使用const指针
* 9.1 什么是引用
* 9.2 将地址运算符用于引用
* 9.3 空指针和空引用
* 9.4 按引用传递函数参数
* 9.4.1 使用指针让swap()管用
* 9.4.2 使用引用来实现swap()
* 9.5 返回多个值
* 9.6 按引用传递以提高效率
* 9.6.1 传递const指针
* 9.6.2 用引用代替指针
* 9.7 何时使用引用和指针
* 9.8 混合使用引用和指针
* 9.9 返回指向不在作用域中的对象的引用
* 10.1 C++是面向对象的吗
* 10.2 创建新类型
* 10.3 类和成员简介
* 10.3.1 声明类
* 10.3.2 有关命名规则的说明
* 10.3.3 定义对象
* 10.3.4 类与对象
* 10.4 访问类成员
* 10.4.1 给对象而不是类赋值
* 10.4.2 类不能有没有声明的功能
* 10.5 私有和公有
* 10.6 实现类方法
* 10.7 添加构造函数和析构函数
* 10.7.1 默认构造函数和析构函数
* 10.7.2 使用默认构造函数
* 10.8 const成员函数
* 10.9 将类声明和方法定义放在什么地方
* 10.10 内联实现
* 10.11 将其他类用作成员数据的类
* 10.12 探索结构
* 11.1 什么是继承
* 11.1.1 继承和派生
* 11.1.2 动物世界
* 11.1.3 派生的语法
* 11.2 私有和保护
* 11.3 构造函数和析构函数的继承性
* 11.4 覆盖基类函数
* 11.4.1 隐藏基类的方法
* 11.4.2 调用基类方法
* 11.5 虚方法
* 11.5.1 虚函数的工作原理
* 11.5.2 通过基类指针访问派生类的方法
* 11.5.3 切除
* 11.5.4 创建虚析构函数
* 11.5.5 虚复制构造函数
* 11.5.6 使用虚方法的代价
* 11.6 私有继承
* 11.6.1 使用私有继承
* 11.6.2 私有继承和聚合(组合)
* 12.1 单继承存在的问题
* 12.1.1 提升
* 12.1.2 向下转换
* 12.1.3 将对象添加到链表中
* 12.2 多重继承
* 12.2.1 多重继承对象的组成部分
* 12.2.2 多重继承对象中的构造函数
* 12.2.3 避免歧义
* 12.2.4 从共同基类继承
* 12.2.5 虚继承
* 12.2.6 多重继承存在的问题
* 12.2.7 混合(功能)类
* 12.3 抽象数据类型
* 12.3.1 纯虚函数
* 12.3.2 实现纯虚函数
* 12.3.3 复杂的抽象层次结构
* 12.3.4 哪些类是抽象的
* 13.1 C++中的运算符
* 13.2 单目运算符
* 13.2.1 单目运算符的类型
* 13.2.2 单目递增与单目递减运算符
* 13.2.3 解除引用运算符*与成员选择运算符-的编程
* 13.2.4 转换运算符的编程
* 13.3 双目运算符
* 13.3.1 双目运算符的类型
* 13.3.2 双目加与双目减运算符的编程
* 13.3.3 运算符+=与-=的编程
* 13.3.4 重载比较运算符
* 13.3.5 重载运算符、、=和=
* 13.3.6 下标运算符
* 13.4 operator()函数
* 13.5 不能重新定义的运算符
* 14.1 什么是类型转换
* 14.2 为何需要类型转换
* 14.3 为何有些C++程序员不喜欢C风格类型转换
* 14.4 C++类型转换运算符
* 14.4.1 使用static_cast
* 14.4.2 使用dynamic_cast和运行阶段类型识别
* 14.4.3 使用reinterpret_cast
* 14.4.4 使用const_cast
* 14.5 C++类型转换运算符存在的问题
* 15.1 预处理器与编译器
* 15.2 预处理器指令#define
* 15.3 宏函数
* 15.3.1 为什么要使用括号
* 15.3.2 宏与类型安全问题
* 15.3.3 宏与函数及模板之比较
* 15.3.4 内联函数
* 15.4 模板简介
* 15.4.1 模板声明语法
* 15.4.2 各种类型的模板声明
* 15.4.3 模板类
* 15.4.4 模板的实例化和具体化
* 15.4.5 模板与类型安全
* 15.4.6 使用多个参数声明模板
* 15.4.7 使用默认参数来声明模板
* 15.4.8 一个模板示例
* 15.4.9 在实际C++编程中使用模板
* 16.1 STL容器
* 16.1.1 顺序容器
* 16.1.2 关联容器
* 16.1.3 选择正确的容器
* 16.2 STL迭代器
* 16.3 STL算法
* 16.4 使用迭代器在容器和算法之间交互
* 17.1 为何需要字符串操作类
* 17.2 使用STL string类
* 17.2.1 实例化STL string及复制
* 17.2.2 访问string及其内容
* 17.2.3 字符串连接
* 17.2.4 在string中查找字符或子字符串
* 17.2.5 截短STL string
* 17.2.6 字符串反转
* 17.2.7 字符串的大小写转换
* 17.3 基于模板的STL string实现
* 18.1 std::vector的特点
* 18.2 典型的vector操作
* 18.2.1 实例化vector
* 18.2.2 在vector中插入元素
* 18.2.3 访问vector中的元素
* 18.2.4 删除vector中的元素
* 18.3 理解size()和capacity()
* 18.4 STL deque 类
* 19.1 std::list的特点
* 19.2 基本的list操作
* 19.2.1 实例化std::list对象
* 19.2.2 在list开头插入元素
* 19.2.3 在list末尾插入元素
* 19.2.4 在list中间插入元素
* 19.2.5 删除list中的元素
* 19.3 对list中元素进行反转和排序
* 19.3.1 反转元素的排列顺序
* 19.3.2 元素排序
* 20.1 简介
* 20.2 STL set和multiset的基本操作
* 20.2.1 实例化std::set对象
* 20.2.2 在STL set或multiset中插入元素
* 20.2.3 在STL set或multiset中查找元素
* 20.2.4 删除STL set或multiset中的元素
* 20.3 使用STL set和multiset的优缺点
* 21.1 简介
* 21.2 STL map和multimap的基本操作
* 21.2.1 实例化std::map对象
* 21.2.2 在STL map或multimap中插入元素
* 21.2.3 在STL map或multimap中查找元素
* 21.2.4 删除STL map或multimap中的元素
* 21.3 提供自定义的排序谓词
* 22.1 函数对象与谓词的概念
* 22.2 函数对象的典型用途
* 22.2.1 一元函数
* 22.2.2 一元谓词
* 22.2.3 二元函数
* 22.2.4 二元谓词
* 23.1 什么是STL算法
* 23.2 STL算法的分类
* 23.2.1 非变序算法
* 23.2.2 变序算法
* 23.3 STL算法的应用
* 23.3.1 计算元素个数与查找元素
* 23.3.2 在集合中搜索元素或序列
* 23.3.3 将容器中的元素初始化为指定值
* 23.3.4 用for_each处理范围内的元素
* 23.3.5 使用std::transform对范围进行变换
* 23.3.6 复制和删除操作
* 23.3.7 替换值以及替换满足给定条件的元素
* 23.3.8 排序、在有序集合中搜索以及删除重复元素
* 23.3.9 将范围分区
* 23.3.10 在有序集合中插入元素
* 24.1 栈和队列的行为特征
* 24.1.1 栈
* 24.1.2 队列
* 24.2 使用STL stack类
* 24.2.1 实例化stack
* 24.2.2 stack的成员函数
* 24.3 使用STL queue类
* 24.3.1 实例化queue
* 24.3.2 queue的成员函数
* 24.4 使用STL优先级队列
* 24.4.1 实例化priority_queue类
* 24.4.2 priority_queue的成员函数
* 25.1 bitset类
* 25.2 使用std::bitset及其成员
* 25.2.1 std:bitset的运算符
* 25.2.2 std::bitset的成员方法
* 25.3 vectorbool
* 25.3.1 实例化vectorbool
* 25.3.2 使用vectorbool
* 26.1 什么是智能指针
* 26.1.1 使用常规(原始)指针有何问题
* 26.1.2 智能指针有何帮助
* 26.2 智能指针是如何实现的
* 26.3 智能指针类型
* 26.3.1 深度复制
* 26.3.2 写时复制机制
* 26.3.3 引用计数智能指针
* 26.3.4 引用链接智能指针
* 26.3.5 破坏性复制
* 26.4 使用std::auto_ptr
* 26.5 流行的智能指针库
* 27.1 流概述
* 27.1.1 数据流的封装
* 27.1.2 理解缓冲技术
* 27.2 流和缓冲区
* 27.3 标准I/O对象
* 27.4 重定向标准流
* 27.5 使用cin进行输入
* 27.5.1 输入字符串
* 27.5.2 字符串的问题
* 27.5.3 的返回值
* 27.6 cin的其他成员函数
* 27.6.1 单字符输入
* 27.6.2 从标准输入读取字符串
* 27.6.3 使用cin.ignore()
* 27.6.4 查看和插入字符:peek()和putback()
* 27.7 使用cout进行输出
* 27.7.1 刷新输出
* 27.7.2 执行输出的函数
* 27.7.3 控制符、标记和格式化指令
* 27.8 流和printf()函数之比较
* 27.9 文件输入和输出
* 27.9.1 使用ofstream
* 27.9.2 条件状态
* 27.9.3 打开文件进行输入和输出
* 27.9.4 修改ofstream打开文件时的默认行为
* 27.10 二进制文件和文本文件
* 27.11 命令行处理
* 28.1 程序中的各种错误
* 28.2 异常的基本思想
* 28.2.1 异常处理的组成部分
* 28.2.2 手工引发异常
* 28.2.3 创建异常类
* 28.3 使用try块和catch块
* 28.4 捕获异常的工作原理
* 28.4.1 使用多条catch语句
* 28.4.2 异常层次结构
* 28.5 异常中的数据及给异常对象命名
* 28.6 异常和模板
* 28.7 没有错误的异常
* 28.8 bug和调试
* 28.8.1 断点
* 28.8.2 监视点
* 28.8.3 查看内存
* 28.8.4 查看汇编代码
* 28.9 总结
* 28.10 问与答
* 28.11 作业
* 28.11.1 测验
* 28.11.2 练习
* 29.1 预处理器和编译器
* 29.2 预编译器指令#define
* 29.2.1 使用#define定义常量
* 29.2.2 将#define用于检测
* 29.2.3 预编译器命令#else
* 29.3 包含和防范多重包含
* 29.4 字符串操纵
* 29.4.1 字符串化
* 29.4.2 拼接
* 29.5 预定义的宏
* 29.6 assert()宏
* 29.6.1 使用assert()进行调试
* 29.6.2 assert()与异常之比较
* 29.6.3 副作用
* 29.6.4 类的不变量
* 29.6.5 打印中间值
* 29.7 位运算
* 29.7.1 “与”运算符
* 29.7.2 “或”运算符
* 29.7.3 “异或”运算符
* 29.7.4 “求反”运算符
* 29.7.5 设置位
* 29.7.6 清除位
* 29.7.7 反转位
* 29.7.8 位字段
* 29.8 编程风格
* 29.8.1 缩进
* 29.8.2 大括号
* 29.8.3 长代码行和函数长度
* 29.8.4 格式化switch语句
* 29.8.5 程序文本
* 29.8.6 标识符命名
* 29.8.7 名称的拼写和大写
* 29.8.8 注释
* 29.8.9 设置访问权限
* 29.8.10 类定义
* 29.8.11 包含文件
* 29.8.12 使用assert()
* 29.8.13 使用const
* 29.9 C++开发工作的下一步
* 29.9.1 从何处获得帮助和建议
* 29.9.2 相关的C++主题:托管C++、C#和微软的.NET




