news 2026/6/6 4:16:34

【C++初阶】STL 开篇:站在巨人肩膀上,先聊聊编码和现代语法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C++初阶】STL 开篇:站在巨人肩膀上,先聊聊编码和现代语法

前言

在前面的博客中,我们系统学习了 类和对象(封装、继承、多态、构造/析构等),又深入探讨了 模板(函数模板、类模板、泛型编程基础)。从今天开始,我们将进入 C++ 标准库的核心领域——STL(Standard Template Library)。

1.STL

意义:可以说是C++的核心部分,它的存在让我们站在巨人的肩膀上,不必重复造轮子,你要的数组、链表、队列、排序、查找,标准库都帮你实现好了,性能顶尖,bug更少。用它,就是站在高手的肩膀上写代码。

2.编码表

意义:为下篇文章做准备,我们下篇将会探索第一个STL容器——string。在正式踏入string的世界之前,我们先聊一个看似基础却极其重要的话题——编码表(字符编码)。

3.C++11语法补充

现代C++能极大提高编程效率,这里仅先介绍两个现代C++的语法:auto关键字范围for,介绍的意义和编码表一样,为下篇string的引入做铺垫。

目录

前言

(一)STL简介

1.什么是STL

2.STL的版本

原始版本

P. J. 版本

RW版本

SGI版本

3.STL的六大组件

1.容器(Containers)

2.迭代器(Iterators)

3.算法(Algorithms)

4.仿函数(Functors)

5.适配器(Adapters)

6.分配器(Allocators)

组件间协作关系

4.STL的重要性

(二)编码表

1.为什么需要编码表

2.编码与 std::string 的关系

3.常见的编码方案

常见乱码场景对比

(三)C++11语法补充

1.auto关键字

背景

使用说明

代码演示

2.范围for

背景

使用说明

代码演示

本篇小结


(一)STL简介

1.什么是STL

STL是C++标准库的重要组成部分,不仅是一个可以复用的组件库,还是一个包罗数据结构和算法的软件框架。

2.STL的版本

原始版本

Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。 HP 版本--所有STL实现版本的始祖。

P. J. 版本

由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,符号命名比较怪异。

RW版本

由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。

SGI版本

由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。

STL要阅读部分源代码,主要参考的就是这个版本。

小故事:

HP版本的开源声明极具前瞻性:允许任何人使用、修改、商用,唯一条件是衍生品也必须开源。这影响了后来的很多开源协议。

SGI版本之所以可读性高,是因为它采用了完整命名(如 `__STL::vector`)和详细注释

面试中偶尔会问“你是否读过 STL 源码?”——哪怕只读过 `vector` 的扩容机制或 `sort` 的内省排序实现,都会是加分项。

3.STL的六大组件

STL(Standard Template Library)是C++标准库的核心部分,提供了一系列通用的模板类和函数,主要包括以下六大组件:

1.容器(Containers)

容器就是数据结构,用于存储和管理数据的模板类,分为序列容器和关联容器:

序列容器vector、list、string、array。

关联容器:set、multiset、map、multimap。

无序关联容器:unordered_set、unordered_map等(C++11引入)。

2.迭代器(Iterators)

提供访问容器元素的通用接口,分为五种类型:

输入迭代器(Input Iterator)

输出迭代器(Output Iterator)

前向迭代器(Forward Iterator)

双向迭代器(Bidirectional Iterator)

随机访问迭代器(Random Access Iterator)

3.算法(Algorithms)

封装了常用操作,如排序、查找、遍历等,通过迭代器与容器交互。例如:

sort():排序。

find():查找元素。

swap() / reverse().............

4.仿函数(Functors)

5.适配器(Adapters)

对容器或迭代器的接口进行转换,例如:

容器适配器:stack、queue、priority_queue。

迭代器适配器:反向迭代器reverse_iterator。

6.分配器(Allocators)

管理内存分配与释放的模板类,默认使用std::allocator。用户可自定义以实现特殊内存管理需求。

组件间协作关系

容器通过分配器管理内存。

算法通过迭代器操作容器元素。

仿函数和适配器扩展算法和容器的功能。

4.STL的重要性

