基于范围的for循环

发布时间 2023-12-04 17:04:15作者: Beasts777

文章参考:爱编程的大丙 (subingwen.cn)

1. for循环新语法

在C++98中,对于不同的容器和数组,遍历方式不尽相同,也不够简洁。而在C++11中,基于范围的for循环可以更加方便的遍历容器和数组。

语法:

for(declaration: expression){
    ...
}
  • declaration:当前遍历的变量。默认会将当前遍历到的变量复制给这个变量。如果要修改,那么需要使用引用。
  • expression:要遍历的对象,可以是表达式、容器、数组、初始化列表。

EG:

  • 代码:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    // 只读
    void func_r(){
        vector<int> v = {2, 3, 4};
        for(auto temp : v){
            cout << temp << " ";
        }
        cout << endl;
    }
    // 修改
    void func_w(){
        vector<int> v = {2, 3, 4};
        for(auto &temp : v){
            cout << temp++ << " ";
        }
        cout << endl;
        for(auto &temp : v){
            cout << temp++ << " ";
        }
        cout << endl;
    }
    
    int main(void){
        func_r();
        func_w();
        return 0;
    }
    
  • 输出:

    2 3 4
    2 3 4
    3 4 5
    

2. 使用细节

2.1 关系型容器map

传统的for循环使用迭代器遍历map,在使用迭代器遍历map中的元素时,要取出当前元素的键或者值,需要->,和指针类似。

而在基于范围的for循环中,auto自动推导出的类型是一个键值对类型,取出键或者值时直接通过.即可。

EG:

  • 迭代器遍历map:

    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    
    void func_1(){
        map<int, string> name_map{
            {1, "zhangSan"},
            {2, "liSi"},
            {3, "wangWu"}
        };
        // 传统的遍历
        cout << "传统的基于迭代器的遍历:" << endl;
        for( auto it = name_map.begin(); it != name_map.end(); ++it ){
            cout << "key = " << it->first << " " << "value = " << it->second << endl;
        }
        // 基于范围的遍历
        cout << "基于范围的遍历:" << endl;
        for ( auto &it : name_map ){
            cout << "key = " << it.first << " " << "value = " << it.second << endl;
        }
    }
    
    int main(void){
        func_1();
        return 0;
    }
    
  • 输出:

    传统的基于迭代器的遍历:
    key = 1 value = zhangSan
    key = 2 value = liSi
    key = 3 value = wangWu
    基于范围的遍历:
    key = 1 value = zhangSan
    key = 2 value = liSi
    key = 3 value = wangWu
    

2.2 set元素只读

对于set来说,内部元素是只读的,因此如果使用auto&来遍历,会被视为const auto &

2.3 容器访问次数

对于基于范围的for循环来说,冒号后面的表达式只会执行一次,得到遍历对象后就不会再去重新获取该对象。

而对于普通的for循环,每次迭代的时候都要判断是否已经到了边界。