当前位置:   article > 正文

C++日记——Day5:迭代器、begin()/end(),rbegin()/rend()、迭代器失效、const_iterator_const_iterator指向不存在怎样判定

const_iterator指向不存在怎样判定

迭代器简介

迭代器是一种遍历容器内元素的一种数据类型,这种数据类型感觉有点像指针,我们理解的时候可以理解为欸带起用来指向容器中某个元素。

string,vector,[],很少用[],更常用的访问方式是迭代器(更通用)。

通过迭代器,我们就可以读容器中的元素值,读string中的每个字符,还可以修改某个迭代器所指向的元素值。

 

容器的迭代器类型

  1. vector<int> v{1, 2 ,3};
  2. vector<int>::iterator iter; //定义了一个迭代器,也必须是vector<int>
  3. //把整个的 vector<int>::iterator 理解成一个类型,这种类型专门应用于迭代器。
  4. //当我们用这个类型定义变量的时候,这个变量就是一个迭代器,这里iter就是个迭代器。

 

迭代器的begin()/end()操作,反向迭代器rbgin()/rend操作。

//begin()/end() 用来返回迭代类型。 rbegin()/rend()用来返回迭代类型。

1、begin()返回一个迭代器类型

iter = iv.begin(); //如果容器中有元素,则begin返回迭代器,指向容器的第一个元素相当于iv[0]

2、end():返回的是一个迭代器类型,返回的迭代器指向的是并不是末端元素,而是末端元素的后边,我们就理解成指向的是一个不存在的元素。

iter = iv.end(); 

 3、如果一个容器为空的话那么begin和end返回的迭代器就相同。

  1. vector<int> i {1, 2, 3, 4};
  2. vector<int>::iterator iter_begin;
  3. vector<int>::iterator iter_end;
  4. iter_begin = i.begin();
  5. iter_end = i.end();

4、通用的访问方法

  1. vector<int> i {1, 2, 3, 4};
  2. for (vector<int>::iterator iter = i.begin; iter != i.end(); iter++){
  3. cout << *iter << endl;
  4. }
  5. //反向迭代器
  6. for (vector<int>::reverse_iterator riter = i.rbegin; iter != i.rend(); iter++){
  7. cout << *riter << endl;
  8. }

 反向迭代器原理

 

迭代器运算符

*iter:返回迭代器iter所指向的元素引用。必须要保证中灌迭代器指向的是有效的元素,不能指向end,因为end是末端元素后边,也就是一个不存在的元素。

iter++:指向当前迭代器的下一个元素。已经指向end后就不能在++

iter--:指向容器中的上一个元素,指向begin时不能再--

iter1 == iter2: iter1 != iter2,判断两个迭代器是否相等,否则就不等。

  1. struct student { int num;};
  2. vector<student> sv;
  3. student stu;
  4. stu.num = 10;
  5. sv.push_back(stu);
  6. vector<student>::iterator iter;
  7. iter = sv.begin();
  8. cout << (*iter).num << endl;
  9. cout << iter->num << endl;

 

const_iterator迭代器:const:常量,const_iterator迭代器,表示值不能改变的意思,这里的值不能改变表示这个迭代器指向的元素值不能改变,而不是这个迭代器本身不能改变。所以这个迭代器只能读取元素,不能通过这个迭代器改写容器中的元素

  1. const vector<int> i {1, 2, 3, 4};
  2. vector<int>::const_interator iter; //常量容器必须用常量迭代器读取
  3. for (iter = i.begin; iter != i.end(); iter++){ //可以
  4. cout << *iter << endl;
  5. }
  6. //-----------------------------------------------------------------------
  7. vector<int>::interator iter; //常量容器必须用常量迭代器读取
  8. for (iter = i.begin; iter != i.end(); iter++){ //报错
  9. cout << *iter << endl;
  10. }
  11. //-----------------------------------------------------------------------
  12. vector<int> i {1, 2, 3, 4};
  13. vector<int>::const_interator iter; //常量容器必须用常量迭代器读取
  14. for (iter = i.begin; iter != i.end(); iter++){ //可以
  15. *iter = 4; // 报错,常量迭代器只能读取容器数据,不能修改
  16. cout << *iter << endl;
  17. }

 

cbegin()和cend(),和begin,end类似。cbegin与cend返回的都是常量迭代器。

  1. for (auto iter = iv.cbegin(), iter != iv.cend(), iter++){
  2. *iter = 4;//报错
  3. }

 

迭代器失效问题

  1. vector<int> vecvalue{1, 2, 3, 4};
  2. for(auto v: vecvalue){
  3. }

再操作迭代器过程中千万不要改变,也就是不要增加或者删除vector中的元素。往容器中增加或者删除元素,可能导致迭代器失效也就是不能再代表容器中的任何元素,一旦失效,就等与犯了严重的错误,很多情况下程序会直接崩溃报错。

防止迭代器失效最有效的方法就是修改后break出来,重新生成迭代

 

如何防止迭代器失效

防止迭代器失效要具体查找每种结构的构造方法。

  1. vector<int> vec{1, 2, 3, 4};
  2. vector<int>::iterator beg = vec.begin();
  3. auto end = vec.end();
  4. int icont = 0;
  5. while( beg != vec.end() ){ //每次更新end,防止迭代器失效
  6. vec.insert(beg, 80+icont);
  7. icont++;
  8. if(icont > 5){
  9. break;
  10. }
  11. beg++;
  12. }

 

释放vector

  1. vector<int> iv = {1, 2, 3};
  2. for(vector<int>::iterator iter = iv.begin(); iter != iv.end; ++iter){
  3. iv.erase(iter); //erase函数,移除iter位置上的元素,返回下一个位置元素;
  4. }

上面的写法报错;

  1. vector<int> iv = {1, 2, 3};
  2. auto beg = iv.begin();
  3. while (iter ! = iv.end()){
  4. iter = iv.erase(iter);
  5. }
  6. while (!iv.empty()){
  7. vector<int>::iterator iter = iv.begin();
  8. iv.erase(iter);
  9. }

 

样例:

  1. class conf {
  2. public:
  3. char item_name[40];
  4. char item_content[100];
  5. };
  6. char *get_content(vector<conf *> conf_list, const char *pitem) {
  7. vector<conf *>::iterator conf_item;
  8. for (conf_item = conf_list.begin(); conf_item != conf_list.end(); conf_item++) {
  9. if (_stricmp((*conf_item)->item_name, pitem) == 0) {
  10. return (*conf_item)->item_content;
  11. }
  12. cout << (*conf_item)->item_name << endl;
  13. }
  14. return nullptr;
  15. }
  16. int main()
  17. {
  18. conf *conf1 = new conf;
  19. conf *conf2 = new conf;
  20. strcpy_s(conf1->item_name, sizeof(conf1->item_name), "ServerName");
  21. strcpy_s(conf1->item_content, sizeof(conf1->item_content), "1区");
  22. strcpy_s(conf2->item_name, sizeof(conf2->item_name), "ServerID");
  23. strcpy_s(conf2->item_content, sizeof(conf2->item_content), "1001");
  24. vector<conf *> vec{conf1,conf2};
  25. char *p = get_content(vec, "ServerID");
  26. if (p != nullptr) {
  27. cout << p << endl;
  28. }
  29. else
  30. {
  31. cout << "not match" << endl;
  32. }
  33. vector<conf *>::iterator pos;
  34. for (pos = vec.begin(); pos != vec.end(); pos++) {
  35. delete (*pos);
  36. }
  37. vec.clear();
  38. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/179649
推荐阅读
相关标签
  

闽ICP备14008679号