C++ string 部分功能详解:迭代器、初始化与常用函数

C++ string 部分功能详解:迭代器、初始化与常用函数

在 C++ 中,string是处理字符串的核心容器,它封装了丰富的接口来简化字符串操作。本文将围绕string迭代器访问、初始化方式、容量调整(reserve)、反转(reverse) 四大核心功能展开,结合可直接运行的代码和结果验证建议,帮你快速掌握string的实用技巧。

一、迭代器与范围 for:遍历 string 的两种核心方式

string作为 STL 容器的一种,支持迭代器(类似指针的访问工具)和范围 for 两种遍历方式,所有的STL容器都可以用以上两种方式遍历,其中范围 for 的底层本质就是迭代器。下面通过代码详细演示两者的用法。

1.1 迭代器遍历:灵活控制访问过程

迭代器的核心作用是 “指向容器元素”,支持*解引用获取值、++移动到下一个元素,适用于所有 STL 容器(如vectorlist等)。注意:原文代码存在语法错误(如#include<iostrean漏写mmainO错写括号、cout符号错误),以下是修正后的可运行代码:

cpp

#include <iostream> // 修正:补充<iostream>完整头文件 #include <string> using namespace std; // 修正:添加分号 int main() { string s = "asjhjksd"; // 待遍历的字符串 cout << "原字符串:" << s << endl; // 方式1:显式声明迭代器类型(string::iterator) string::iterator it = s.begin(); // begin()获取指向第一个元素的迭代器 cout << "显式迭代器遍历:"; while (it != s.end()) { // end()获取指向"最后一个元素的下一个位置"的迭代器 cout << *it << " "; // 解引用获取当前元素 it++; // 移动到下一个元素 } cout << endl; // 方式2:用auto简化迭代器类型(推荐) // 修正:auto自动推导为string::iterator,避免长类型书写 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直接关联原字符串的元素,支持修改。

cpp

#include <iostream> #include <string> using namespace std; int main() { string s = "asjhjksd"; cout << "修改前:" << s << endl; // 1. 普通范围for(仅遍历,不修改) cout << "普通范围for遍历:"; for (auto ch : s) { cout << ch << " "; } cout << endl; // 2. 引用型范围for(支持修改原字符串) for (auto& ch : s) { // 关键:添加&,ch成为原元素的引用 ch = toupper(ch); // 将小写字母转为大写 } cout << "引用修改后:" << s << endl; // 输出:ASJHJKSD return 0; } 

结果验证建议(图片内容)

运行上述两段代码后,截图应包含:

  • 原字符串输出(如asjhjksd);
  • 显式迭代器与 auto 迭代器的遍历结果(如a s j h j k s d );
  • 引用型范围 for 修改后的大写字符串(如ASJHJKSD)。

二、反向迭代器与传统访问:更多遍历选择

除了正向遍历,string还支持反向迭代器(从后往前遍历) 和数组式访问(用 [] 运算符),满足不同场景需求。

2.1 反向迭代器:从后往前遍历

反向迭代器通过rbegin()(指向最后一个元素)和rend()(指向 “第一个元素的前一个位置”)控制范围,++操作实际是 “向前移动”。

cpp

#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(); // auto推导为string::reverse_iterator while (rit != s.rend()) { cout << *rit << " "; // 依次输出:d s k j h j s a rit++; // 反向迭代器的++是“向前移动” } cout << endl; return 0; } 

2.2 传统数组式访问:借助 [] 运算符重载

string重载了[]运算符,允许像访问数组一样通过 “索引” 获取元素(索引从 0 开始),语法更符合 C 语言习惯。

cpp

#include <iostream> #include <string> using namespace std; int main() { string s = "asjhjksd"; cout << "数组式访问遍历:"; // size()获取字符串长度(元素个数) for (int i = 0; i < s.size(); i++) { cout << s[i] << " "; // 等价于*(s.begin() + i) } cout << endl; return 0; } 

2.3 只读遍历:const 迭代器

若只需 “遍历不修改”,可在迭代器函数前加c(如cbegin()crbegin()),获取const类型迭代器,避免误修改。

cpp

// const正向迭代器(只读) for (auto it = s.cbegin(); it != s.cend(); it++) { // *it = 'a'; // 报错:const迭代器不允许修改 cout << *it << " "; } // const反向迭代器(只读) for (auto rit = s.crbegin(); rit != s.crend(); rit++) { cout << *rit << " "; } 

结果验证建议(图片内容)

截图应包含:

  • 正向遍历结果(a s j h j k s d );
  • 反向迭代器遍历结果(d s k j h j s a );
  • 数组式访问结果(与正向遍历一致)。

三、string 的初始化:简洁的 “内置类型式” 写法

string的初始化方式有多种,最常用且直观的是拷贝初始化,语法与内置类型(如int)完全一致,降低记忆成本。

cpp

#include <iostream> #include <string> using namespace std; int main() { // 常用初始化:拷贝初始化(类似int a = 10;) string s1 = "zhdshk"; // 直接赋值字符串常量 cout << "s1: " << s1 << endl; // 其他常见初始化(补充参考) string s2; // 默认初始化:空字符串 string s3(s1); // 拷贝构造:s3是s1的副本 string s4(5, 'a'); // 填充初始化:5个'a',即"aaaaa" cout << "s2: " << s2 << "(空字符串)" << endl; cout << "s3: " << s3 << "(s1的副本)" << endl; cout << "s4: " << s4 << "(5个'a')" << endl; return 0; } 

补充说明

更多初始化方式(如用字符指针、子字符串初始化)可参考cppreference.com或原文提到的cplusplus.com,文档中有详尽的参数说明。

结果验证建议(图片内容)

截图应包含 4 个字符串的输出:

  • s1: zhdshk
  • s2: (空字符串)(无内容);
  • s3: zhdshk(与 s1 一致);
  • s4: aaaaa

四、reserve 函数:灵活调整 string 的容量

reserve(n)的核心作用是预分配字符串的容量(capacity),用于优化内存分配效率,不影响字符串的长度(size)和内容。理解sizecapacity的区别是关键:

  • size:字符串当前的元素个数(实际存储的字符数);
  • capacity:字符串在不重新分配内存的情况下,最多能存储的元素个数(底层数组的大小)。

4.1 reserve 的核心规则(原文重点)

  1. n > 当前capacity:扩容到n(或更大,取决于编译器);
  2. n < 当前capacity不强制缩容(是否缩容由编译器决定);
  3. n < 当前size:绝对不缩容(容量不能小于实际元素个数);
  4. 不改变size和字符串内容。

4.2 代码演示:reserve 的实际效果

以下代码基于原文test_string4()修正,直观展示reservesizecapacity的影响:

cpp

#include <iostream> #include <string> using namespace std; // 测试reserve函数 void test_string4() { // 初始化一个较长的字符串 string s2("hello worldxxxxxxxxxxxxx"); // 内容:hello world + 11个x cout << "初始状态:" << endl; cout << "size: " << s2.size() << endl; // 输出实际字符数(11+11=22?需以运行结果为准) cout << "capacity: " << s2.capacity() << endl; // 编译器默认分配的容量 cout << "------------------------" << endl; // 1. reserve(20):n < 初始capacity(假设初始capacity>20) s2.reserve(20); cout << "reserve(20)后:" << endl; cout << "size: " << s2.size() << endl; // size不变 cout << "capacity: " << s2.capacity() << endl; // 可能不缩容(编译器决定) cout << "------------------------" << endl; // 2. reserve(40):n > 初始capacity s2.reserve(40); cout << "reserve(40)后:" << endl; cout << "size: " << s2.size() << endl; // size仍不变 cout << "capacity: " << s2.capacity() << endl; // 扩容到40(或更大) cout << "------------------------" << endl; } int main() { test_string4(); return 0; } 

结果验证建议(图片内容)

以 GCC 编译器为例,截图可能包含:

  • 初始状态:size:22capacity:31(编译器默认分配的容量通常略大于实际需求);
  • reserve(20)后:size:22capacity:31(不缩容);
  • reserve(40)后:size:22capacity:40(扩容到 40)。

五、reverse 函数:一键反转 string 或容器

reverse是 STL 算法库中的函数,支持对stringvector等容器进行反转,只需传入 “待反转范围” 的迭代器(左闭右开[begin, end))。

5.1 代码演示:反转 string

cpp

#include <iostream> #include <string> #include <algorithm> // 必须包含:reverse函数在<algorithm>中 using namespace std; int main() { string s = "hello world"; cout << "反转前:" << s << endl; // 反转:传入s的首尾迭代器(覆盖整个字符串) reverse(s.begin(), s.end()); cout << "反转后:" << s << endl; // 输出:dlrow olleh return 0; } 

5.2 扩展:反转 vector

reverse同样适用于vector,用法完全一致:

cpp

#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()); // 反转vector cout << "\n反转后:"; for (auto num : v) cout << num << " "; // 输出:5 4 3 2 1 return 0; } 

结果验证建议(图片内容)

截图包含两部分:

  • string 反转:反转前:hello world反转后:dlrow olleh
  • vector 反转:反转前:1 2 3 4 5 反转后:5 4 3 2 1 

总结

本文围绕string的核心功能展开,重点掌握:

  1. 迭代器(正向 / 反向、const)与范围 for 的遍历逻辑,尤其是引用型范围 for 的修改用法;
  2. 简洁的string初始化方式,以及更多方式的查询渠道;
  3. reserve对容量的调整规则(不影响 size、缩容依赖编译器);
  4. reverse对容器的反转用法(需传入迭代器范围)。

string的接口远不止这些,若需深入学习,可访问cppreference.comcplusplus.com,结合实际代码测试,才能真正熟练掌握。

Could not load content