来源:https://www.jianshu.com/p/bbb220824c9a

1.在形式上

for的形式是
for(int i=0;i<arr.size();i++){...}

foreach的形式是
for(int i in arr){...}

iterator的形式是

set<int>::iterator it=a.begin();
while(it.hasNext()){ object o =it.next(); ...}

2.条件上

  • for需要知道集合或数组的大小,而且需要是有序的,不然无法遍历;
  • foreach和iterator都不需要知道集合或数组的大小,他们都是得到集合内的每个元素然后进行处理

3.用法差别

  • for循环一般用来处理比较简单的有序的,可预知大小的集合或数组
  • foreach可用于遍历任何集合或数组,而且操作简单易懂,他唯一的不好就是需要了解集合内部类型
  • iterator是最强大的,他可以随时修改或者删除集合内部的元素,并且是在不需要知道元素和集合的大小的情况下进行的,当你需要对不同的容器实现同样的遍历方式时,迭代器是最好的选择!

5.效率差别

同样遍历一个集合,iterator和foreach用时不相上下。for循环用时最少。

----------------------------------------------------

summary

for循环需要了解集合内部类型以及大小;foreach和iterator只需要知道类型、不需要知道大小。三者使用效率差别很小(见博文:https://blog.csdn.net/woniulx2014/article/details/83176360的验证)

对于iterator的使用,可以大大方便编程,C++中的iterator在博文https://blog.csdn.net/zhanh1218/article/details/33340959中有详细解读,这里摘取一些关键的地方:

  1. 迭代器类型可使用解引用操作符(dereference operator)(*)来访问迭代器所指向的元素,同时可以通过这种方式修改元素的值:
    *iter = 0;//对于set无效,这倒不是迭代器的问题,而是set的元素本身就不允许修改

  2.用 == 或 != 操作符来比较两个迭代器,如果两个迭代器对象指向同一个元素,则它们相等,否则就不相等。

  3.可以用迭代器算术操作来移动迭代器直接指向某个元素,例如,下面语句直接定位于 vector 中间元素:

    vector<int>::iterator mid = vi.begin() + vi.size() / 2;
上述代码用来初始化 mid 使其指向 vi 中最靠近正中间的元素。这种直接计算迭代器的方法,与用迭代器逐个元素自增操作到达中间元素的方法是等价的,但前者的效率要高得多。

  4.任何改变 vector 长度的操作都会使已存在的迭代器失效。例如,在调用 push_back 之后,就不能再信赖指向 vector 的迭代器的值了。

  请看例子:
  *iter = i; // set element to which iter refers to i
  ivec.push_back(i*2);
  加上这句代码没问题,正确运行,但是,我们试图在for循环里面执行,即:
  {
  *iter = i; // set element to which iter refers to i
  ivec.push_back(i*2);
  }
  则会莫名其妙退出!

05-21 08:27