C++11 for循環(基於範圍的循環)詳解

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 &(常引用)形式的變量(避免了底層複製變量的過程,效率更高),也可以定義普通變量。

圖片


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章