思考一个问题:我们该如何遍历一个字符串呢?
方法一:正常遍历
string s1("hello");
for(size_t i = 0;i<s1.size();i++)
{
cout<<s1[i]<<" ";
//[]是一个重载运算符,实际上调用了s1.operator[](i);
}
cout<<endl;
方法二:利用迭代器
迭代器是一个像指针一样访问数据结构的东西
我们首先使用的是正向迭代器,它通常用于正向遍历
//迭代器是用于访问数据结构的
string s1("hello");
string::iterator it = s1.begin();//属于string的迭代器
while(it != s1.end)//s1.begin永远表示第一个位置的地址,s1.end永远表示最后一个位置'\0'的地址
{
cout<<*it<<" "
++it;
}
cout<<endl;
那如果我想倒着遍历字符串该怎么办呢?
这个时候就可以利用反向迭代器,它可以用于反向遍历
string::reverse_iterator rit = s.rbegin();
while(rit != s.rend())
{
cout<<*rit<<" ";
++rit;
}
cout<<endl;
反向迭代器的工作原理如下:
我们已经知道迭代器相当于一个指针,既然相当于一个指针,那么如果其指向一个const对象,那么我们就有可能可以通过该迭代器修改该const对象,那么编译器就会报错!比如下面这段代码s.begin返回一个iterator,iterator保存该字符串首字符的地址,那么我们就可以根据这个iterator修改这个const字符串,所以编译器会报错。
于是就引入了const iterator,const iterator指向const对象,受const限制,我们无法通过iterator来修改这个const对象,此时就是合理的,下面代码修改如下。
根据官网的这份文档我们可以得知,普通对象会调用begin()/end(),返回的是iterator,const对象调用const begin()/const end(),返回一个const iterator。(对于反向迭代器同理)
有时我们觉得用迭代器写一列代码太麻烦了
string::const_reverse_iterator rit = rs.rbegin();
此时我们就可以用auto来帮我们自动推导:
auto rit = rs.rbegin();
方法三:利用范围for
for(auto ch : s1)
{
cout << ch<<" ";
}
cout << endl;
范围for的底层实际上就是利用了迭代器