实例代码:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct student{
int num;
};
struct conf {
char itemName[40];
char itemContect[100];
};
char* getinfo(vector<conf*> & conflist, const char* pitem) {
for (auto pos = conflist.begin(); pos != conflist.end(); ++pos) {
if (_stricmp((*pos)->itemName, pitem) == 0) {
return (*pos)->itemContect;
}
}
return nullptr;
}
int main() {
//一: 迭代器简介
//迭代器是一种遍历容器内元素的 数据类型, 这种数据类型感觉有点像指针,我们可以理解为迭代器用来指向容器中的某个元素。
//通过迭代器,我们就可以读容器中的元素值,读string中的每个字符,HIA可以修改某个迭代器所指向的元素值
//list map这些容器 尽量用迭代器来访问容器中的元素
//二: 容器的迭代器类型
vector<int> iv = { 100, 200, 300 };
vector<int>::iterator iter;//定义迭代器,也必须是 vector<int>
//大家在理解的时候,就把整个vector<int>::iterator 理解成一个类型,这种类型就专门应用于迭代器。
//党我们用这个类型定义一个变量的时候,这个变量就是个迭代器,这里iter这个变量 就是个迭代器
//三:迭代器begin() / end()操作,反向迭代器rbegin()/rend() 操作
//begin()/end()用来 返回 迭代类型。rbegin()/rend()用来返回迭代类型。
//(1) begin()返回一个迭代器类型(大家就理解成返回一个迭代器)
iter = iv.begin();// 如果容器中有元素,则begin返回的迭代器,指向的是容器中的第一个元素。 相当于iter 指向iv[0];
//(2) end(); 返回一个迭代器类型(大家就理解成返回一个迭代器);
iter = iv.end(); // end 返回的迭代器指向的并不是末端元素,而是末端元素的后面,
//(3) 如果一个容器为空,那么begin()和end()返回的迭代器就相同
vector<int> iv2;
vector<int>::iterator iterbegin = iv2.begin();
vector<int>::iterator iterend = iv2.end();
if (iterbegin == iterend) {
cout << "容器iv2为空" << endl;
}
//(4)
vector<int> iv3 = {100, 200, 300}; //定义一个容器
for (vector<int>::iterator iter = iv3.begin(); iter != iv3.end(); iter++) {
cout << *iter << endl; //输出 : 100 200 300
}
//rbegin()/rend() 反向迭代器(逆向迭代器)用于从后往前遍历一个容器
//rbegin(): 返回一个反向迭代器,指向反向迭代器的第一个元素
//rend():返回一个反向迭代器,指向反向迭代器的最后元素的下一个位置
for (vector<int>::reverse_iterator riter = iv3.rbegin(); riter != iv3.rend(); riter++) {
cout << *riter << endl; //输出: 300 200 100
}
//四:迭代器运算符
//(1) *iter: 返回迭代器iter所指向元素的引用。必须要保证这个迭代器指向的是有效的容器元素,
// 不能指向end(),因为end() 是末端元素的后边,也就是end()指向的是一个不存在的元素
//iter = iv3.end();
iter = iv3.begin();
cout << *iter << endl; //输出: 100
//(2) ++iter; iter++; 让迭代器指向容器中下一个元素,已经指向end()的时候你不能再++;
iter = iv3.begin();
iter++; //++iter;
cout << *iter << endl; //输出: 200
//(3) --iter 和--iter:让迭代器指向容器中的上一个元素。已经指向开头元素,就不能再--
iter = iv3.end();
iter--; //--iter;
cout << *iter << endl; //输出: 300
//(4) iter1 == iter2, iter1 != iter2。 判断两个迭代器是否相等。
//如果两个迭代器指向的是同一个元素,就相等,否则就不等
//(5) 如何引用结构中的成员
vector<student> sv;
student mystu;
mystu.num = 100;
sv.push_back(mystu); //把对象mystu赋值到sv容器中
vector<student>::iterator iterstud;
iterstud = sv.begin();//指向第一个元素
cout << (*iterstud).num << endl;
cout << iterstud->num << endl;
//五: const_iterator迭代器,const: 常量
//const_iterator迭代器,表示值不能改变的意思,这里的值不能改变表示这个迭代器指向的元素值不能改变
//只能从容器中读元素,不能通过这个迭代器改写容器中的元素
//iterator 是能读能写
for (vector<int>::const_iterator constIter = iv3.begin(); constIter != iv3.end(); constIter++) {
//*constIter = 4; //报错
cout << *constIter << endl; //可以正常读 输出 : 100 200 300
}
//(1). cbegin() 和 cend()操作
//C++ 11 引入的两个新函数cbegin()、cend(),跟begin()、end()类似。cbegin()、cend()返回的都是常量迭代器;c 代表const
for (auto iter = iv3.cbegin(); iter != iv3.cend(); iter++) {
//*iter = 4; //报错 , 不能给常量赋值,这说明cbegin返回的是常量迭代器。
cout << *iter << endl; //可以正常读 输出 : 100 200 300
}
//六: 迭代器失效
vector<int> vecvalue{ 1,2,3,4,5 };
//for (auto vecitem : vecvalue){
// vecvalue.push_back(888); //在循环中插入数据 导致迭代器失效
// cout << vecitem << endl; //输出数据混乱
//}
//在操作迭代器的过程中(使用了迭代器这种循环体),千万不要改变vector容器的容量,也就是不要增加或者删除vector容器中的元素
//往容器中增加或者从容器中删除元素,这些操作可能也使指向容器元素的指针、引用、迭代器失效。
//失效就表示不能再带吧任何容器中的元素,一旦使用失效的东西,程序会直接奔溃。
//(1) 避免迭代器失效1
auto beg = vecvalue.begin();
auto end = vecvalue.end();
while (beg != end) {
cout << *beg << endl;
//我们往这个位置插入新值
vecvalue.insert(beg, 80); //插入新值,第一个参数为插入位置,第二个参数为插入的元素
break; //为了防止迭代器失效,插入完毕就break出循环体
++beg;
}
beg = vecvalue.begin();
end = vecvalue.end();
while (beg != end) {
cout << *beg << endl;
++beg;
}
//(2) 避免迭代器失效2
auto iterea = vecvalue.begin();
while (iterea != vecvalue.end()) {
iterea = vecvalue.erase(iterea);
}
//(3) 避免迭代器失效3
vecvalue = { 1,2,3,4,5 };
while (!vecvalue.empty()){
auto iter = vecvalue.begin(); //因为不为空,所以返回begin()是没问题。
vecvalue.erase(iter);//删除该位置上的元素
}
//七:范例演示
//(1) 用迭代器遍历一下string类型数据
string strt("I Love China!");
for (auto iter = strt.begin(); iter != strt.end(); ++iter) {
*iter = toupper(*iter);
}
cout << strt << endl;
//(2) vector 容器常用操作与内存释放
conf* pconf1 = new conf;
strcpy_s(pconf1->itemName, sizeof(pconf1->itemName), "ServerName");
strcpy_s(pconf1->itemContect, sizeof(pconf1->itemContect), "1区");
conf* pconf2 = new conf;
strcpy_s(pconf2->itemName, sizeof(pconf2->itemName), "ServerID");
strcpy_s(pconf2->itemContect, sizeof(pconf2->itemContect), "10000");
vector<conf*> conflist;
conflist.push_back(pconf1); //[0]
conflist.push_back(pconf2); //[1]
//strcpy_s(pconf1->itemName, sizeof(pconf1->itemName), "ServerName123456");
char* p_tmp = getinfo(conflist, "ServerName");
if (p_tmp != nullptr) {
cout << p_tmp << endl;
}
//我们要释放内存,自己new的就要自己释放,否则会造成内存泄露;
std::vector<conf*>::iterator pos;
for (pos = conflist.begin(); pos != conflist.end();++pos) {
delete(*pos); //只是释放内存 并没有破坏vector中元素 所以迭代器并不会失效
}
conflist.clear(); //这个要不要都行
system("pause");
return 0;
}
示意图