C++教程之迭代器Iterator(转载)

C++教程之迭代器Iterator

一, 前言
之前的两篇文章我们主要了解了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|判断两个迭代器是否不等|
对于指针,我们 可以使用解引用符获取一个迭代器的元素,和指针相同,我们只能通过解引用符获取一个有效的迭代器的元素,如果解引用一个最后一个元素之后的迭代器结果是未知的。
迭代器从一个元素移动到另一个元素
迭代器私用自增操作符从一个元素移动到该元素的下一个元素,自增一个迭代器与自增一个整型十分类似,对于整型而言,自增的是其本身的值,对于迭代器而言,其影响是往前进一个位置。
由于end返回的不是一个元素,所以其不能自增或者解引用
for ( vector < string >:: iterator iter = v1.begin(); iter != v1.end(); iter ++ )
       {
              cout << * iter << endl;
              cout << ( * iter).empty() << endl;
              cout << iter -> empty() << endl;//二者等效
       }

迭代器的类型

正如我们并不准确知道vector的准确类型或者string的size,同样的,我们也不知道同时也不需要知道迭代器的准确类型,但是根据迭代器的读写权限定义了以下几种迭代器的类型:
  vector<int>::iterator it; //it可以读也可以写vector<int>的元素
  string::iterator it2; //it2可以读写字符串里的字符
  vector<int>::const_iterator it3; //it3可以读但是不可以写元素
  string::const_iterator it4; //it4可以读但是不可以写字符串里面的字符
  const_iterator表现就像是 常量指针 ,可以读取元素但是不能写元素
begin和end操作
1.begin和end返回的结果取决于它们操作的对象是不是常量,如果 操作对象是常量 ,那么begin和end返回的就是const_iterator,如果对象不是常量,那么返回的就是iterator。
# include<iostream>
# include<string>
# include<vector>
using namespace std;
int main() {
vector<int> v;
const vector<int> cv;
auto it1 = v.begin(); //it返回的是vector<int>::iterator
auto it2 = v.begin(); //it返回的是vector<int>::const_iterator
}
这种默认的返回策略有时候并不满足需求,在一些情况下一些非常量的vector我们只想读取元素,避免元素被更改,在C++11中提供了以下新的方法cbegin和cend,无论vetor是不是常量都返回const_iterator。
auto it3 = v.cbegin();
2. 反向迭代器
1.定义: 在容器中从尾元素向首元素反向移动的迭代器
2.对于反向迭代器,递增和递减的含义会颠倒过来
递增一个反向迭代器会移动到前一个元素
递减一个迭代器会移动到下一个元素
注意:除了forward_list容器之外,其他容器都支持反向迭代器
2.使用反向迭代器的相关函数
rbegin() —指向容器尾元素
rend()—指向容器首元素之前一个位置
crbegin()
crend()
下面两个c开头的是反向迭代器的const版本,即不能修改迭代器指向位置的值
3.反向迭代器与正向迭代器的比较
for (vector<string>:: reverse_iterator iter = v6.rbegin(); iter != v6.rend(); iter++)
{
    cout << *iter << endl;
}
const_reverse_iterator iter 表示只读
迭代器的数学运算
处理之前提到自增和自减外,迭代器还支持以下数学运算,虽然迭代器是没有下标的概念的,但是一下运算都可以理解为是对于下标的操作,如加减就是自增和自减的普通形式,就是向前移动或者向后移动,大小比较就是前后位置的比较。
iter + n    同一个容器向前移动n个元素
iter - n    同一个容器向后移动n个元素
iter1 += n    将移动结果赋值给iter1
iter1 -= n    将移动结果赋值给iter1
>, >=, <, <=    相对位置的比较
# include<iostream>
# include<string>
# include<vector>
using namespace std;
int main() {
  vector<int> v = {1, 2, 3, 4, 5};
  auto beg = v.begin(), end = v.end();
  auto mid = v.begin() + (end - beg) / 2;//等价于 auto mid = v.begin() + (5 - 0) / 2-->下标之差
  int target = 2;
  while (mid != end && *mid != target)
  {
    if (target < *mid) {
      end = mid;
    } else{
      beg = mid;
    }
    mid = beg + (end - beg) / 2;
  }
  cout<<to_string(*mid)<<endl;
  }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值