当前位置:网站首页>string类对象的访问及遍历操作

string类对象的访问及遍历操作

2022-06-12 09:48:00 华为云

3、string类对象的访问及遍历操作
函数名称功能说明
operator[] —— 重点返回 pos 位置的字符,const string 类对象调用
begin + endbegin 获取一个字符的迭代器,end 获取最后一个字符下一个位置的迭代器
rbegin + rendbegin 获取一个字符的迭代器,end 获取最后一个字符下一个位置的迭代器
范围 forC++11 支持更简洁的范围 for 的新遍历方式

在这里插入图片描述

#include<assert.h>#include<string>#include<iostream>using namespace std;   //大概原理template<class T>class basic_string{public:	char& operator[](size_t pos)	{		assert(pos < _size);//检查越界:s2[20] -> err		return _arr[pos];		}private:	T* _arr;	int _size;	int _capacity;};//typedef basic_string<char> string;int main(){	//逐一遍历字符串		//1、operator[]	string s1("hello world");	for(size_t i = 0; i < s1.size(); ++i)	{		s1[i] += 1;//写	}	for(size_t i = 0; i < s1.size(); ++i)	{		cout << s1[i] << " ";//读	}	cout << endl;			//2、范围for	string s2("hello world");	for(auto& e : s2)	{		e += 1;//写 	}	for(auto e : s2)	{		cout << e << " ";//读	}	cout << endl;			//3、迭代器	string s3("hello world");	string::iterator it = s3.begin();	while(it != s3.end())	{		*it += 1;//写		++it;	}	it = s3.begin();	while(it != s3.end())	{		cout << *it << " ";//读		++it;	}	cout << endl;		return 0;}

说明

operator [] | at

operator[] 和 at 的价值是一样的,但是不一样的地方是对于越界:operator[] 直接使用断言报错,比较粗暴;而 at 则会抛异常。
在这里插入图片描述
在这里插入图片描述

范围 for

这是 C++11 中提出的新语法,比较抽象,对于它的原理,后面会再模拟实现它。

注意 auto e : s3 只能读,不能写;auto& e : s3 可读可写。

迭代器

它是 STL 中六大组件中的核心组件,这里先见个面。
在这里插入图片描述

begin() 返回第一个有效数据位置的迭代器;

end() 返回最后一个有效数据的下一个位置的迭代器;

目前可以认为它类似于指针,—— 有可能是指针,有可能不是指针,因为不仅仅 string 有迭代器,其它容器里也有迭代器。

while(it != s3.end()) 也可以 while(it < s3.end()),但不建议。这里是数组,换成小于它依然没问题,但是如果是链表,小于就不行了。所以这里统一就用不等于。

迭代器的好处是可以用统一类似的方式去访问修改容器 (也就意味着会了 string 的迭代器就等于会了其它容器的迭代器):
在这里插入图片描述
为什么这里要提供三种遍历方式

其实只提供了两种,因为范围 for 本质是迭代器,也就是说一个容器支持迭代器才会支持范围 for,后面会演示。

operator [] 可以像数组一样去访问,这种方式对于 vector 连续的数据结构是支持的,但是不支持 list。

迭代器这种方式是任何容器都支持的方式,所以迭代器才是容器通用的访问方式。

再简单了解迭代器

#include<string>#include<iostream>using namespace std;void Print1(const string& s)//不需要写{	string::iterator it = s.begin();//err,普通迭代器	//string::const_iterator it = s.begin();//ok,const迭代器	//string::const_iterator it = s.cbegin();//ok,C++11提供的cbegin	while(it != s.end())	{		cout << *it << " ";		++it;		}	cout << endl;}void Print2(const string& s){	string::reverse_iterator rit = s.rbegin();//err,普通反向迭代器	//string::const_reverse_iterator rit = s.rbegin();//ok,const反向迭代器	//auto rit = s.rbegin();//ok,auto的体现	while(rit != s.rend())	{		cout << *rit << " ";		++rit;//注意这里不是--	}	cout << endl;}void test_string(){	string s1("hello");	Print1(s1);	string s2("hello");	Print2(s2);	}int main(){	test_string();	return 0;}

说明

这里利用迭代器打印 s1:
在这里插入图片描述
查文档:begin 有两个版本
在这里插入图片描述

所以报错的原因是:s 是 const 对象,返回的是 const 迭代器,而这里使用普通迭代器来接收。解决方法就是用 const 迭代器接收。

在文档中看到 C++11 中又提供了一个 cbegin ???
在这里插入图片描述
为什么 C++11 把 const 迭代器单独拎出来,大概原因应该是 begin 里有普通 / const 迭代器不太明确,容易误导。不知道大家是怎么想的,我是觉得有点画蛇添足了。

rbegin:

rbegin 就是反向迭代器,顾名思义就是反向遍历。
在这里插入图片描述
在这里插入图片描述
auto 的价值

到了迭代器这里我们就可以用 auto 来替代比较长的类型,auto 的价值得以体现。

原网站

版权声明
本文为[华为云]所创,转载请带上原文链接,感谢
https://bbs.huaweicloud.com/blogs/358990