C++迭代器小结-1
这里借助vector容器来讲解C++中的迭代器里的基本语法。
迭代器是遍历容器的一种方式。在C++标准库提供的容器中,尽管有些容器支持以索引的方式进行操作,但是并不是全部容器类型都是这样的。而迭代器作为C++语法自带的一种遍历机制,它很好的支持了所有C++标准库的容器。借助迭代器进行遍历能够很好地使程序员淡化容器本身的数据结构而更多地关注基于容器的操作。毕竟,持有事物是容器的最基本的工作。C++中的迭代器坚持以 从begin()开始到end()结束依次自增(++) 的模式,操作方便快捷。
1、下面对容器的迭代器类型进行一个梳理:
首先是vector的迭代器,这是一个随机访问迭代器:
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 vector<int> psd{1,2,3,4,5,6,7,8}; 5 int main() 6 { 7 vector<int>::iterator it1 = psd.begin(); 8 while(it1!=psd.end()) cout<<*it1++<<endl; 9 //普通正向迭代器 10 vector<int>::reverse_iterator it2 = psd.rbegin(); 11 while(it2!=psd.rend()) cout<<*it2++<<endl; 12 //普通逆向迭代器 13 vector<int>::const_iterator it3 = psd.cbegin(); 14 while(it3!=psd.cend()) cout<<*it3++<<endl; 15 //常量正向迭代器 16 vector<int>::const_reverse_iterator it4 = psd.crbegin(); 17 while(it4!=psd.crend()) cout<<*it4++<<endl; 18 //常量逆向迭代器 19 return 0; 20 }//不再说明运行结果
注意:尽管有的迭代器本身支持了自减运算符,但是不能使用。这不仅违反了迭代器的设计初衷,更会增加隐患。应按照需求准确选择正向或逆向迭代器。
同样,map迭代器依然如此:
1 #include<iostream> 2 #include<string> 3 #include<map> 4 using namespace std; 5 map<int,char> psd; 6 7 void initial(){for(int i=0;i<10;i++)psd[i]='a'+i;} 8 9 int main() 10 { 11 initial();//赋值 12 map<int,char>::iterator it1 = psd.begin(); 13 while(it1!=psd.end()) cout<<it1++->second<<endl; 14 //普通正向迭代器//其余情况略 15 return 0; 16 }
其中const_iterator类型的迭代器是不能通过迭代器修改其所指向的变量的值的。
2、迭代器的比较
迭代器并不一定支持运算符<,但是迭代器一定支持==与!=两种运算符。其中,在第五版C++ primer中对迭代器的这两种运算有这样一句说明:
如果两个迭代器指向的元素相同或者都是同一个容器的尾后迭代器,则它们相等。否则不等。
经过测试,我发现上述语句应当这样理解:只有指向同一个容器的同一个位置(自然就是没有指向元素或指向的元素相同)的两个迭代器才相同。
又:如果一个容器中有两个相同的元素在不同的位置,那么其对应迭代器是不同的。
简而言之:地址相同/位置相同。
3、迭代器中又*与->两种操作符,他们是解引用的操作符,其返回值是目标元素的引用。
综上:迭代器像仿佛一个被特殊化的指针,是遍历标准库容器的一大利器!
P.S. 迭代器这个名词有三种不同的含义: 1、表示迭代器概念本身 2、指容器定义的迭代器类型 3、指某个具体的迭代器对象 我们需要重点理解的是:我们认定某个类型是迭代器的充分必要条件是该类型支持一套操作使得我们能够访问容器的元素或者从某个元素移动到另一个元素。
OK