当前位置: 首页 > news >正文

C++基础补充(01)C++11基于范围的for循环

文章目录

  • 1. 基本语法
    • 1.1 decalaration
      • 默认获取值
      • 引用&
      • 自动类型推导(auto)
    • 1.2 container
      • 数组
      • STL容器
      • 初始化列表
      • 自定义类型
      • 返回容器的函数
  • 2. 其他示例
    • 2.1 遍历数组
    • 2.2 遍历vector,并修改元素
    • 2.3 使用常量引用遍历,防止容器中的值被误修改
  • 3. 小结

C++11 引入了基于范围的for循环,自动迭代一个范围对象中的每个元素,而无需显式地使用循环变量或索引,是一种简化数组遍历、简化容器遍历的语法糖。

语法糖,“锦上添花”的意思,并不会引入新的功能或者改变语言的核心功能,只是让代码更容易理解、编写或维护。提供简洁语法,同时不影响性能。

1. 基本语法

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

1.1 decalaration

默认获取值

是一个变量,依次获取范围中的每个元素的,即遍历过程中每个元素将自己拷贝一份给decalaration,适合用于小型元素,例如 int 等,对于较大较复杂的对象,会有资源开销。
例如:

for(int val:vec)
{
// val 是 vec 中元素的副本
}

引用&

可以通过引用&获取范围中的每个元素,避免复制,适用于较大的数据类型,例如:

for(string& str : vec)
{
// 遍历过程中,str 是 vec 中元素的引用
}

自动类型推导(auto)

通过auto关键字,让编译器自动推导元素的类型。配合引用&,可以自动处理复杂类型的推导。例如:

for(auto& elem: vec)
{
// auto& 推导出 vec 中元素的类型,通过引用获取元素
}

1.2 container

container,是被遍历的范围对象,必须支持支持begin() 和end()函数,这样才能让 for 循环知道从哪里开始和结束遍历。常见的范围对象有数组、STL容器、初始化列表,或者返回类型为容器的函数。

数组

int arr[] = {1,2,3,4,5};
for(int val:arr)
{cout<<val<<" ";
}

STL容器

例如 std::vector、std::list、std::map 等标准容器

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int>vec = { 1,2,3,4,5 };for (int i : vec){cout << i << " ";}cout << endl;return 0;
}
//输出1 2 3 4 5

初始化列表

int main()
{for (int i : { 1, 2, 3, 4, 5 }){cout << i << " ";}cout << endl;return 0;
}
//输出1 2 3 4 5

自定义类型

只要自定义类型提供了begin()和end()函数,就可以被基于范围的for循环遍历。例如:

class CustomContainer
{
public:int* begin() { return &data[0]; }int* end() { return &data[sizeof(data)/sizeof(data[0])]; }// 计算的是数组的长度(即 10)
private:int data[10] = { 1,2,3,4,5 };// 数组自动填充剩余部分为0
};
int main()
{CustomContainer c;for (auto i : c)cout << i << " ";// 输出 1 2 3 4 5 0 0 0 0 0return 0;
}

在C++容器(如数组、vector)等中,end()返回的不是最后一个元素的迭代器,而是指向最后一个元素下一个位置的迭代器,这个位置不是有效的元素,仅仅用于表达结束和终点。

这是C++标准库设计的常见模式,称为半开区间。范围的起点是包含的,而终点是不包含的,包含begin()所指向的元素,不包含end()所指向的位置上的元素。

返回容器的函数

如果一个函数返回容器或可迭代对象,可以直接将函数调用作为范围对象是用。例如

#include <iostream>
#include <vector>
using namespace std;vector<int> getNumbers()
{return { 1,2,3,4,5,6 };
}
int main()
{	for(int i:getNumbers())cout << i << " ";// 输出 1 2 3 4 5 6return 0;
}

2. 其他示例

2.1 遍历数组

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };for(int i:arr)cout << i <<" "; //输出1 2 3 4 5 6 7 8 9 10return 0;
}

2.2 遍历vector,并修改元素

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> vec = { 1,2,3,4,5,6 };for (int& i : vec){i *= 2;}for (int i : vec)cout << i << " "; //输出2 4 6 8 10 12return 0;
}

2.3 使用常量引用遍历,防止容器中的值被误修改

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<string> words = { "Hello","World" };for (const auto& w : words){cout << w << " ";//输出:Hello World}return 0;
}

3. 小结

基于范围的 for 循环背后的实现依赖于两个函数:
begin():指向容器或数组的第一个元素
end():指向容器或数组的末尾元素(不含)
假设我们有如下代码:

#include <iostream>
#include <vector>
#include <string>
using namespace std;int main()
{vector<string> words = { "Hello","World","C++" };for (auto& w : words){cout<<w<<" ";}cout << endl;	return 0;
}

等价于

#include <iostream>
#include <vector>
#include <string>
using namespace std;int main()
{vector<string> words = { "Hello","World","C++" };for (auto w = words.begin(); w != words.end(); w++){cout << *w << " ";}cout << endl;return 0;
}
http://www.lryc.cn/news/451437.html

相关文章:

  • qt6 使用QPSQL
  • 【PostgreSQL】提高篇——公用表表达式(CTE)和窗口函数
  • 【min25筛】【CF2020F】Count Leaves
  • 【d57】【sql】1661. 每台机器的进程平均运行时间
  • ArcGIS共享数据的最佳方法(不丢可视化、标注等各类显示信息一样带)
  • 小程序this.getOpenerEventChannel()当前页面与navigateTo页面之间数据通信
  • 调用飞书接口导入供应商bug
  • 《深度学习》OpenCV 角点检测、特征提取SIFT 原理及案例解析
  • golang grpc初体验
  • 基于小程序+Vue + Spring Boot的进销存库存出库入库统计分析管理系统
  • 【数据结构与算法】时间复杂度和空间复杂度例题
  • 停止模式下USART为什么可以唤醒MCU?
  • Web安全 - 路径穿越(Path Traversal)
  • JSR303微服务校验
  • 56. QTreeWidget的基本使用
  • 领域偏移:协变量移位下的域自适应
  • 前端开发技术框架选型
  • /etc/init.d/mysql
  • Qt_线程介绍与使用
  • 通讯方面的数据,人工智能 机器学习的时候,因为数字都接近于一,数据归一化的一种方法,做了一个简化版本的Z-score标准化
  • python itertools模块介绍
  • 【分布式微服务云原生】5分钟深入剖析Kafka:Leader与Follower分区的秘密及负载均衡的艺术
  • 在线代码编辑器
  • 深入了解 MPlayer:Linux 系统中的多功能多媒体播放器
  • Netty系列-7 Netty编解码器
  • OpenHarmony标准系统上实现对rk系列芯片NPU的支持(npu使用)
  • 大表性能优化的关键技术
  • 广联达 Linkworks办公OA Service.asmx接口存在信息泄露漏洞
  • 如何成为成功的AI产品经理:经验与策略分享
  • spring loCDI 详解