news 2026/4/12 20:40:13

《C++初阶之STL》【vector容器:详解 + 实现】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《C++初阶之STL》【vector容器:详解 + 实现】
1. 为什么要学习string类?

在 C 语言里,字符串被定义为以字符’\0’作为结尾标志的一组字符集合。这种定义方式使得字符串在存储识别上有了明确的界定。 为了让开发者能更便捷地对字符串进行诸如:复制拼接比较等操作,C 标准库精心提供了一系列以str开头的库函数,例如

  • strcpy(字符串复制函数)
  • strcat(字符串拼接函数)
  • strcmp(字符串比较函数)
  • ……

然而:这些库函数存在一定的局限性,它们与字符串本身在逻辑上是相互分离的。

  • 从面向对象编程(OOP)的理念来看,OOP 强调将数据和操作数据的方法封装在一起,形成一个有机的整体,这样可以让代码的结构更加清晰,可维护性更强。
  • 但 C 标准库中的str系列库函数并非如此,它们独立于字符串对象之外,不太契合 OOP 这种将数据与操作紧密结合的思想。

不仅如此:在使用这些库函数操作字符串时,底层的内存空间管理责任完全落在了用户身上。

  • 用户需要自行负责分配足够的空间来存储字符串以及确保在对字符串进行操作时不会超出所分配空间的边界。
  • 这就要求开发者在编写代码时格外小心谨慎,稍有疏忽,比如:在复制字符串时没有正确计算目标空间的大小,就极有可能导致越界访问的问题,进而引发程序崩溃、数据损坏等严重后果。

基于上述种种原因,我们会发现 C 语言中字符串操作存在一些不便之处,而 C++ 的string 类能够很好地解决这些问题:

  • string类将字符串数据及其相关操作封装在一起,完美契合面向对象编程(OOP)的思想,使得代码结构更加清晰、易于维护。
  • string类内部会自动管理底层的内存空间,无需开发者手动操心内存分配与释放的细节,极大地降低了因内存管理不当导致越界访问等错误的风险。
2. 标准库中的string类是什么样的呢?

cplusplus网站上关于C++的string类的介绍: C++ Reference

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

标准库中的string类相关知识主要可分为以下三大部分:1. 成员函数

  • 迭代器相关:用于获取指向string类内部字符的迭代器。
    • 例如:方便对字符串进行遍历、查找等操作
  • 容器特性相关:实现类似容器的功能。
    • 例如:获取字符串长度、判断是否为空等
  • 元素访问:提供接口用于直接访问字符串中的字符。
    • 例如:通过下标访问特定位置的字符
  • 修改操作:用于改变字符串的内容。
    • 例如:插入、删除、替换字符或子串等
  • 字符串操作:比较字符串等操作。
    • 例如:字符串的拼接、查找子串

2. 非成员函数重载

  • 对一些常见运算符(+用于字符串拼接等 )以及输入输出流运算符(<<>>)进行重载。
  • 以支持与string类对象的自然交互。

3. 成员常量string类中定义的一些具有固定值的常量,可能用于表示特定的属性边界条件等。

在这里插入图片描述

3. string类在MSVC和g++编译器下有什么区别?
3.1:结构上不同

注意:下述结构是在 32 位平台下验证的,在 32 位平台中指针占 4 个字节

在 MSVC(Microsoft Visual C++)环境下,string的结构相对复杂,总共占用28 个字节

其内部包含一个联合体,该联合体用于定义string中字符串的存储空间。

代码语言:javascript

AI代码解释

//联合体的定义如下: union _Bxty { // 用于存放小缓冲区或指向更大缓冲区的指针 value_type _Buf[_BUF_SIZE]; pointer _Ptr; char _Alias[_BUF_SIZE]; // 用于允许别名 } _Bx;
  • 当字符串长度 < 16 时:使用内部固定的字符数组来存放字符串。
  • 当字符串长度 >= 16 时:则从堆上开辟空间来存储。

这种设计是有道理的,在大多数情况下,字符串长度小于 16 。 此时,string对象创建后,内部已具备 16 个字符数组的固定空间,无需从堆上动态创建,提高了效率。

  • 此外,string结构中还有一个size_t类型字段,用于保存字符串的实际长度。
  • 另一个size_t类型字段,用来保存从堆上开辟空间的总容量。
  • 最后,还有一个指针,用于其他相关操作。

因此:string的总字节数为 16(联合体中字符数组的大小) + 4(保存长度的size_t字段) + 4(保存容量的size_t字段) + 4(指针大小) = 28 个字节。


