范围for循环:
1.基于范围的for循环
for(元素类型 元素对象:容器对象)
{
循环体
}
(1.1)如果循环体由单条语句或者单个结构块组成,可以省略花括号
(1.2)用元素对象依次结合容器对象中的每一个元素,每结合一个元素,执行依次循环体,直至容器内的所有元素都被结合完为止.
(1.3)不依赖于下标元素,通用
(1.4)不需要访问迭代器,透明
(1.5)不需要定义处理函数,简洁
#include "stdafx.h" #include <iostream> #include <vector> #include <algorithm> using namespace std; void print(int i) { cout << i << " "; } int _tmain(int argc, _TCHAR* argv[]) { int ai[] {65, 66, 67, 68, 69}; size_t size = sizeof(ai) / sizeof(ai[0]); vector<int> vi(ai, ai + size); //基于下标运算的for循环,不是所有的容器都支持下标运算,不通用 for (size_t i = 0; i < size; ++i) cout << ai[i]<<" "; cout << endl; for (size_t i = 0; i < vi.size(); ++i) cout << vi[i]<<" "; cout << endl; //基于迭代器的for循环,需要指明容器两端,且对迭代器做自增,必须了解迭代器的运算规则,不够透明 for (int *it = ai; it != ai + size; ++it) cout << *it << " "; cout << endl; for (auto it = vi.begin(); it != vi.end(); ++it) cout << *it << " "; cout << endl; //基于泛型函数的for循环,需要提供针对元素的处理函数,对于一般性遍历而言比较繁琐 for_each(ai, ai + size, print); cout << endl; for_each(vi.begin(),vi.end(), print); cout << endl; for (auto a : ai) cout << a << " "; cout << endl; for (auto a : vi) cout << a << " "; cout << endl; for (auto &a : ai) ++a; for (auto &a : vi) --a; for (auto const &a : ai) cout << a << " "; cout << endl; for (auto const &a : vi) cout << a << " "; cout << endl; for (char a : ai) cout << a << " "; cout << endl; for (char a : vi) cout << a << " "; cout << endl; getchar(); return 0; }
2.范围循环的注意事项
(2.1)对map和multimap容器使用范围循环,每次拿到的元素既不是键也不是值,而是由键和值组成的pair
(2.2)在使用基于范围的for循环时,不能违背容器本身的约束
(2.3)基于范围的for循环,无论循环体执行多少次,冒号后面的表达式永远只执行一次
(2.4)基于范围的for循环,其底层实现依然要借助于容器的迭代器,
因此任何可能导致迭代器失效的结构性改变,都可能引发未定义的后果
1 #include "stdafx.h" 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <list> 6 using namespace std; 7 8 list<int> getScores(void) 9 { 10 cout << __FUNCTION__ << endl; 11 return{ 70, 75, 80, 85, 90, 95 }; 12 } 13 14 int _tmain(int argc, _TCHAR* argv[]) 15 { 16 //对map和multimap容器使用范围循环,每次拿到的元素既不是键也不是值,而是由键和值组成的pair 17 multimap<string, int> msi; 18 msi.insert(make_pair("张飞", 100)); 19 msi.insert(make_pair("赵云", 90)); 20 msi.insert(make_pair("关羽", 80)); 21 for (auto c : msi) 22 cout << c.first << ":" << c.second << endl; 23 cout << endl; 24 for (auto it = msi.begin(); it != msi.end(); ++it) 25 cout << it->first << ":" << it->second << endl; 26 cout << endl; 27 28 //在使用基于范围的for循环时,不能违背容器本身的约束 29 /*for (pair<string,int> &c:msi) 30 if (c.first == "张飞") 31 c.first = "张菲菲";*/ 32 for (auto c : msi) 33 cout << c.first << ":" << c.second << endl; 34 cout << endl; 35 //基于范围的for循环,无论循环体执行多少次,冒号后面的表达式永远只执行一次 36 for (auto score : getScores()) 37 cout << score << " "; 38 cout << endl; 39 auto scores = getScores(); 40 for (auto score : scores) 41 { 42 cout << score << " "; 43 //基于范围的for循环,其底层实现依然要借助于容器的迭代器, 44 //因此任何可能导致迭代器失效的结构性改变,都可能引发未定义的后果 45 //scores.pop_front(); 46 } 47 cout << endl; 48 getchar(); 49 return 0; 50 }
3.使自己定义的容器类型支持范围循环
一个类只要提供了分别获取起始和终止迭代器的begin和end函数,就可以支持基于范围的for循环
1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 template <typename T, size_t S> 6 class Array 7 { 8 public: 9 T &operator[](size_t i) 10 { 11 return m_array[i]; 12 } 13 T const &operator[](size_t i)const 14 { 15 return const_cast<Array&>(*this)[i]; 16 } 17 //获取起始迭代器 18 T *begin() 19 { 20 return m_array; 21 } 22 T const *begin()const 23 { 24 return const_cast<Array *>(this)->begin(); 25 } 26 //获取终止迭代器 27 T *end() 28 { 29 return m_array+S; 30 } 31 T const *end()const 32 { 33 return const_cast<Array *>(this)->end(); 34 } 35 private: 36 T m_array[S]; 37 }; 38 39 40 int _tmain(int argc, _TCHAR* argv[]) 41 { 42 int i = 0; 43 Array<int, 5> ai; 44 for (auto &a : ai) 45 a = ++i * 10; 46 auto const &cai = ai; 47 for (auto &a : cai) 48 cout << /*++*/a << " "; 49 cout << endl; 50 getchar(); 51 return 0; 52 }