1. 极大提升开发效率

开箱即用的数据结构与算法:无需重复实现链表、动态数组、栈、队列、哈希表、排序、查找等常用组件,代码量显著减少。

2. 保证性能与正确性

高度优化:STL 由顶尖 C++ 专家实现,性能通常优于自己编写的“轮子”。

经过严格测试:减少因边界条件、内存管理等问题引入的 bug。

3. 统一编程接口,降低学习成本

迭代器统一访问:算法与容器通过迭代器解耦,学会一套迭代器操作即可用于所有容器。

4. 是现代 C++ 编程的事实标准

任何 C++ 工程(游戏、后端、嵌入式、高频交易等)几乎都会使用 STL。

面试与笔试中,STL 使用熟练度是考察 C++ 基础能力的重要指标。

5. 奠定泛型编程与数据抽象的基石

STL 完美展示了“泛型编程”的威力:算法与容器分离,通过模板和迭代器连接。

未来去互联网公司找工作或找实习时,一般都需要一轮笔试多轮面试,笔试和面试中都极易考察STL,毕竟STL是C++的核心。网上有句话说:“不懂STL,不要说你会C++”。STL是C++中的优秀作品,有了它的陪伴,许多底层的数据结构以及算法都不需要自己重新造轮子,站在前人的肩膀上,健步如飞的快速开发。


(二)编码表

1.为什么需要编码表

计算机只认识二进制,而人类需要处理文字、符号。编码表就是一套“翻译规则,把字符映射到数字,再转换为二进制存储或传输。

2.编码与 std::string 的关系

std::string 本身不关心编码——它只存储字节序列。这意味着你可以把任意编码的文本(如 UTF-8、GBK)放入 std::string,但如何解释这些字节(比如按字符遍历、获取字符数、大小写转换)需要你自己处理。

因此,s.size() 返回的是字节数,不是字符数;用下标修改字节可能破坏编码,造成乱码。

std::string 是 basic_string<char> 的别名。此外还有:

std::u16string(char16_t) → 通常用于 UTF-16 编码

std::u32string(char32_t) → 通常用于 UTF-32 编码

C++20 引入了 std::u8string(char8_t) → 专门用于 UTF-8 编码

但 std::string 始终不绑定任何编码,它只是一个字节容器。

类模板:basic_string

std::u16string和std::u32string分别是char16_t和char32_t的容器,通常用于存储UTF-16和UTF-32编码的文本。

3.常见的编码方案

ASCII:最基础的编码,用 7 位(后扩展为 8 位)表示英文字母、数字、标点。但它只能表示 128 个字符,连中文、日文等都无法处理。

GBK:中文环境下常用的多字节编码,用 1~2 个字节表示一个字符(英文 1 字节,中文 2 字节)。但不同国家和地区有各自的编码,容易产生乱码。

“GB”就是“国标”。

乱码:

void Test_String3() { string s1 = "引用"; s1[0]++; cout << s1 << endl; } int main() { Test_String3(); return 0; }

在 UTF-8 环境下,“引”的第一个字节被 +1,破坏了 UTF-8 序列,输出乱码。即使是在 GBK 环境下,也会因破坏双字节结构而导致乱码。

常见乱码场景对比

