C++ 11標準之前(C++ 98/03 標準),如果要用 for 循環語句遍歷一個數組或者容器,只能套用如下結構:
for(表達式 1; 表達式 2; 表達式 3){
//循環體
}
例如,下面程序演示了用上述結構遍歷數組和容器的具體實現過程(實例一):
#include <iostream>#include <vector>#include <string.h>using namespace std;int main() { char arc[] = "http://c.biancheng.net/cplus/11/"; int i; //for循環遍歷普通數組 for (i = 0; i < strlen(arc); i++) { cout << arc[i]; } cout << endl; vector<char>myvector(arc,arc+23); vector<char>::iterator iter; //for循環遍歷 vector 容器 for (iter = myvector.begin(); iter != myvector.end(); ++iter) { cout << *iter; } return 0;}
程序執行結果爲:
http://c.biancheng.net/cplus/11/
http://c.biancheng.net/
此示例中,vector 爲 STL 標準庫提供的序列式容器,關於該容器的具體用法,可閱讀《C++ STL vector容器詳解》一節,這裏不再做重複贅述。
而 C++ 11 標準中,除了可以沿用前面介紹的用法外,還爲 for 循環添加了一種全新的語法格式,如下所示:
for (declaration : expression){
//循環體
}
其中,兩個參數各自的含義如下:
declaration:表示此處要定義一個變量,該變量的類型爲要遍歷序列中存儲元素的類型。需要注意的是,C++ 11 標準中,declaration參數處定義的變量類型可以用 auto 關鍵字表示,該關鍵字可以使編譯器自行推導該變量的數據類型。
expression:表示要遍歷的序列,常見的可以爲事先定義好的普通數組或者容器,還可以是用 {} 大括號初始化的序列。
可以看到,同 C++ 98/03 中 for 循環的語法格式相比較,此格式並沒有明確限定 for 循環的遍歷範圍,這是它們最大的區別,即舊格式的 for 循環可以指定循環的範圍,而 C++11 標準增加的 for 循環,只會逐個遍歷 expression 參數處指定序列中的每個元素。
下面程序演示瞭如何用 C++ 11 標準中的 for 循環遍歷實例一定義的 arc 數組和 myvector 容器:
#include <iostream>#include <vector>using namespace std;int main() { char arc[] = "http://c.biancheng.net/cplus/11/"; //for循環遍歷普通數組 for (char ch : arc) { cout << ch; } cout << '!' << endl; vector<char>myvector(arc, arc + 23); //for循環遍歷 vector 容器 for (auto ch : myvector) { cout << ch; } cout << '!'; return 0;}
程序執行結果爲:
http://c.biancheng.net/cplus/11/ !
http://c.biancheng.net/!
這裏有以下 2 點需要說明:
1) 程序中在遍歷 myvector 容器時,定義了 auto 類型的 ch 變量,當編譯器編譯程序時,會通過 myvector 容器中存儲的元素類型自動推導出 ch 爲 char 類型。注意,這裏的 ch 不是迭代器類型,而表示的是 myvector 容器中存儲的每個元素。
2) 仔細觀察程序的輸出結果,其中第一行輸出的字符串和 "!" 之間還輸出有一個空格,這是因爲新格式的 for 循環在遍歷字符串序列時,不只是遍歷到最後一個字符,還會遍歷位於該字符串末尾的 '\0'(字符串的結束標誌)。之所以第二行輸出的字符串和 "!" 之間沒有空格,是因爲 myvector 容器中沒有存儲 '\0'。
除此之外,新語法格式的 for 循環還支持遍歷用{ }
大括號初始化的列表,比如:
#include <iostream>using namespace std;int main() { for (int num : {1, 2, 3, 4, 5}) { cout << num << " "; } return 0;}
程序執行結果爲:
1 2 3 4 5
另外值得一提的是,在使用新語法格式的 for 循環遍歷某個序列時,如果需要遍歷的同時修改序列中元素的值,實現方案是在 declaration 參數處定義引用形式的變量。舉個例子:
#include <iostream>#include <vector>using namespace std;int main() { char arc[] = "abcde"; vector<char>myvector(arc, arc + 5); //for循環遍歷並修改容器中各個字符的值 for (auto &ch : myvector) { ch++; } //for循環遍歷輸出容器中各個字符 for (auto ch : myvector) { cout << ch; } return 0;}
程序執行結果爲:
bcdef
此程序中先後使用了 2 個新語法格式的 for 循環,其中前者用於修改 myvector 容器中各個元素的值,後者用於輸出修改後的 myvector 容器中的各個元素。
有讀者可能會問,declaration 參數既可以定義普通形式的變量,也可以定義引用形式的變量,應該如何選擇呢?其實很簡單,如果需要在遍歷序列的過程中修改器內部元素的值,就必須定義引用形式的變量;反之,建議定義const &
(常引用)形式的變量(避免了底層複製變量的過程,效率更高),也可以定義普通變量。