• String(二)————迭代器及相关接口使用


    目录

    string构造接口(Construct string object)

    string的元素访问(读写)

     迭代器


    string构造接口(Construct string object)

    string相比于C语言的字符数组要好用的多,无论是在初始化还是在读写方面都方便许多。

    以basic_string 为例,来看一下它的构造接口:

    1、 第一个string():无参类型的构造,字符串长度为0。

    2、string (const string& str) :拷贝构造

    3、string (const string& str, size_t pos, size_t len = npos)

    以一个字符串的第pos个字符为起始,长度为len构造一个字符串:

     如果构造字符串的过程超过了目标字符串最后一位,那么将拷贝到最后一位停止:

    4、string (const char* s) :以字符串为参数构造,有两种形式。
    

    5、string (const char* s, size_t n)  :拷贝一个字符串的前n个字符

    6、string (size_t n, char c) :构造n个c字符的字符串:

    7、string (InputIterator first, InputIterator last) :从first开始到 last结束进行构造字符串:

    此外对多个字符串还能进行拼接,使用重载运算符 += 即可:

    上面所讲,红色标注的为重点,其他的了解用法即可。

    string的元素访问(读写)

     string中也对运算符 [  ]进行了重载,使得可以通过下标来访问元素。

    [ ] 运算符重载原型如下:

    1. char& operator[](size_t i)
    2. {
    3. assert(i < s0.size() );
    4. return _str[i];
    5. }

     并且相比于静态数组,它可以防止溢出。

     这里也可以使用范围for:

     看起来范围for好像是比用下标访问要方便一点,但是有的情况下用下标访问比较好,比如需要逆置上面的数组时:

     迭代器

    上面的数组还有第三种表示方式,就是迭代器。

    迭代器是string类里定义的类型,但不是内部类,只是在其中定义,属于string类。

    迭代器 iterators是一种行为像指针的类型,但它底层是不是指针不确定,具体要看实现,但是它的用法很像指针,且看他如何访问数组元素:

    1. string s0("abcd1234");
    2. string::iterator it = s0.begin();
    3. while (it != s0.end())
    4. {
    5. *it += 1;
    6. ++it;
    7. }
    8. it = s0.begin();
    9. while (it != s0.end())
    10. {
    11. cout << *it << " ";
    12. ++it;
    13. }
    14. cout << endl;

    it 是迭代器的对象,迭代器里面都有begin和end,分别表示第一个元素和最后一个的下一个元素。

    这是正向迭代器,还有反向迭代器

    1. string::reverse_iterator rit = s0.rbegin();
    2. while (rit != s0.rend())
    3. {
    4. *rit += 1;
    5. ++rit;
    6. }
    7. rit = s0.rbegin();
    8. while (rit != s0.rend())
    9. {
    10. cout << *rit << " ";
    11. ++rit;
    12. }
    13. cout << endl;

     与正向相对,反向开始是rbegin,结束是rend,它是倒着遍历的。

    看到迭代器的示例,有人会问 “这迭代器看上去非常麻烦,不好理解而且难记,不如直接用下标访问的方式 ”

    ————下标访问的方式在string和vector(顺序表)中可以使用,但是在其他容器(如map)就无法使用了。而迭代器是一种容器通用的遍历方式,具有普遍性。

    迭代器还有const修饰类型的,上面讲的迭代器对数据可读可写,const修饰的是只读属性,像print这种接口就要写成const修饰的。

    1. void print(const string& s)
    2. {
    3. string::const_iterator it = s.begin();
    4. while (it != s.end())
    5. {
    6. cout << *it << " ";
    7. ++it;
    8. }
    9. cout << endl;
    10. }
    11. int main()
    12. {
    13. string s0("abcd");
    14. print(s0);
    15. return 0;
    16. }

    string::const_iterator it = s.begin(); 这里要用const修饰迭代器对象,防止修改迭代器里的内容(*it)注意:这里不能写成 const string::iterator it = s.begin(); 这种是防止修改 it本身,而我们要遍历是需要修改 it 的,而 it 指向的内容不能修改。

    const修饰的迭代器有正向的,也就有反向的。

    1. void Test1()
    2. {
    3. string s0 = "qwer";
    4. string::const_reverse_iterator rit = s0.rbegin();
    5. while (rit != s0.rend())
    6. {
    7. cout << *rit << " ";
    8. ++rit;
    9. }
    10. cout << endl;
    11. }

    看上去确实长了点,但是有的时候是不可避免的,只要意思表达清楚即可,何况库里面也是这么使用的。

    总结:正向、反向迭代器可以读取和修改容器数据,而const正向、反向迭代器可以读取容器数据。

    那么什么时候需要const版本,什么时候需要非const版本呢?

    1、只读功能函数,只需要const版本;

    2、只写功能函数,只需要非const版本;

    3、可读可写功能函数,两个都需要。

    可读可写功能的函数,因为有可能是只读对象调用它,也可能是可读可写对象调用它,而const修饰的只读的对象只能调用const版本的函数,  只写的 \ 可读可写的对象可以不需要const版本的函数,因此需要提供两个版本。

  • 相关阅读:
    【信号隐藏-数字水印】基于小波变换算法DWT结合离散余弦变换DCT实现音频数字水印嵌入提取附matlab代码
    简单谈下Spring、Spring MVC和Spring Boot
    改进 Elastic Agent 和 Beats 中的事件队列
    第一章 使用管理门户(一)
    vue异步加载数据 传递给 子组件,触发mounted方法,子组件修改父组件值
    离线方式安装高可用RKE2 (版本: v1.22.13+rke2r1)记录
    编程大杂烩(三)
    C语言:输入t行字符串,每行字符串有10个字符
    混合编程python与C++
    NLP---文本前期预处理的几个步骤
  • 原文地址:https://blog.csdn.net/SAKURAjinx/article/details/127585347