范围for的底层本质也是迭代器

发布时间:2025-06-24 20:11:22  作者:北方职教升学中心  阅读量:783


operator<< (重点)(重点)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

**③getline **
从流中获取一行放到字符串中
在这里插入图片描述

  • 接口演示
    在这里插入图片描述

getline与流插入的区别
流插入遇到空格就会停止,也就是说,如果要输入hello world,那么它只会接收到hello这部分,但是getline则会全部都接收到
在这里插入图片描述

vs和g++下string结构的说明(了解即可)

vs下stirng的结构

1.当字符串长度小于16时,使用内部固定的字符数组来存放

2.当字符串长度大于等于16时,从堆上开辟空间

其次:还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的 容量最后:还有一个指针做一些其他事情。
在这里插入图片描述
前面说了,范围for本质还是迭代器,上面代码中遍历s1,实际是将*it1的值赋值到x中。但记住,它只是类似于指针,但不是指针。字符或者一个对象
在这里插入图片描述

string s1("hello");s1 +="world";for(charx :s1){cout <<x;

在这里插入图片描述
④c_str()(重点)
返回c格式的字符串
在这里插入图片描述

string s1("hello");cout <<s1.c_str()<<endl;

在这里插入图片描述
⑤find()
从字符串pos位置开始往后找字符c、在这里输出迭代器位置的值时,用到了"*"//和指针不同的是,这里的解引用操作符是被重载过的cout <<*it1 <<" ";//输出迭代器当前位置的值++it1;//然后迭代器后移}

rbegin()+rend()反向迭代器
rbegin()返回指向容器最后一个元素的迭代器,rend()返回指向容器第一个元素的前一个位置的迭代器。

接下来,我就来具体的讲讲begin()end()

  • bengin(),返回指向容器第一个元素位置的迭代器
  • end(),返回容器最后一个元素的下一个位置的迭代器
    在这里插入图片描述
  • 现在来分析下前面的那段代码
string s1("hello world");//string::iterator是迭代器类型,不同的容器,迭代器类型不同string::iterator it1 =s1.begin();//it1存储s1.begin()返回的迭代器位置while(it1!=s1.end())//当it1没到s1.end()位置时{//如前面所说,我们可以暂且把迭代器当作指针来理解。

string类

  • 为什么学习string类
  • 什么是string
  • 标准库中的string类
    • sting类的常用接口
      • 构造接口
      • string类对象的容量操作接口
      • string类对象的访问及遍历操作接口
      • string类对象的修改操作
      • string类非成员函数
  • vs和g++下string结构的说明(了解即可)
    • vs下stirng的结构
    • g++下string的结构

为什么学习string类

在c语言中,字符串是以’\0’结尾的一些字符集合,为了操作方便,c语言提供了一些str系列的库函数,但是这些库函数是于字符串分离开的,不太符合oop思想,而且底层需要用户自己管理,稍不留神可能还会越界访问

什么是string

string就是字符串的意思,是 C++用来代替 char 数组的数据结构。里面封装了一些常用的方法,方便我们对其进行一些操作,而且string的空间大小是动态变化的,大大减小了不必要的花销

标准库中的string类

string底层本质上还是一个顺序表,我们可以理解为是一个封装了char*的容器。
在这里插入图片描述

  • 下面是接口演示
    在这里插入图片描述
  • ③clear()

    • 这个接口的作用是清空存储的字符串。
      在这里插入图片描述
    • 下面是接口演示
      在这里插入图片描述
      在这里插入图片描述
    • 它只是清空字符串,不会影响到空间
    • 咱们来看下是不是真的清空了字符串
      在这里插入图片描述

    ④reserve()

    • 调整空间,若大于原空间,则进行扩容,若小于原空间,则不进行操作
      在这里插入图片描述
    • 下面是接口演示
      .当大于原空间时
      在vs平台下,string类初始空间是15(平台不同开辟的空间也不同)
      在这里插入图片描述
      .当小于原空间时
      在这里插入图片描述

    ⑤resize()

    • 调整字符串的长度,这个接口不仅会影响到size(),还会影响到capacity()
    • 若大于原长度,但小于原空间,则会增加有效字符个数,直到达到给定的长度,多出来的部分则是用’\0’填充
    • 若大于原长度,并且大于原空间,则会增加有效字符个数,直到达到给定的长度,并进行扩容
    • 若小于原长度,则会减少有效字符个数,并且减去的部分可以理解为被删除了。
      关于auto,可以到这篇文章中进行了解
      在这里插入图片描述
      第二种,自己给出类型。

    struct_Rep_base{size_type               size_type               _Atomic_word            };

    只不过:

    • char*是一个指针

    • string本质上是一个类,类的内部封装了char*,即**string是一个char***型的容器

    • **string管理char***所分配的内存,不用担心复制越界和取值越界等

    typedefbasic_string<char>string;

    在这里插入图片描述

    在使用string这个容器时,需要包含头文件

    sting类的常用接口

    构造接口

    1. 无参构造
    2. 字符串构造
    3. n个字符c构造
    4. 拷贝构造
      在这里插入图片描述
    string s1;//无参构造**************************string s1("hello world");//字符串构造stirng s2(s1);//拷贝构造**************************string s1(10,'c');//n个字符构造
    • 下面我会贴出运行图以便更好的理解:
      在这里插入图片描述
      在这里插入图片描述

    string类对象的容量操作接口

    1. size();
    2. lenth();->与size()方法底层实现原理完全相同
    3. capacity()
    4. empty()
    5. clear()
    6. reserve()
    7. resize()
    • 下面我会对这些接口进行演示

    ① size(),lenth(),capacity()

    string s2("hello world");cout <<s2.size()<<endl;cout <<s2.length()<<endl;
    • size()

    第一种情况
    在这里插入图片描述
    第二种情况
    在这里插入图片描述
    第三中情况
    在这里插入图片描述

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

    • operator[]—>返回pos位置字符的引用
    • begin()+end()—>迭代器
    • rbegin()+rend()—>反向迭代器
    • 范围for—> C++11支持更简洁的范围for的新遍历方式

    前面讲到string的底层本质是一个顺序表,既然是顺序表,那就能用下标引用操作符来访问与遍历。字符串s或者一个对象,返回该字符在字符串中的位置
    在这里插入图片描述

    • 代码演示
      在这里插入图片描述
      ⑥substr
      在str中从pos位置开始,截取n个字符,然后将其返回
      在这里插入图片描述
    • 接口演示
    string s1("hello world");string s2 =s1.substr(0,5);for(autox:s2){cout <<x;}

    在这里插入图片描述

    string类非成员函数

    接口使用说明
    operator+尽量少用,因为传值返回,导致深拷贝效率低
    operator>> (重点)流插入重载
    operator<< (重点)流提取重载
    getline (重点)获取一行字符串
    relational operators (重点)大小比较

    ①operator+
    在字符串后拼接字符、

    • 先演示下范围for的用法
      第一种,可以用auto让编译器来推导类型。
      ->注意,是把字符清楚,不会影响到空间,也就是capacity()。

      union_Bxty {// storage for small buffer or pointer to larger onevalue_type _Buf[_BUF_SIZE];pointer _Ptr;char_Alias[_BUF_SIZE];// to permit aliasing}_Bx;

      g++下string的结构

      G++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个 指针,该指针将来指向一块堆空间,内部包含了如下字段:

      • 空间总大小

      • 字符串有效长度

      • 引用计数

      • 指向堆空间的指针,用来存储字符串。字符串或者对象
        在这里插入图片描述
        operator+与operator+=的区别是前者不会影响自身,后者会影响到自身
        在这里插入图片描述
        在这里插入图片描述

        ②operator>> 、
        在这里插入图片描述
        在这里插入图片描述

        • 接口演示以及代码讲解
          在这里插入图片描述
        string s1("hello world");//string::reverse_iterator是反向迭代器的类型string::reverse_iterator it1 =s1.rbegin();//it1存储s1.rbegin()的位置while(it1!=s1.rend())//当没到s1.rend()位置时{cout <<*it1 <<" ";//输出当前位置的值++it1;//前移}

        范围for
        范围for,又称“语法糖”,它是在c++11时才出来的。 故总共占16+4+4+4=28个字节。lenth()这两个接口的功能是一样的呢?这是因为某些历史原因遗留下来的,原本string类使用的是lenth()接口,但是后面为了与其他STL容器保持统一,便有了size()接口,那c++为什么不删了lenth()这个接口呢?很简单,大白话讲就是:在size()接口出来前,很多项目使用的是lenth这个接口,如果删了这个接口,那些项目不就得全崩了吗?所以c++每次更新都是“向前兼容”,不会把之前不好的设定删除掉。
        operator[]->下标引用操作符重载

        在这里插入图片描述在这里插入图片描述

        • 既然我们能通过下标引用来遍历string类的对象,那我们是不是也能借此来修改string类对象中存储的值呢?
          答案是“肯定的”
          在这里插入图片描述
        • 另外,我们还能单独的对某一位置进行自增操作
          在这里插入图片描述

        begin()+end()迭代器
        begin()获取第一个字符的迭代器 + end()获取最后一个字符下一个位置的迭代器
        在这里插入图片描述

        • 下面是接口演示
          在这里插入图片描述

        什么是迭代器
        概念:迭代器是一种检查容器内元素并遍历元素的数据类型,通常用于对C++中各种容器内元素的访问,但不同的容器有不同的迭代器,初学者可以将迭代器理解为指针
        范围for的底层本质也是迭代器。lenth()返回的是字符串有效字符个数,而capacity()返回的是当前对象空间大小
        在这里插入图片描述

      • 为什么size()、下面来看下底层
        在这里插入图片描述

      string类对象的修改操作

      接口使用说明
      push_back()在字符串后尾插字符c
      append()在字符串后追加一个字符串
      operator+= (重点)在字符串末尾追加字符串str
      c_str()(重点)返回c格式的字符串
      find()从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
      substr在str中从pos位置开始,截取n个字符,然后将其返回

      push_back()
      在字符串后尾插字符c
      在这里插入图片描述

      • 接口演示
      string s1("hello");s1.push_back('w');for(charx :s1){cout <<x;}

      在这里插入图片描述

      append()
      在字符串后追加一个字符串

      string s1("hello");s1.append("world");for(charx :s1){cout <<x;}

      在这里插入图片描述
      ③operator+= (重点)
      在字符串末尾追加字符串、

    ②empty()

    • 这个接口的作用是判断该对象是否为空,为空在返回真,否则返回假。