在 g++ (GNU C++)环境下,string采用写时拷贝机制实现。string对象本身仅占4个字节

  • 内部仅有一个指针,该指针指向一块位于堆上的空间。

这块堆空间包含以下字段:

  • 字符串有效长度
  • 空间总容量
  • 引用计数

代码语言:javascript

AI代码解释

struct _Rep_base { size_type _M_length; //字符串有效长度 size_type _M_capacity; //空间总容量 _Atomic_word _M_refcount; //引用计数 };
3.2:扩容规则不同

MSVC(Microsoft Visual C++)的扩容规则:

  • 扩容因子:通常为1.5 倍(非固定值,可能随版本调整)
  • 行为特点:相对保守的内存增长,减少内存浪费

代码语言:javascript

AI代码解释

int main() { // reverse 反转 逆置 // reserve 保留、预留 //1.使用标准库中的string类实例化一个对象 string s; //2.使用标准库中的string类封装的成员函数reserve:提前开空间,避免扩容,提高效率 //s.reserve(100); //3.使用标准库中的string类封装的成员函数capacity:获取当前的字符串的总容量 size_t sz = s.capacity(); cout << "capacity changed: " << sz << '\n'; cout << "making s grow:\n"; for (int i = 0; i < 100; ++i) { //3.使用标准库中的string类封装的成员函数push_back:向字符串的尾部添加字符(目的:观察一下MSVC环境下的string的扩容规则) s.push_back('c'); if (sz != s.capacity()) { sz = s.capacity(); cout << "capacity changed: " << sz << '\n'; } } return 0; }

在这里插入图片描述

g++ (GNU C++)的扩容规则:

  • 扩容因子:通常为2 倍(早期版本常见)
  • 行为特点:更激进的内存增长,减少频繁扩容的开销

-------------标准接口---------------

-----------成员函数-----------
1.常见构造

下面我们直接来看标准库中关于string类构造函数的介绍:早期 C++ 设计者为string类设计了多达 9 个构造函数,目前我们先集中学习以下红色方框中的 4 个。 暂未学习其他构造函数,主要有两点原因:

  1. 部分构造函数实际应用场景较少,现阶段学习性价比不高,可暂不关注
  2. 部分构造函数涉及较复杂的知识(如:模板进阶等),对当前学习进度而言难度较大,适合后续阶段深入学习

构造函数名称

功能说明

string()

构造一个空的 string 类对象(即:空字符串)

string(const char* s)

用 C 风格字符串(C-string)构造 string 类对象

string(size_t n, char c)

构造包含 n 个相同字符 c 的 string 类对象

string(const string& s)

拷贝构造函数,用于复制另一个 string 对象

在这里插入图片描述

代码语言:javascript

AI代码解释

#include <iostream> #include <string> using namespace std; void Teststring() { // 使用string()构造空的string类对象s1 cout << "使用string()构造函数" << endl; string s1; cout << "s1: " << s1 << endl; // 使用string(const char* s)用C-string来构造string类对象s2 cout << "使用string(const char* s)构造函数" << endl; string s2("hello world"); cout << "s2: " << s2 << endl; // 使用string(size_t n, char c)构造包含n个字符c的string类对象s3 cout << "使用string(size_t n, char c)构造函数" << endl; string s3(5, 'a'); cout << "s3: " << s3 << endl; // 使用string(const string& s)拷贝构造函数构造s4,以s2为蓝本 cout << "使用string(const string& s)拷贝构造函数" << endl; string s4(s2); cout << "s4: " << s4 << endl; } int main() { Teststring(); return 0; }

在这里插入图片描述

2.容量操作

:和上面一样这里我们还是只是挑选几个常用的进行介绍

在这里插入图片描述

函数名称

功能说明

备注

size()

返回字符串中有效字符的长度(不包含结尾的 \0)

与 length() 功能完全相同,推荐使用 size() 保持容器一致性

length()

返回字符串中有效字符的长度

历史遗留接口,行为与 size() 一致,通常用于字符串操作的可读性

capacity()

返回当前字符串分配的总空间大小(单位:字节)

总空间 ≥ 有效字符长度(size())

empty()

检查字符串是否为空(即:size() == 0)空则返回 true,否则返回 false

比手动检查 size() == 0 更直观高效

clear()

清空字符串中的所有有效字符(size() 变为 0),但不释放内存空间

清空后 capacity() 保持不变,适合复用对象避免重复分配内存

reserve(n)

预分配至少容纳 n 个字符的内存空间(可能扩容)

仅影响容量,不改变内容或长度若 n < capacity(),可能无操作

resize(n, c)

调整有效字符数量为 n 个,多出的空间用字符 c 填充若 n < size() 则截断

默认填充 \0(若:未指定 c)可能触发扩容(若:n > capacity())

std::string::size

在这里插入图片描述

std::string::length

在这里插入图片描述

std::string::capacity

在这里插入图片描述

代码语言:javascript

AI代码解释

#include <iostream> #include <string> using namespace std; int main() { string str("Test string"); cout << "size: " << str.size() << "\n"; cout << "length: " << str.length() << "\n"; cout << "capacity: " << str.capacity() << "\n"; return 0; }

在这里插入图片描述

std::string::empty

在这里插入图片描述

代码语言:javascript

AI代码解释

#include <iostream> #include <string> using namespace std; int main() { //1.用于临时存储每一行输入的文本 string line; //2.用于存储用户输入的完整文本内容 string content; cout << "请输入一段文本,输入空行以结束:\n"; //3.循环读取用户输入的每一行,直到遇到空行为止 do { //3.1:从标准输入读取一行文本(包括空格),存入 line 中 getline(cin, line); //注意:getline 会读取到换行符为止,但不会将换行符存入 line //3.2:将当前行追加到 content 中,并手动添加换行符(因为 getline 不保留换行符) content += line + '\n'; } while (!line.empty()); //循环条件:只要当前行不为空(!line.empty())就继续循环 //4.输出用户输入的完整文本(包含所有行,包括最后的空行) cout << "您输入的文本是:\n" << content; return 0; }

在这里插入图片描述

std::string::clear

在这里插入图片描述

代码语言:javascript

AI代码解释

#include <iostream> #include <string> using namespace std; int main() { //1.用于存储从输入流读取的单个字符 char c; //2.用于拼接读取到的字符,形成一行文本 string str; cout << "请输入几行文本以(.)作为结束标志\n"; //3.循环读取字符,直到读取到 '.' 时结束循环 do { //3.1:从标准输入流读取一个字符(包括空格、换行符等) c = cin.get(); //3.2:将读取到的字符追加到字符串str的末尾 str += c; //3.3:当读取到换行符 '\n' 时,表示一行输入结束 if (c == '\n') { cout << str; // 输出当前拼接好的一行文本(包含换行符) str.clear(); // 清空字符串str,准备接收下一行的输入 } } while (c != '.'); //4.输出读取到的文本内容 cout << str << endl; return 0; }

在这里插入图片描述

std::string::reserve

在这里插入图片描述

代码语言:javascript

AI代码解释

#include <iostream> #include <string> using namespace std; int main() { /*--------------------创建一个包含长字符串的string对象--------------------*/ cout << "创建一个包含长字符串的string对象" << endl; string s2("hello worldxxxxxxxxxxxxx"); cout << "长度:" << s2.size() << endl; cout << "容量:" << s2.capacity() << endl << endl; /*--------------------要求string保留至少20个字符的容量--------------------*/ cout << "要求string保留至少20个字符的容量" << endl; s2.reserve(20); cout << "长度:" << s2.size() << endl; //长度不变 cout << "容量:" << s2.capacity() << endl << endl; //容量不变 /*--------------------要求string保留至少28个字符的容量--------------------*/ cout << "要求string保留至少28个字符的容量" << endl; s2.reserve(28); cout << "长度:" << s2.size() << endl; //长度不变 cout << "容量:" << s2.capacity() << endl << endl; //容量可能增长 /*--------------------要求string保留至少40个字符的容量--------------------*/ cout << "要求string保留至少40个字符的容量" << endl; s2.reserve(40); cout << "长度:" << s2.size() << endl; //长度不变 cout << "容量:" << s2.capacity() << endl << endl; //容量进一步增长 /*--------------------清空字符串内容--------------------*/ cout << "清空字符串内容" << endl; s2.clear(); //注意:这只会清除内容,不会释放已分配的内存 cout << "长度:" << s2.size() << endl; //长度为0 cout << "容量:" << s2.capacity() << endl << endl; //容量保持不变 return 0; }

在这里插入图片描述

std::string::resize

在这里插入图片描述

代码语言:javascript

AI代码解释

#include <iostream> #include <string> using namespace std; int main() { //1.初始化字符串str为"I like to code in C" string str("I like to code in C"); cout << str << '\n'; //输出初始字符串 //2.获取当前字符串的长度(字符数量),不包含结尾的空字符'\0' unsigned sz = str.size(); //3.调整字符串长度:在原有长度基础上增加2个字符 str.resize(sz + 2, '+'); //新增的字符用'+'填充 cout << str << '\n'; //输出调整后的字符串(末尾多了两个'+') //4.再次调整字符串长度:将长度改为14个字符 str.resize(14); //注意:若新长度小于原长度,会截断字符串(只保留前14个字符) cout << str << '\n'; //输出截断后的字符串(前14个字符为"I like to code") return 0; }

在这里插入图片描述

3.访问操作
std::string::operator[]

在这里插入图片描述

代码语言:javascript

AI代码解释

#include <iostream> #include <string> using namespace std; int main() { //1.初始化字符串str为"Test string" string str("Test string"); //2.循环遍历字符串中的每个字符并输出 for (int i = 0; i < str.length(); ++i) { //2.1:使用 operator[] 访问字符串的第i个字符 cout << str[i]; } cout << endl; return 0; }

在这里插入图片描述

4.修改操作

在这里插入图片描述

函数名称

功能说明

参数说明

注意事项

push_back(c)

在字符串末尾插入单个字符 c

c: 要插入的字符(char类型)

效率高于+=追加单字符,但批量操作建议用append或operator+=

append(str)

在字符串末尾追加另一个字符串(支持string/char*/子串)

str: 要追加的字符串(支持多种重载形式)

比+=功能更灵活(如可追加部分子串或重复字符)

operator+=(str)

最常用的字符串追加方式(支持string/char*/字符)

str: 要追加的内容(支持字符串或单字符)

代码简洁,性能与append()相当,推荐日常使用

insert(pos, str)

在指定位置 pos 插入字符串 str(支持多种插入形式)

pos: 插入位置索引str: 要插入的内容(字符串 / 字符 / 子串等)

插入后原位置及后续字符自动后移pos 超出范围会抛出异常(at() 风格重载)或导致未定义行为([] 风格)

erase(pos, len)

从位置 pos 开始删除 len 个字符(len 省略时删除到末尾)

pos: 起始删除位置len: 要删除的字符数(可选)

若 pos 超出范围会抛出异常若 len 超出剩余字符数,仅删除到字符串末尾

关于 string 需注意以下两点:1. 尾部追加字符的三种方式:

  • s.push_back(c):向string尾部添加单个字符c
  • s.append(1, c):明确指定追加 1 个字符c
  • s += 'c':简洁的运算符重载方式,既可以追加单个字符'c',也能直接连接字符串(如:"hello"

实际应用中+=操作因语法简洁、适用场景灵活(字符 / 字符串均可),是最常用的追加方式

www.dongchedi.com/article/7597217223819772478
www.dongchedi.com/article/7597215233471889944
www.dongchedi.com/article/7597216873696526910
www.dongchedi.com/article/7597217143041737241
www.dongchedi.com/article/7597214870441935385
www.dongchedi.com/article/7597214599947043353
www.dongchedi.com/article/7597214580846477886
www.dongchedi.com/article/7597216071082738201
www.dongchedi.com/article/7597214433031078424
www.dongchedi.com/article/7597214537498362392
www.dongchedi.com/article/7597215399566361150
www.dongchedi.com/article/7597215658752868888
www.dongchedi.com/article/7597215102077141528
www.dongchedi.com/article/7597214696924004889
www.dongchedi.com/article/7597213042329895448
www.dongchedi.com/article/7597215125493400126
www.dongchedi.com/article/7597212587801018905
www.dongchedi.com/article/7597214580846215742
www.dongchedi.com/article/7597214267869692440
www.dongchedi.com/article/7597213056480969278
www.dongchedi.com/article/7597212812516639257
www.dongchedi.com/article/7597212812516868633
www.dongchedi.com/article/7597213320844182041
www.dongchedi.com/article/7597211160895046206
www.dongchedi.com/article/7597211076186374681
www.dongchedi.com/article/7597212587801477657
www.dongchedi.com/article/7597210839670080062
www.dongchedi.com/article/7597210276412899864
www.dongchedi.com/article/7597211030086926872
www.dongchedi.com/article/7597211160895078974
www.dongchedi.com/article/7597209997126238744
www.dongchedi.com/article/7597209064238039577
www.dongchedi.com/article/7597211030087287320
www.dongchedi.com/article/7597209862904480318
www.dongchedi.com/article/7597209319725253145
www.dongchedi.com/article/7597208525277987353
www.dongchedi.com/article/7597208525278151193
www.dongchedi.com/article/7597210268858958398
www.dongchedi.com/article/7597209475426435609
www.dongchedi.com/article/7597209772429476377
www.dongchedi.com/article/7597201951176213017
www.dongchedi.com/article/7597201687174562366
www.dongchedi.com/article/7597199724889997849
www.dongchedi.com/article/7597199550092657177
www.dongchedi.com/article/7597200248943329816
www.dongchedi.com/article/7597199001863701017
www.dongchedi.com/article/7597198298541834777
www.dongchedi.com/article/7597200591446000190
www.dongchedi.com/article/7597199968348357145
www.dongchedi.com/article/7597199312984162841
www.dongchedi.com/article/7597199429019861566
www.dongchedi.com/article/7597196791863902782
www.dongchedi.com/article/7597197725960110616
www.dongchedi.com/article/7597197533550920217
www.dongchedi.com/article/7597196766895079960
www.dongchedi.com/article/7597197878439756313
www.dongchedi.com/article/7597196909912031768
www.dongchedi.com/article/7597195764053492248
www.dongchedi.com/article/7597196370181030424
www.dongchedi.com/article/7597195961618121241
www.dongchedi.com/article/7597195004385182232
www.dongchedi.com/article/7597196281857442366
www.dongchedi.com/article/7597195368090075673
www.dongchedi.com/article/7597195809683505689
www.dongchedi.com/article/7597194439940932158
www.dongchedi.com/article/7597194164794933822
www.dongchedi.com/article/7597194060553749016
www.dongchedi.com/article/7597195414877995544
www.dongchedi.com/article/7597194911112479256
www.dongchedi.com/article/7597194219174068761
www.dongchedi.com/article/7597192718418756120
www.dongchedi.com/article/7597191743318065689
www.dongchedi.com/article/7597194069471003161
www.dongchedi.com/article/7597193401016500760
www.dongchedi.com/article/7597192147254772286
www.dongchedi.com/article/7597192394672505406
www.dongchedi.com/article/7597190301329080894
www.dongchedi.com/article/7597188998091833881
www.dongchedi.com/article/7597190006675243582
www.dongchedi.com/article/7597189866363372056

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

3分钟快速解决:Windows系统苹果设备驱动安装完整指南

3分钟快速解决&#xff1a;Windows系统苹果设备驱动安装完整指南 【免费下载链接】Apple-Mobile-Drivers-Installer Powershell script to easily install Apple USB and Mobile Device Ethernet (USB Tethering) drivers on Windows! 项目地址: https://gitcode.com/gh_mirr…

作者头像 李华
网站建设 2026/3/27 15:27:33

EdgeRemover专业指南:深度解析Windows系统级浏览器卸载方案

EdgeRemover专业指南&#xff1a;深度解析Windows系统级浏览器卸载方案 【免费下载链接】EdgeRemover PowerShell script to remove Microsoft Edge in a non-forceful manner. 项目地址: https://gitcode.com/gh_mirrors/ed/EdgeRemover 在Windows系统管理中&#xff0…

作者头像 李华
网站建设 2026/4/11 19:20:06

Qwen3-Reranker-0.6B性能测试:0.6B模型的排序能力评估

Qwen3-Reranker-0.6B性能测试&#xff1a;0.6B模型的排序能力评估 1. 引言 在信息检索系统中&#xff0c;重排序&#xff08;Re-ranking&#xff09;是提升搜索结果相关性的关键环节。传统的检索模型如BM25能够快速召回候选文档&#xff0c;但往往难以精准捕捉查询与文档之间…

作者头像 李华
网站建设 2026/4/10 8:35:07

前端HTML转Word文档完整解决方案:html-docx-js实战指南

前端HTML转Word文档完整解决方案&#xff1a;html-docx-js实战指南 【免费下载链接】html-docx-js Converts HTML documents to DOCX in the browser 项目地址: https://gitcode.com/gh_mirrors/ht/html-docx-js 在数字化办公时代&#xff0c;将网页内容快速转换为可编辑…

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

NotaGen镜像深度体验|112种古典音乐风格自由创作

NotaGen镜像深度体验&#xff5c;112种古典音乐风格自由创作 1. 引言&#xff1a;AI与古典音乐的融合新范式 近年来&#xff0c;生成式人工智能在艺术创作领域持续突破&#xff0c;从图像到文本&#xff0c;再到音频内容的生成&#xff0c;技术边界不断被拓展。而在音乐创作这…

作者头像 李华