跳到主要内容C++ string 迭代器、初始化及常用函数详解 | 极客日志C++算法
C++ string 迭代器、初始化及常用函数详解
本文详细介绍了 C++ string 容器的核心功能,包括迭代器(正向、反向、const)与范围 for 循环的遍历方式及其修改特性,展示了 string 的多种初始化方法。文章解释了 reserve 函数对容量与长度的影响规则,并演示了如何使用 reverse 算法反转字符串或向量,旨在帮助开发者掌握 string 的实用技巧与内存管理知识。
JavaCoder0 浏览 在 C++ 中,string是处理字符串的核心容器,它封装了丰富的接口来简化字符串操作。本文将围绕string的**迭代器访问、初始化方式、容量调整(reserve)、反转(reverse)**四大核心功能展开,结合可直接运行的代码和结果验证建议,帮你快速掌握的实用技巧。
string
一、迭代器与范围 for:遍历 string 的两种核心方式
string作为 STL 容器的一种,支持迭代器(类似指针的访问工具)和范围 for 两种遍历方式,所有的 STL 容器都可以用以上两种方式遍历,其中范围 for 的底层本质就是迭代器。下面通过代码详细演示两者的用法。
1.1 迭代器遍历:灵活控制访问过程
迭代器的核心作用是'指向容器元素',支持*解引用获取值、++移动到下一个元素,适用于所有 STL 容器(如vector、list等)。
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "asjhjksd";
cout << "原字符串:" << s << endl;
string::iterator it = s.begin();
cout << "显式迭代器遍历:";
while (it != s.end()) {
cout << *it << " ";
it++;
}
cout << endl;
cout << "auto 简化迭代器遍历:";
for (auto it = s.begin(); it != s.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
1.2 范围 for:简化遍历的'语法糖'
范围 for 专门用于'遍历容器中所有元素',无需手动控制迭代器的开始和结束,语法更简洁。其底层逻辑与迭代器完全一致,遍历过程是将s的元素逐个赋值给ch。
关键细节:如何用范围 for 修改字符串?
若直接写for (auto ch : s),ch是元素的'拷贝',修改ch不会影响原字符串;若在ch前加&(引用),则ch直接关联原字符串的元素,支持修改。
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "asjhjksd";
cout << "修改前:" << s << endl;
cout << "普通范围 for 遍历:";
for (auto ch : s) {
cout << ch << " ";
}
cout << endl;
for (auto& ch : s) {
ch = toupper(ch);
}
cout << "引用修改后:" << s << endl;
return 0;
}
二、反向迭代器与传统访问:更多遍历选择
除了正向遍历,string还支持反向迭代器(从后往前遍历)和数组式访问(用 [] 运算符),满足不同场景需求。
2.1 反向迭代器:从后往前遍历
反向迭代器通过rbegin()(指向最后一个元素)和rend()(指向'第一个元素的前一个位置')控制范围,++操作实际是'向前移动'。
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "asjhjksd";
cout << "正向遍历:";
for (auto ch : s)
cout << ch << " ";
cout << endl;
cout << "反向遍历:";
auto rit = s.rbegin();
while (rit != s.rend()) {
cout << *rit << " ";
rit++;
}
cout << endl;
return 0;
}
2.2 传统数组式访问:借助 [] 运算符重载
string重载了[]运算符,允许像访问数组一样通过'索引'获取元素(索引从 0 开始),语法更符合 C 语言习惯。
#include <iostream>
#include <string>
using namespace std;
int main() {
string s = "asjhjksd";
cout << "数组式访问遍历:";
for (int i = 0; i < s.size(); i++) {
cout << s[i] << " ";
}
cout << endl;
return 0;
}
2.3 只读遍历:const 迭代器
若只需'遍历不修改',可在迭代器函数前加c(如cbegin()、crbegin()),获取const类型迭代器,避免误修改。
for (auto it = s.cbegin(); it != s.cend(); it++) {
cout << *it << " ";
}
for (auto rit = s.crbegin(); rit != s.crend(); rit++) {
cout << *rit << " ";
}
三、string 的初始化:简洁的'内置类型式'写法
string的初始化方式有多种,最常用且直观的是拷贝初始化,语法与内置类型(如int)完全一致,降低记忆成本。
#include <iostream>
#include <string>
using namespace std;
int main() {
string s1 = "zhdshk";
cout << "s1: " << s1 << endl;
string s2;
string s3(s1);
string s4(5, 'a');
cout << "s2: " << s2 << "(空字符串)" << endl;
cout << "s3: " << s3 << "(s1 的副本)" << endl;
cout << "s4: " << s4 << "(5 个'a')" << endl;
return 0;
}
四、reserve 函数:灵活调整 string 的容量
reserve(n)的核心作用是预分配字符串的容量(capacity),用于优化内存分配效率,不影响字符串的长度(size)和内容。理解size与capacity的区别是关键:
size:字符串当前的元素个数(实际存储的字符数);
capacity:字符串在不重新分配内存的情况下,最多能存储的元素个数(底层数组的大小)。
4.1 reserve 的核心规则
- 若
n > 当前 capacity:扩容到n(或更大,取决于编译器);
- 若
n < 当前 capacity:不强制缩容(是否缩容由编译器决定);
- 若
n < 当前 size:绝对不缩容(容量不能小于实际元素个数);
- 不改变
size和字符串内容。
4.2 代码演示:reserve 的实际效果
以下代码直观展示reserve对size和capacity的影响:
#include <iostream>
#include <string>
using namespace std;
void test_string4() {
string s2("hello worldxxxxxxxxxxxxx");
cout << "初始状态:" << endl;
cout << "size: " << s2.size() << endl;
cout << "capacity: " << s2.capacity() << endl;
cout << "------------------------" << endl;
s2.reserve(20);
cout << "reserve(20) 后:" << endl;
cout << "size: " << s2.size() << endl;
cout << "capacity: " << s2.capacity() << endl;
cout << "------------------------" << endl;
s2.reserve(40);
cout << "reserve(40) 后:" << endl;
cout << "size: " << s2.size() << endl;
cout << "capacity: " << s2.capacity() << endl;
cout << "------------------------" << endl;
}
int main() {
test_string4();
return 0;
}
五、reverse 函数:一键反转 string 或容器
reverse是 STL 算法库中的函数,支持对string、vector等容器进行反转,只需传入'待反转范围'的迭代器(左闭右开[begin, end))。
5.1 代码演示:反转 string
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string s = "hello world";
cout << "反转前:" << s << endl;
reverse(s.begin(), s.end());
cout << "反转后:" << s << endl;
return 0;
}
5.2 扩展:反转 vector
reverse同样适用于vector,用法完全一致:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5};
cout << "反转前:";
for (auto num : v)
cout << num << " ";
reverse(v.begin(), v.end());
cout << "\n反转后:";
for (auto num : v) {
cout << num << " ";
}
return 0;
}
总结
- 迭代器(正向/反向、const)与范围 for 的遍历逻辑,尤其是引用型范围 for 的修改用法;
- 简洁的
string初始化方式;
reserve对容量的调整规则(不影响 size、缩容依赖编译器);
reverse对容器的反转用法(需传入迭代器范围)。
string的接口远不止这些,若需深入学习,可查阅官方文档,结合实际代码测试,才能真正熟练掌握。
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown 转 HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
- HTML 转 Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online