网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > C++ >

基于范围的for循环

时间:2026-03-10 19:00

人气:

作者:admin

标签:

导读:c11基于范围的for循环,语法: for (Type declaration : expression) { // 循环体 } 在上面的语法格式中Type declaration表示遍历声明,在遍历过程中,当前被遍历导的元素会被存储到声明的变量declar...

c++11基于范围的for循环,语法:

for (Type declaration : expression)
{
    // 循环体
}

在上面的语法格式中Type declaration表示遍历声明,在遍历过程中,当前被遍历导的元素会被存储到声明的变量declaration中。expression是要遍历的对象,它可以是表达式、容器、数组、初始化列表等。

如下代码:

#include <iostream>
#include <vector>
using namespace std;

int main(void)
{
    vector<int> t{ 1,2,3,4,5,6 };
    for (auto value : t){    //第一次遍历
        cout << value++ << " ";
    }
    cout << endl;

    for(int value : t){           //第二次遍历
        cout << value << " ";
    }
    
    cout << endl;
    
    for(auto& value : t){        //第三次遍历
        cout << value++ << " ";
    }
    
    cout << endl;
    
    for(auto& value : t){          //第四次遍历
        cout << value << " ";
    }
    
    cout << endl;
    
    for(const auto& value : t){      //第五次遍历
        cout << value << " ";
    }
    
    return 0;
}

运行结果:

1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
2 3 4 5 6 7
2 3 4 5 6 7

在上面的例子中,第一次遍历是将容器中的元素拷贝到声明的遍历变量value中, 因此无法对value的++操作是不影响原数据的,所以第二次遍历的结果不会有改变。第二次遍历中声明遍历变量用的int,因为这里知道遍历的t容器中全是int类型,auto推导出的就是int类型。

第三次遍历时,遍历变量value声明成引用类型,不仅没有拷贝的过程使得效率更高,而且对value的++操作会直接作用到原数据上,因此第四次遍历的结果会全部+1。

在第五次遍历时,遍历变量声明称const auto&,value被限制成只读权限,如果对value进行++操作会报错。

使用注意

1. 关系型容器

在使用基于范围的for循环遍历map容器时:

#include <iostream>
#include <string>
#include <map>
using namespace std;

int main(void)
{
    map<int, string> m{
        {1, "lucy"},{2, "lily"},{3, "tom"}
    };

    // 基于范围的for循环方式
    for (auto& it : m)
    {
        cout << "id: " << it.first << ", name: " << it.second << endl;
    }

    // 普通的for循环方式
    for (auto it = m.begin(); it != m.end(); ++it)
    {
        cout << "id: " << it->first << ", name: " << it->second << endl;
    }

    return 0;
}

上述代码使用了基于范围的for循环方式和普通的for循环方式两种方式对map进行遍历,注意到:

  • 使用普通for循环遍历关系型容器时,auto自动推导出的是一个迭代器类型,需要使用迭代器的类型方式取出元素中的键值对,迭代器返回的是地址:

    it->first;

    it->second;

  • 使用基于范围的for循环方式遍历关系型容器时,auto自动推导出的类型是容器中的value_type,相当于一个std::pair对象,提取键值对的方式:

    it.first;

    it.second;

2. 元素只读

在对基于范围的for循环语法的介绍中可以得知,在for循环内部声明一个变量的引用就可以修改遍历的表达式中的元素的值,但是这并不是用于所有的情况,对应set容器来说,内部元素都是只读的,这是由容器的特性决定的,因此在for循环中auto&会被是为const auto&。

#include <iostream>
#include <set>
using namespace std;

int main(void)
{
    set<int> st{ 1,2,3,4,5,6 };
    for (auto &item : st) 
    {
        cout << item++ << endl;		// error, 不能给常量赋值
    }
    return 0;
}

除此之外,在遍历关系型容器map时也会出现同样的问题,基于范围的for循环中,虽然可以得到一个std::pair引用,但是我们是不能修改里面的first值的,也就是key值。

#include <iostream>
#include <string>
#include <map>
using namespace std;

int main(void)
{
    map<int, string> m{
        {1, "lucy"},{2, "lily"},{3, "tom"}
    };

    for (auto& item : m)
    {
        // item.first 是一个常量
        cout << "id: " << item.first++ << ", name: " << item.second << endl;  // error
    }

    return 0;
}
访问次数

基于范围for循环遍历的对象可以是一个表达式或者容器/数组等。在我们对一个容器进行遍历过程中对这个容器的访问次数时一次还是多次呢?

#include <iostream>
#include <vector>
using namespace std;

vector<int> v{ 1,2,3,4,5,6 };
vector<int>& getRange()
{
    cout << "get vector range..." << endl;
    return v;
}

int main(void)
{
    for (auto val : getRange())
    {
        cout << val << " ";
    }
    cout << endl;

    return 0;
}

上面代码通过getRange()函数对容器v进行访问,每访问一次就会输出一次get vector range...

输出结果:

get vector range...
1 2 3 4 5 6

可以从上面的结果看出只访问了一次,所以不管遍历的容器里面有多少个元素,都只在第一次迭代之前被访问一次,得到这个容器对象之后不会再去重新获取这个对象了。

对应基于范围的for循环来说,冒号后边的表达式只会被执行一次。在得到遍历对象之后会先确定好迭代的范围,基于这个范围直接进行遍历。如果是普通的for循环,在每次迭代的时候都需要判断是否已经到了结束边界。

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
  • 指针空置类型-nullptr

    指针空置类型-nullptr

    先看一段代码: #include lt;iostreamgt; using namespace std; void func(char* p) { cout lt;lt; q...
  • 基于范围的for循环

    基于范围的for循环

    c11基于范围的for循环,语法: for (Type declaration : expression) { // 循环体 } 在上面的...
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信