深圳医疗网站建设报价,个人怎么做网站优化,福州网站建设网络公司,平面设计哪里学前言
之前的两篇文章我们主要了解了vector和string的相关知识#xff0c;从中我们知道可以通过下标来访问vector的元素或者string的字符#xff0c;但是除了这种方式还有一种更为通用的方式获取元素#xff0c;那就是迭代器#xff0c;这篇文章就会简单介绍迭代器的相关内…前言
之前的两篇文章我们主要了解了vector和string的相关知识从中我们知道可以通过下标来访问vector的元素或者string的字符但是除了这种方式还有一种更为通用的方式获取元素那就是迭代器这篇文章就会简单介绍迭代器的相关内容。
迭代器简介
在我们使用容器去存储元素的时候有时候会需要获取存储的元素而迭代器就是用于从容器中获取元素的基本上所有容器的库都支持迭代器但是只有其中一小部分支持下标获取元素的。虽然string不是容器但是其支持很多容器的操作其中就包括下标和迭代器。
与指针类似迭代器提供了一种间接获取对象的方式对于迭代器而言这个对象就是容器中的元素或者string中的字符我们可以通过迭代器获取一个元素与此同时也可以将指向的对象从一个对象移到下一个对象。迭代器还和指针一样有有效和无效之分所有代表容器中元素或最后一个元素的下一个位置都是有效的其他所有的迭代器都是无效的。
迭代器的使用
不像指针我们不使用地址操作符去获取一个迭代器每一个支持迭代器的类型都有函数可以返回迭代器这些类型都有名为begin和end的函数begin返回的是代表第一个元素的迭代器end的返回的迭代器是容器或者字符串的最后一个元素的下一个位置这个迭代器代表着最后一个元素的下一个位置是一个不存在的元素。如果容器为空则begin和end返回的是同一个迭代器。
auto b v.begin(), e v.end()迭代器的操作
迭代器只支持下表列出来的操作我们可以通过或!比较两个有效的迭代器如果迭代器代表着同一个元素或者都是最后一个元素的下一个位置则相等否则它们不等。 |操作|解释| |*iter|返回迭代器代表的指针指向的值| |iter-mem|等价于(*iter).mem| |iter|指向容器中的下一个元素| |–iter|指向容器中的前一个元素| |iter1 iter2|判断两个迭代器是否相等| |iter1 ! iter2|判断两个迭代器是否不等|
对于指针我们可以使用解引用符获取一个迭代器的元素和指针相同我们只能通过解引用符获取一个有效的迭代器的元素如果解引用一个最后一个元素之后的迭代器结果是未知的。
# includeiostream
# includestring
using namespace std;int main() {string s(some string);if (s.begin() ! s.end()) {auto it s.begin();*it toupper(*it);}coutsendl;}上述的例子就是通过迭代器获取字符串s的首个字符并将其大写。
迭代器从一个元素移动到另一个元素
迭代器私用自增操作符从一个元素移动到该元素的下一个元素自增一个迭代器与自增一个整型十分类似对于整型而言自增的是其本身的值对于迭代器而言其影响是往前进一个位置。 由于end返回的不是一个元素所以其不能自增或者解引用 使用自增操作我们可以重写之前的程序
# includeiostream
# includestring
using namespace std;int main() {string s(some string);for (auto it s.begin(); it ! s.end() !isspace(*it); it) {*it toupper(*it);}coutsendl;}如上例所示我们通过迭代器可以实现循环遍历。
迭代器的类型
正如我们并不准确知道vector的准确类型或者string的size同样的我们也不知道同时也不需要知道迭代器的准确类型但是根据迭代器的读写权限定义了以下几种迭代器的类型: vectorint::iterator it; //it可以读也可以写vectorint的元素string::iterator it2; //it2可以读写字符串里的字符vectorint::const_iterator it3; //it3可以读但是不可以写元素string::const_iterator it4; //it4可以读但是不可以写字符串里面的字符const_iterator表现就像是常量指针可以读取元素但是不能写元素
begin和end操作
begin和end返回的结果取决于它们操作的对象是不是常量如果操作对象是常量那么begin和end返回的就是const_iterator如果对象不是常量那么返回的就是iterator。
# includeiostream
# includestring
# includevector
using namespace std;int main() {
vectorint v;
const vectorint cv;
auto it1 v.begin(); //it返回的是vectorint::iterator
auto it2 v.begin(); //it返回的是vectorint::const_iterator
}这种默认的返回策略有时候并不满足需求在一些情况下一些非常量的vector我们只想读取元素避免元素被更改在C11中提供了以下新的方法cbegin和cend无论vetor是不是常量都返回const_iterator。
auto it3 v.cbegin();迭代器的数学运算
处理之前提到自增和自减外迭代器还支持以下数学运算虽然迭代器是没有下标的概念的但是一下运算都可以理解为是对于下标的操作如加减就是自增和自减的普通形式就是向前移动或者向后移动大小比较就是前后位置的比较。
操作解释iter n同一个容器向前移动niter - n同一个容器向后移动iter1 n将移动结果赋值给iter1iter1 - n将移动结果赋值给iter1, , , 相对位置的比较
这么说起来可能又带你抽象下面用一个二分法来说明
# includeiostream
# includestring
# includevector
using namespace std;int main() {vectorint v {1, 2, 3, 4, 5};auto beg v.begin(), end v.end();auto mid v.begin() (end - beg) / 2;int target 2;while (mid ! end *mid ! target){if (target *mid) {end mid;} else{beg mid;}mid beg (end - beg) / 2;}coutto_string(*mid)endl;}以上例子会打印2也就是元素2的位置。
最后
这篇文章主要介绍了C中的迭代器更多文章可以关注公众号QStack。