C++ 11 新特性:基于范围的 for 循环

基于范围的for 循环(Range-based for loop)是 C++11 标准引入的一项特性,它提供了一种更简洁、更安全的遍历容器(如数组、向量等)的方式。

与传统的 for 循环相比,基于范围的 for 循环自动处理迭代,避免了迭代器或下标可能引入的错误,使代码更加易于编写和理解。

基本语法

基于范围的 for 循环的基本语法如下:

cpp 复制代码
for (declaration : expression) {
    // 循环体
}
  • declaration 是当前范围内元素的声明,通常是一个变量定义,这个变量会依次取得 range 中每个元素的值。

  • expression 是要迭代的序列,可以是花括号括起来的初始化列表、数组、容器类对象等,也可以是返回 string 字符串和容器对象的函数。

下面我们通过几个代码示例,学习一下基于范围 for 循环的用法。

使用方法

1、遍历数组和初始化列表

cpp 复制代码
#include <iostream>

int main() {
    int arr[] = {1, 2, 3, 4, 5};

    // 使用基于范围的 for 循环遍历数组
    for (int elem : arr) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;
    
    // 使用基于范围的 for 循环初始化列表
    for (int elem : {6, 7, 8, 9, 10}) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}
// 输出:
// 1 2 3 4 5 
// 6 7 8 9 10

2、遍历容器

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {6, 7, 8, 9, 10};

    // 使用基于范围的for循环遍历vector
    for (int elem : vec) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}
// 输出:6 7 8 9 10 

3、使用 auto 关键字

使用 auto 关键字可以让编译器自动推断元素的类型,这在遍历复杂类型的容器时非常有用。

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>

int main() {
    std::vector<std::string> strings = {"Hello", "World", "C++11"};

    // 使用基于范围的for循环和auto关键字遍历vector
    for (auto& str : strings) { // 使用引用避免拷贝
        std::cout << str << " ";
    }
    std::cout << std::endl;

    return 0;
}
// 输出:Hello World C++11 

4、修改容器元素

如果需要在循环中修改容器元素的值,应使用引用类型。

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 使用基于范围的for循环修改vector元素的值
    for (auto& elem : vec) {
        elem *= 2; // 将每个元素值翻倍
    }

    // 再次遍历显示修改后的值
    for (const auto& elem : vec) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}
// 输出:2 4 6 8 10 

5、返回容器类对象的函数

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>

std::string strings = {"Hello World, C++11"};

std::string return_str() {
    return strings;
}

int main() {
    for (auto& ch : return_str()) { // 使用引用避免拷贝
        std::cout << ch;
    }
    std::cout << std::endl;

    return 0;
}
// 输出:Hello World C++11 

通过这些示例,我们可以看到,基于范围的for循环提供了一种更加简洁和安全的方式来遍历各种容器,使得代码更具可读性和维护性。

有读者可能会问,declaration 参数既可以定义普通形式的变量,也可以定义引用形式的变量,应该如何选择呢?

其实很简单,如果需要在遍历序列的过程中修改器内部元素的值,就必须定义引用形式 的变量;反之,建议定义 const &(常引用)形式的变量(避免了底层复制变量的过程,效率更高),也可以定义普通变量。

相关推荐
从零开始的代码生活_22 分钟前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法
云小逸26 分钟前
【C++ 第七阶段:模板、泛型编程与工程综合详解】
开发语言·c++
GIS阵地1 小时前
QgsSingleBandPseudoColorRenderer 完整详解(QGIS 3.40.13 C++)
开发语言·前端·c++·qt·qgis
王维同学1 小时前
[原创][Windows C++]LSA 认证、安全与通知包的注册表枚举
c++·windows·安全
_wyt0012 小时前
完全背包问题详解
c++·背包dp
皓月斯语4 小时前
B3842 [GESP202306 三级] 春游 题解
数据结构·c++·算法·题解
春日见5 小时前
算法与数据结构----哈希表
数据结构·人工智能·算法·机器学习·自动驾驶·哈希算法·散列表
CedarQR5 小时前
万字长文:从零在 RK3588 上部署 PaddleSpeech 中文 TTS 全流程(FastSpeech2 + HiFiGAN)
开发语言·c++·嵌入式硬件·ubuntu·json
萌动的小火苗5 小时前
嵌入式开发中的栈与队列:任务调度为什么依赖数据结构
数据结构·c++·单片机·嵌入式硬件
叩码以求索5 小时前
统计按位或能得到最大值的子集数目(一)
数据结构·算法