
💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶🔹C++
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍
文章目录
- 前言
- 对string对象的访问接口
- 1.oparator[]
- 2.at()
- 3.迭代器iterators
- (1)begin和end
- 💤中途休息~问题思考
- (2)rbegin和rend
- 3.范围for
- 4.back和front
前言
上一篇文章中讲解了关于string类,以及相关的默认函数,容量有关的接口的学习。本篇博客继续对string接口进行讲解 。其中迭代器的讲解是重中之重。
对string对象的访问接口
- 1.下标访问
oparator[] - 2.
at(), - 3.迭代器
iterators, - 4.
范围for, - C++11中的5.
back和6.front
1.oparator[]

- 简单来说就是通过类似于数组的访问方式,来对字符串进行访问以及增,删等操作。
如下:

- 这种方法比较简单常用。上面这种string[]的形式和下面这样对字符数组的访问是有本质区别的。
其底层依然是调用了operator[],而普通的数组[]实际上是一种解引用。
如下两幅图所示👇,

查看反汇编:

由此可以证明,string类使用[]时其底层依然是调用了operator[],而普通的数组[]实际上是一种解引用。
2.at()

同样有两个重载,一个是普通对象,一个则是const对象
使用:

- 可以看到,他的使用方式也是十分简单。
下面再来看看处理异常时的情况:👇
int main()
{string s1("hello world!");1.s1.at(20)++;2.s1[20]++;return 0;
}
-
1.使用
at()的运行结果是:抛出异常!

-
2.使用
oparator[]的运行结果是:产生了一个越界访问的话就直接报出【断言错误】

3.迭代器iterators
迭代器(iterator)是一种可以遍历容器元素的数据类型。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。C++更趋向于使用迭代器而不是数组下标操作,因为标准库为每一种标准容器(如vector、map和list等)定义了一种迭代器类型,而只有少数容器(如vector)支持数组下标操作访问容器元素。可以通过迭代器指向你想访问容器的元素地址,通过*x打印出元素值。这和我们所熟知的指针极其类似。
————————————————
⭐️问题1:迭代器到底是什么?
答C++迭代器是一种用于遍历容器中元的对象。它提供了一种统一的访问容器元素的方式,无论容器的类型如何,都可以使用相同的语法进行操作。
迭代器的本质是一个指针,它指向容器中的某个元素。通过迭代器,我们可以访问容器中的元素,并且可以对元素进行修改、删除或插入操作。迭代器可以分为正向迭代器和反向迭代器,分别用于从容器的起始位置向后遍历和从容器的末尾位置向前遍历。
迭代器的实现方式取决于容器的类型。对于数组和指针类型的容器,迭代器本质上就是指针,通过指针的加减运算来实现遍历。对于其他类型的容器,如vector、list等,迭代器是一个包含指向容器元素的指针以及一些操作函数的对象。
- 总结来说,C++迭代器的本质是一个指针,它提供了一种统一的访问容器元素的方式,使得我们可以方便地遍历和操作容器中的元素。iterator提供一种统一的方式访问和修改容器。
接口汇总
| 接口 | 作用 |
|---|---|
| begin | 将迭代器返回到开头 |
| end | 返回迭代器以结束 |
| rbegin | 返回反向迭代器以反向开始 |
| rend | 将反向迭代器返回到反向端 |
| cbegin | 返回const_iterator开头 |
| cend | 返回const_iterator结束 |
| crbegin | 返回const_reverse_iterator以反转开始 |
| crend | 返回const_reverse_iterator反转端 |
(1)begin和end
同样有两个重载,一个是普通对象,一个则是const对象
begin:获取一个字符的迭代器end:获取最后一个字符下一个位置的迭代器

实例操作:
string::iterator it = s1.begin();

- 每个容器(ist,vector,map等等)里都有iterator迭代器,所以我们要在iterator前加上作用域(当然也可以加
auto去自动匹配类型)。 it取到的是每个元素的位置,那么对于*it来说即为每个元素。- 使用
正向迭代器接收iterator.还会有反向迭代器,马上会讲。
💤中途休息~问题思考
那么,如果使用const对象呢?
- 使用const修饰的迭代器接收:

- 传入const修饰的对象的引用

通过上图可以发现,const修饰后,都不能进行修改指向的元素值。
- 还有重要的一点,在一个函数中,通常使用迭代器遍历封装为函数,采取
引用传值减少拷贝构造,再加上const做修饰,防止权限放大。还必须使用const_iterator接收,如下图👇:

- 正确的做法是使用
const_iterator接收👇
(2)rbegin和rend
rbegin:指向的是最后一个字符的位置rend: 指向的是第一个字符的前一个位置

实例操作:使用反向迭代器接收reverse_iterator

小结:
四种迭代器:

| 可读不可改 | const_iterator 和 const_reverse_iterator |
|---|---|
| 可读可改 | iterator 和 reverse_iterator |
🚩一定一定注意权限问题!!!
3.范围for
格式:for (type val:
iterable);
使用:
int main()
{string s1("hello world!");for (char val : s1){cout << val << " ";}return 0;
}
执行结果:
- 在增强for循环中,我们不需要再通过计算数组长度遍历数组,增强for循环会自动根据数组长度将数组中的每一个数据赋值给同类型的val,我们只需要输出val就遍历了数组。
iterable不止可以为数组,还可以是迭代的对象(比如支持begin、end操作的容器、string类型等)- 范围for的底层实现还是
迭代器,所以我们可以说在它在遍历的时候相当于是将*it的数据给到当前的val,与迭代器十分相似。
还有十分要的一点,注意这个val他是一个拷贝。最好进行传引用,可以减少拷贝构造。以及多次析构等问题。
4.back和front
front:取到的是字符串的首字符back:取到的则是字符串的尾字符

注意:直接取到元素。