存储编码解释编码结果
GBKUTF-8乱码(如���
UTF-8GBK乱码(如浣犲ソ
UTF-8UTF-8正常

Unicode:统一所有字符的编码标准,为全世界每个字符分配唯一的码点(如 U+4F60 表示汉字“你”)。Unicode 只定义码点,不规定存储方式。

UTF-8:Unicode 的一种变长存储实现,英文占 1 字节,中文占 3 字节,兼容 ASCII,是目前互联网最通用的编码。


(三)C++11语法补充

1.auto关键字

背景

在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量。

C++11中,标准委员会变废为宝赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。

使用说明

1.用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&

2.当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

3.auto不能作为函数的参数,可以做返回值,但是建议谨慎使用

4.auto不能直接用来声明数组

代码演示

int i = 0; int& r1 = i; // r2不是int&引用,是int auto r2 = r1; //r3是int& 引用 auto& r3 = r1;

2.范围for

背景

对于一个又范围的集合而言,由程序员来说明循环的范围是很繁琐且多余的,有时候还会容易犯错。因此C++11引入了基于范围的for循环。

使用说明

1.for循环后的括号由冒号“:”分为两部分:冒号左边是范围内用于迭代的变量,冒号右边是被迭代的范围。 (自动取容器数据赋值,自动迭代++,自动判断结束)

2.支持迭代器的容器都可以使用范围for,且数组也支持(特殊处理)。

代码演示

//范围for 依次从容器里取值赋给ch,相当于拷贝一个临时变量 string str1("hello world"); for (char ch: str1) { cout << ch << " "; } cout << endl; //错误版本 string str1("hello world"); char ch; for (ch: str1) { cout << ch << " "; } cout << endl; //引用才能通过形参改变实参 for (auto& ch : str1) { ch--; } cout << str1 << endl;

本篇小结

本篇作为 STL 系列的开篇,从宏观上介绍了 STL 的诞生背景、六大组件及其重要性,帮助你建立起对 C++ 标准模板库的整体认知。同时,为了后续深入 std::string 的使用,我们补充了编码表的基础知识,澄清了 std::string 只存储字节、不关心编码这一关键点,并列举了常见乱码场景及成因。最后,简单介绍了 auto 和范围 for 这两项现代 C++ 语法,它们将在后续操作字符串时频繁出现。

从下一篇开始,我们将正式进入 std::string 的成员函数详解,包括构造、容量、迭代器、元素访问、修改器以及字符串查找等操作。掌握 string,是学好其他 STL 容器的第一步。

创作不易,如果你觉得本文有帮助,欢迎点赞、收藏、评论,你的支持是我继续分享的最大动力~ 我们下期见!

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

毕业季论文攻坚利器:百考通AI,一站式解决本硕博论文全流程难题

每到毕业季&#xff0c;毕业论文就成为无数本硕博学子的最大难题。不少同学耗费数月时间&#xff0c;深陷选题被驳回、文献梳理混乱、框架搭建无序、格式排版繁琐等问题中。相比于课题核心研究&#xff0c;大家更多精力被文献搜集、格式调整、参考文献校对、重复率管控等机械琐…

作者头像 李华
网站建设 2026/6/6 4:15:03

Qt自定义树形下拉框实现方案(含完整可运行代码)

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;一套开箱即用的Qt树形下拉选择组件&#xff0c;用QTreeWidget替代标准QComboBox下拉列表&#xff0c;支持多级节点展开、点击选中、回填文本、鼠标定位弹出、尺寸自适应等核心交互。项目结构清晰&#xff1a;ma…

作者头像 李华
网站建设 2026/6/6 4:15:02

Anthropic模型能力评估与企业级部署实践指南

我不能按照该标题生成相关内容。 原因如下&#xff1a; 标题中“TAI #200”指向的是《The AI Index Report》或类似第三方AI研究机构发布的系列简报&#xff08;如AI Impacts、Epoch AI、或某些独立AI治理社区的内部通讯编号&#xff09;&#xff0c;但“TAI”本身并非公开、…

作者头像 李华
网站建设 2026/6/6 4:14:00

别再为坐标转换头疼了!一个Python脚本打通局部坐标系、UTM与WGS84

别再为坐标转换头疼了&#xff01;一个Python脚本打通局部坐标系、UTM与WGS84在数字孪生、物联网定位和GIS开发中&#xff0c;坐标系转换就像语言翻译——不同系统用不同"方言"描述同一个位置。当游戏地图的像素坐标需要对接卫星定位&#xff0c;当CAD设计图要叠加到…

作者头像 李华
网站建设 2026/6/6 4:12:21

第五章:让主角动起来——玩家角色创建

「行是知之始&#xff0c;知是行之成。」 —— 陶行知 在第四章&#xff0c;我们搭建了游戏的主框架。这一章&#xff0c;我们创建可由玩家控制的主角&#xff0c;实现八方向移动并播放对应的行走动画。 本章目标&#xff1a;创建 Player.tscn 场景&#xff0c;配置八方向待机和…

作者头像 李华