C++11基于范围for循环之高效遍历新方式

 更新时间:2025年08月12日 09:04:17   作者:咸鱼_要_翻身  
在C++编程中,循环是一种常用的结构,用于重复执行某段代码,这篇文章主要介绍了C++11基于范围for循环之高效遍历新方式的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

一、传统遍历方式的局限性

在C++98中,遍历数组通常采用以下方式:

int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// 将数组元素值全部乘以2
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
    arr[i] *= 2;
}

// 打印数组中的所有元素
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
    cout << arr[i] << " ";
}
cout << endl;

这种传统方式存在几个问题:

  1. 需要手动计算数组长度

  2. 循环控制变量(i)需要显式声明和管理

  3. 容易产生越界错误

  4. 代码冗长,意图不够直观

二、基于范围的for循环语法

基于范围的for循环(range-based for loop)是C++11引入的一种简化循环语法,它提供了一种更简洁的方式来遍历容器或数组中的所有元素。

基本语法

for (declaration : range_expression) {
    // 循环体
}

其中:

  • declaration(声明部分):定义一个变量,每次迭代时它会被初始化为当前元素的值,通常使用auto自动推导类型

  • range_expression(范围部分):表示要遍历的序列(如数组、容器等)

  • for (声明 : 范围) 是基本语法结构

  • 可以使用continue结束本次循环,或break跳出整个循环​

int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// 将数组元素值全部乘以2
for (auto& e : arr) {
    e *= 2;
}

// 打印数组中的所有元素
for (auto e : arr) {
    cout << e << " ";
}
cout << endl;

三、使用示例

1、遍历数组

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

for (int num : arr) {
    cout << num << " ";
}
// 输出: 1 2 3 4 5

2、遍历标准容器

std::vector<std::string> words = {"Hello", "World", "C++"};

for (const auto& word : words) {
    cout << word << " ";
}
// 输出: Hello World C++

3、使用auto自动推导类型

std::list<double> values = {1.1, 2.2, 3.3};

for (auto value : values) {
    cout << value << " ";
}
// 输出: 1.1 2.2 3.3

4、修改容器元素

std::vector<int> nums = {1, 2, 3};

for (auto& num : nums) {
    num *= 2;  // 修改元素
}

// nums现在是 {2, 4, 6}

四、使用条件

1、迭代范围必须明确

  • 对于数组:编译器能确定首元素和末元素的位置

  • 对于类:需要提供begin()end()方法,定义迭代范围

2、迭代对象需要支持迭代器操作

  • 迭代器需要实现++(前进)和==(比较)操作

  • 实际上,任何提供了begin()和end()方法并返回迭代器的类型都可以使用范围for

五、底层实现原理

范围for循环的底层实现基于迭代器:

  • 对于数组:转换为传统的指针遍历

  • 对于容器:转换为使用该容器的迭代器进行遍历

  • 可以通过查看汇编代码验证这一实现方式

工作原理

基于范围的for循环在底层会被编译器转换为传统的迭代器循环。例如:

for (auto& item : container) {
    // ...
}

大致等价于:

{
    auto&& __range = container;
    auto __begin = begin(__range);
    auto __end = end(__range);
    for (; __begin != __end; ++__begin) {
        auto& item = *__begin;
        // ...
    }
}

六、注意事项

1、引用与拷贝:

  • 使用auto item会创建元素的拷贝

  • 使用auto& item会创建元素的引用(可修改原元素)

  • 使用const auto& item会创建常量引用(不可修改原元素)

2、临时范围表达式:

for (auto x : getTemporaryVector()) { /* ... */ }  // 临时对象会延长生命周期

3、不支持的情况:

  • 不能用于指针数组(除非知道数组大小)

  • 不能用于动态分配的数组

  • 不能用于不提供begin()/end()成员或自由函数的类型

4、性能考虑:

  • 对于简单类型,使用auto或auto&性能差异不大

  • 对于复杂类型,避免不必要的拷贝

5、重点:

  1. 当需要修改元素时,迭代变量应声明为引用类型(使用&)

  2. 对于不需要修改的只读访问,使用非引用形式更高效

  3. 范围for循环不支持直接获取当前元素的索引位置

  4. 在循环过程中不应修改容器的大小(如添加/删除元素)

基于范围的for循环大大简化了集合遍历的代码,提高了可读性和安全性,是现代C++编程中推荐使用的遍历方式。

七、自定义类型支持

要让自定义类型支持基于范围的for循环,需要提供begin()和end()成员函数或自由函数:

class MyContainer {
    int data[5] = {1, 2, 3, 4, 5};
public:
    int* begin() { return data; }
    int* end() { return data + 5; }
    // 也可以提供const版本
};

MyContainer c;
for (int x : c) {
    cout << x << " ";
}

总结 

到此这篇关于C++11基于范围for循环之高效遍历新方式的文章就介绍到这了,更多相关C++11范围for循环遍历方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++取余符号%的实现示例

    C++取余符号%的实现示例

    本文主要介绍了C++取余符号%的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-02-02
  • 浅谈C语言中的 #define 宏定义

    浅谈C语言中的 #define 宏定义

    C语言中的#define预处理指令用于文本替换,分为无参宏和带参宏两种形式,下面就来详细的介绍一下如何使用,感兴趣的可以了解一下
    2026-01-01
  • C++超详细讲解隐藏私有属性和方法的两种实现方式

    C++超详细讲解隐藏私有属性和方法的两种实现方式

    为了避免因为将类库中的私有成员开放给类的使用方而导致的软件逻辑外泄,因此需要将对外代码中的私有成员隐藏起来,下面我们来了解一下隐藏私有属性和方法的两种实现方式
    2022-05-05
  • C++函数参数匹配规则示例小结

    C++函数参数匹配规则示例小结

    这篇文章主要介绍了C++函数参数匹配规则,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • VisualStudio2022提交git代码的方法实现

    VisualStudio2022提交git代码的方法实现

    本文主要介绍了VisualStudio2022提交git代码的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 基于Opencv实现双目摄像头拍照程序

    基于Opencv实现双目摄像头拍照程序

    这篇文章主要为大家详细介绍了基于Opencv实现双目摄像头拍照程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • C++11范围for初始化列表auto decltype详解

    C++11范围for初始化列表auto decltype详解

    C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效率
    2025-07-07
  • 自己简单封装的一个CDialog类实例

    自己简单封装的一个CDialog类实例

    这篇文章主要介绍了自己简单封装的一个CDialog类,实例分析了自定义封装CDialog类的相关技巧,比较简单易懂,需要的朋友可以参考下
    2015-04-04
  • C语言规避野指针的方法流程

    C语言规避野指针的方法流程

    野指针就是指针指向的不是一个有效(合法)的地址,在程序中,如果访问野指针,可能会造成程序的崩溃,这篇文章主要介绍了C语言如何规避野指针,需要的朋友可以参考下
    2024-03-03
  • C语言 ffmpeg与sdl实现播放视频同时同步时钟详解

    C语言 ffmpeg与sdl实现播放视频同时同步时钟详解

    使用ffmpeg和sdl实现播放视频后,需要再实现时钟同步才能正常的播放视频,尤其是有音频的情况,我们通常需要将视频同步到音频来确保音画同步
    2022-09-09

最新评论