迭代器的简介
(1):迭代器类似于指针类型,它也提供了对对象的间接访问。
(2):指针是c语言中就有的东西,迭代器是c++中才有的,指针用起来灵活高效,迭代器功能更丰富些。
(3):迭代器提供一个对容器对象或者string对象的访问的方法,并且定义了容器范围。
使用迭代器
迭代器和指针不一样,容器和string有迭代器类型同时拥有返回迭代器的成员。比如,容器都有的成员begin和end,其中begin成员复制返回指向第一个元素(第一个字符)的迭代器,而end成员返回指向容器(或string对象)尾元素的下一个位置的迭代器,也就是说end指示的是一个不存在的元素,所以叫end返回的是尾后迭代器。一般我们清楚一个迭代器的准确类型是什么,所以我们都是使用auto或者decltype来定义变量的。
vector<int> v;
auto b=v.begin();
decltype(v.begin()) b=v.begin();
- 1
- 2
- 3
标准容器迭代器的运算符
*iter 返回迭代器iter所指元素的引用
iter->men 解引用iter并获得该元素的名为men的成员,相当于(*iter).men
++iter 令iter指示容器的下一个元素
--iter 令iter指示容器的上一个元素
iter1==iter2 如果两个迭代器指示的是同一个元素或者它指向同一个容器的尾后迭代器,则相等.
- 1
- 2
- 3
- 4
- 5
下面给出一个使用迭代器运算符修改容器元素的代码示例:
#include<iostream>
using namespace std;
#include<vector>
int main()
{
vector <int> v(10, 1);
int i=1;
cout << "未修改前:";
for (auto v_quote : v)
{
cout << v_quote << " " ; //未修改前
}
cout << endl;
for (auto v_quote = v.begin(); v_quote != v.end(); ++v_quote)
{
*v_quote += i;
++i;
}
cout << "修改后:";
for (auto v_quote : v)
{
cout << v_quote << " ";
}
cout << endl;
system("pause");
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
输出结果:
迭代器的类型
那些拥有迭代器的标准库类型都是使用:iterator和const_iterator来表示迭代器的类型:
vector <int> ::iterator it; //it能读写vector<int>的元素
vector <int>::const_iterator it; //it只能读vector<int>的元素,不可以修改vector<int>中的元素
string::iterator s; //s可以读写string对象中的元素
string::const_iterator s; //s只可以读string对象中的元素,不可以修改string对象中的元素
- 1
- 2
- 3
- 4
- 5
- 6
const_iterator和常量指针一样,只可以读取但不可以修改所指的值。在c++11的新标准中,为了便于得到const_iterator类型的返回值,引入两个新的函数,分别是cbegin和cend,功能类似于begin和end,只是返回的值类型为const_iterator;
vector动态增长的限制:
(1):不能再范围for循环中向vector对象添加元素。
(2):任何一种可能改变vector容量的操作,比如push_back,都会使该vector对象的迭代器失效。
迭代器的运算
iter+n //迭代器加上一个整数值仍得到一个迭代器,迭代器指示的新位置向前移动了,指示可能是容器的一个元素或者是尾部的下一个位置
iter-n //相反,迭代器指示的位置向后移动了,指示可能是容器的一个元素或者是尾部的下一个位置
iter1+=n //等价于iter1+n
iter1-=n //等价于iter2-n
iter1-iter2 //两个迭代器的距离,
>,<,>=,<= //位置离begin近的较小
- 1
- 2
- 3
- 4
- 5
- 6
两个迭代器返回的值,在string和vector都为它定义了一个新的类型–difference_type,它是一个带符号的整型。
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
int main()
{
int a[7] = {1,20,10,5,6,7,90};
vector<int> v(a, a + 7);
cout << "input search num:";
int tmp = 0;
cin >> tmp;
sort(v.begin(), v.end());
vector<int>::iterator beg = v.begin();
vector<int>::iterator end = v.end();
vector<int>::iterator mid = beg + (end - beg) / 2;
while (mid != end && *mid != tmp) {
if (*mid > tmp) {
end = mid;
} else {
beg = mid + 1;
}
mid = beg + (end - beg) / 2;
}
if (*mid == tmp)
cout << "find:" << *mid << endl;
else
cout << "Not find" << endl;
return 0;
}
vector的几种初始化及赋值方式:
(1)不带参数的构造函数初始化
//初始化一个size为0的vector
vector<int> abc;
- 1
- 2
(2)带参数的构造函数初始化
//初始化size,但每个元素值为默认值
vector<int> abc(10); //初始化了10个默认值为0的元素
//初始化size,并且设置初始值
vector<int> cde(10,1); //初始化了10个值为1的元素
- 1
- 2
- 3
- 4
(3)通过数组地址初始化
int a[5] = {1,2,3,4,5};
//通过数组a的地址初始化,注意地址是从0到5(左闭右开区间)
vector<int> b(a, a+5);
- 1
- 2
- 3
(4)通过同类型的vector初始化
vector<int> a(5,1);
//通过a初始化
vector<int> b(a);
- 1
- 2
- 3
(5)通过insert初始化
//insert初始化方式将同类型的迭代器对应的始末区间(左闭右开区间)内的值插入到vector中
vector<int> a(6,6);
vecot<int> b;
//将a[0]~a[2]插入到b中,b.size()由0变为3
b.insert(b.begin(), a.begin(), a.begin() + 3);
- 1
- 2
- 3
- 4
- 5
insert也可通过数组地址区间实现插入
int a[6] = {6,6,6,6,6,6};
vector<int> b;
//将a的所有元素插入到b中
b.insert(b.begin(), a, a+7);
- 1
- 2
- 3
- 4
此外,insert还可以插入m个值为n的元素
//在b开始位置处插入6个6
b.insert(b.begin(), 6, 6);
- 1
- 2
(6)通过copy函数赋值
vector<int> a(5,1);
int a1[5] = {2,2,2,2,2};
vector<int> b(10);
/*将a中元素全部拷贝到b开始的位置中,注意拷贝的区间为a.begin() ~ a.end()的左闭右开的区间*/
copy(a.begin(), a.end(), b.begin());
//拷贝区间也可以是数组地址构成的区间
copy(a1, a1+5, b.begin() + 5);
https://blog.csdn.net/yjunyu/article/details/77728410?locationNum=10&fps=1
https://blog.csdn.net/qq_35644234/article/details/52331948