C++高级_ 迭代器(iterator)的基本原理和使用方法

除了使用下标来访问vector对象的元素外,标准库还提供了另一种检测元素的方法:使用迭代器(iterator)迭代器就如同一个指针。迭代器就是指针的泛指,可以指向元素。事实上,C++的指针也是一种迭代器。但是,迭代器不仅仅是指针,因此你不能认为他们一定具有地址值。例如,一个数组索引,也可以认为是一种迭代器。

  1. 迭代器是一个“可遍历STL容器内全部或部分元素”的对象。 
  2. 迭代器指出容器中的一个特定位置。 
  3. 迭代器就如同一个指针。 
  4. 迭代器提供对一个容器中的对象的访问方法,并且可以定义了容器中对象 的范围。 

迭代器的类别:   

正向迭代器:组合输入迭代器和输出迭代器的功能,还可以多次解析一个 迭代器指定的位置,可以对一个值进行多次读/写。   

双向迭代器:组合正向迭代器的功能,还可以通过–操作符向后移动位 置。   

随机访问迭代器:组合双向迭代器的功能,还可以向前向后跳过任意个位 置,可以直接访问容器中任何位置的元素。 

双向迭代器支持的操作:
it++, ++it, it–, –it,*it, itA = itB,tA == itB,itA != itB

(其中list,set,multiset,map,multimap支持双向迭代器。)

 

随机访问迭代器支持的操作:
在双向迭代器的操作基础上添加
it+=i, it-=i, it+i(或it=it+i),it[i],itA<itB, itA<=itB, itA>itB, itA>=itB 等功能。

(其中vector,deque支持随机访问迭代器。)

迭代器的概念如下所示:

set<int>::iterator zploo;
↓  →→ ++(迭代)
          {  1,2,3,4,5,6,7,8,9,0  }
↑ ↑

迭代器范围

迭代器是左闭合区间,(begin,end)。 表示自 begin(); 开始,到 end(); 结束(迭代器使用一对迭代器来标记迭代器范围,这两个迭代器分别指向同一个容器中的两个元素或超出末端的下一个位置,通常将它们命名为 first 和 last ,或 beg 和 end ,用于标记容器中的一段元素范围。该范围内的元素包括从first开始到last指向的位置之前的所有元素。如果两个迭代器相等,则迭代器范围为空。)

begin和end必须同时指向同一个容器。

1、什么是左闭合区间?

[first,last),就是包含first,但是不包含last的区间范围。

2、为什么使用左闭合区间?

使用左闭合区间有两个方便的性质:

a、first == last,说明没有区间元素

b、first!=last,说明区间至少有一个元素,而且多次first++,最终可以到达last

c、查找target,返回的位置==last,说明在范围内没有找到target

编程中使用左闭合区间,更重要的是,提供了一致性。我们知道对于数组,和基于连续内存的集合,假如元素个数为5,可访问的范围是[0,5),注意下标5并不是有效元素。

vector迭代器的自增和解引用运算

迭代器类型定义了一些操作来获取迭代器所指向的元素,并允许程序员将迭代器从一个元素移动到另一个元素。

迭代器类型可使用解引用操作符(*操作符)来访问迭代器所指向r 元素:

*iter = 0;

解引用操作符返回迭代器当前所指向的元素

 STL把迭代器划分为5个类别(Category),这5类迭代器分别具有不同的能力,表现为支持不同的运算符,它们都是类模版,因此具有通用性。

标准迭代器

6

迭代器失效及其危险性

迭代器失效是指当前容器底层存储发生变动时,原来指向容器中某个或某些元素的迭代器由于元素的存储位置发生了改变而不再指向它们,从而成为无效的迭代器。使用无效的迭代器就像使用无效的野指针一样危险

可能引起容器存储变动的操作:reserve()、resize()、push_back()、pop_back()、insert()、erase()、clear()等容器方法和一些泛型算法如sort()、copy()、replace()、remove()、unique(),以及集合操作(并、交、差)算法等。

容器的正向遍历和反向遍历:

3
使用迭代器正向遍历:
for(vector<int>::iterator it=vecInt.begin(); it!=vecInt.end(); ++it)
{
	cout << *it;
}

使用迭代器反向遍历:

for(vector<int>::reverse_iterator rit=vecInt.rbegin(); rit!=vecInt.rend(); + +rit) //注意,⼩括号内仍是++rit
	
{
        cout << *rit;
}

3 条评论

  • situs poker uang asli 2016年5月20日

    What’s up, I check your C 高级_ 迭代器(iterator)的基本原理和使用方法-庄朋龙的博客 new stuff daily. Your writing style is witty, keep it up! situs poker uang asli http://feraripoker.com/

  • corburt erilio 2016年10月16日

    My spouse and I absolutely love your blog and find nearly all of your post’s to be just what I’m looking for. can you offer guest writers to write content in your case? I wouldn’t mind creating a post or elaborating on a number of the subjects you write about here. Again, awesome website!

  • corburt erilio 2016年12月31日

    You really make it appear so easy together with your presentation but I in finding this matter to be really one thing which I believe I might never understand. It seems too complicated and very vast for me. I am taking a look ahead on your next put up, I?¦ll try to get the dangle of it!

发表评论