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

C++ 11 for 循环和容器

Range-Based for 循环

C++为 for 提供 for range 的用法。对于 STL(vector/list/map)的遍历带来了极
大的书写便利。

(range for)语句遍历给定序列中的每个元素并对序列中的每个值执行某种操作,
其语法形式是:

for (declaration : expression)statement</code>expression 部分是一个对象,必须是一个序列,比方说用花括号括起来的初始值
列表、数组或者 vector 或 string 等类型的对象。这些类型的共同特点是拥有能返回迭
代器的 begin 和 end 成员。
declaration 部分负责定义一个变量,该变量将被用于访问序列中的基础元素。每
次迭代,declaration 部分的变量会被初始化为 expression 部分的下一个元素值。确
保类型相容最简单的办法是使用 auto 类型说明符。
#include <iostream>
using namespace std;int main(){int arr[10] = {1,2,3,4,5,6,7};for(auto &i: arr){cout<<i<<endl;}string str = "china"; //OKchar  str[] = "china"; //OKchar  * str = "china"; //ERRORfor(auto & ch: str){cout<<ch<<endl;}return 0;
}

for STL


#include <iostream>
#include <vector>
using namespace std;int main(){// 定义一个长度为10的数组,并初始化前7个元素为1, 2, 3, 4, 5, 6, 7,其余元素默认为0int arr[10] = {1, 2, 3, 4, 5, 6, 7};// 使用数组arr的首地址和尾地址(arr+10)初始化一个vector<int>,即vi// arr是数组的首地址,arr+10表示数组的尾地址(即数组最后一个元素的下一个地址)vector<int> vi(arr, arr + 10);// 定义一个vector<int>的迭代器itvector<int>::iterator it;// 使用迭代器遍历vector<int> vifor (it = vi.begin(); it != vi.end(); ++it) {// 输出迭代器指向的元素值,并换行cout << *it << endl;}for (auto & i : vi){i+=5;}for (auto i : vi){cout<<i<<endl;}return 0;
}
#include <iostream>
#include <map>
using namespace std;int main(){// 定义一个map,键类型为int,值类型为stringmap<int, string> mis;// 向map中插入键值对mis[1] = "apple";  // 使用下标操作符插入键值对mis[2] = "banana"; // 使用下标操作符插入键值对mis.insert({0, "zero"}); // 使用insert函数插入键值对// 定义一个map<int, string>的迭代器itmap<int, string>::iterator it;// 使用迭代器遍历mapfor (it = mis.begin(); it != mis.end(); ++it) {// 输出迭代器指向的键和值cout << it->first << " " << it->second << endl;}// 使用范围for循环遍历mapfor (auto & p : mis) {// 输出键和值cout << p.first << " " << p.second << endl;}return 0;
}

vector 初始化

std::vector 是 C++ 标准库中的一个动态数组容器,定义在 头文件中。
它提供了高效的随机访问和在末尾插入/删除元素的能力,
但在中间或开头插入/删除元素的效率较低。
std::vector 是动态大小的,可以根据需要自动调整其大小。

主要特点动态数组:
std::vector 是一个动态数组,可以在运行时根据需要增长或缩小。
它支持高效的随机访问,时间复杂度为 O(1)。高效的末尾操作:
在 std::vector 的末尾插入或删除元素的时间复杂度为 O(1)(平均情况)。低效的中间或开头操作:
在 std::vector 的中间或开头插入或删除元素的时间复杂度为 O(n),因为需要移动后续元素。自动管理内存:
std::vector 自动管理内存,当元素被插入或删除时,它会自动调整其内部存储。

vector 初始化可以有多种方式,下面介绍几种常用的初始化方式。

#include <iostream>
#include <vector>using namespace std;int main()
{// 定义一个数组并初始化int arr[] = {1, 2, 3, 4, 5};// 以下是几种不同的方式来初始化一个vector<int>// 1. 声明一个空的vector<int>,不进行初始化vector<int> vi;// 2. 声明一个大小为5的vector<int>,默认初始化为0vector<int> vi(5);// 3. 声明一个大小为5的vector<int>,每个元素初始化为5vector<int> vi(5, 5);// 4. 使用数组arr的元素来初始化vector<int>vector<int> vi(arr, arr + 5);// 5. 使用初始化列表来初始化vector<int>vector<int> vi = {1, 2, 3, 4, 5};// 6. 使用初始化列表来初始化vector<int>,与上面的方式等价vector<int> vi{1, 2, 3, 4, 5};// 遍历并输出vector<int>中的元素for (auto i : vi) {cout << i << " ";}cout << endl;return 0;
}

list 初始化

std::list 是 C++ 标准库中的一个双向链表容器,定义在 头文件中。
它提供了高效的插入和删除操作,特别是在链表的任意位置进行插入和删除操作时,
时间复杂度为 O(1)。
然而,由于其链表的特性,
随机访问(即通过索引直接访问元素)的效率较低,时间复杂度为 O(n)。

主要特点
双向链表: std::list 是一个双向链表,每个元素都包含指向前一个元素和后一个元素的指针。这使得在链表的任意位置进行插入和删除操作非常高效。不支持随机访问:由于链表的特性,std::list 不支持通过索引直接访问元素,必须通过迭代器遍历链表。高效的插入和删除:在链表的任意位置插入和删除元素的时间复杂度为 O(1),前提是已经有了指向该位置的迭代器。动态大小:std::list 可以根据需要动态增长或缩小,不需要预先分配固定大小的内存。

list 初始化可以有多种方式,下面介绍几种常用的初始化方式。

#include <iostream>
#include <list>using namespace std;int main()
{// 定义一个数组并初始化int arr[] = {1, 2, 3, 4, 5};// 以下是几种不同的方式来初始化一个list<int>// 1. 声明一个空的list<int>,不进行初始化// list<int> vi;// 2. 声明一个大小为5的list<int>,默认初始化为0// list<int> vi(5);// 3. 声明一个大小为5的list<int>,每个元素初始化为5// list<int> vi(5, 5);// 4. 使用数组arr的元素来初始化list<int>// list<int> vi(arr, arr + 5);// 5. 使用初始化列表来初始化list<int>// list<int> vi = {1, 2, 3, 4, 5};// 6. 使用初始化列表来初始化list<int>,与上面的方式等价list<int> vi{1, 2, 3, 4, 5};// 遍历并输出list<int>中的元素for (auto i : vi) {cout << i << " ";}cout << endl;return 0;
}

map 初始化

在C++中,std::map 是一个关联容器,用于存储键值对(key-value pairs),
其中键(key)是唯一的,并且每个键关联一个值(value)。
std::map 通常使用红黑树(Red-Black Tree)实现,
这使得查找、插入和删除操作的时间复杂度为 O(log n)。

主要特点
键值对存储:
std::map 存储键值对,其中键是唯一的。
键和值可以是任意类型,但键必须支持比较操作(通常是 < 操作符)。有序存储:
std::map 中的元素是按照键的顺序自动排序的。高效的查找、插入和删除:
由于使用红黑树实现,std::map 的查找、插入和删除操作的时间复杂度为 O(log n)。动态大小:
std::map 可以根据需要动态增长或缩小,不需要预先分配固定大小的内存。
//todo map 初始化
#include <iostream>
#include <map>
#include <string>using namespace std;int main() {// 定义一个map<int, string>map<int, string> m;// 以下是几种不同的方式来初始化一个map<int, string>// 使用下标操作符插入元素// m[1] = "apple";// m[2] = "banana";// m[3] = "orange";// m[4] = "grape";// 使用insert方法和make_pair插入元素// m.insert(make_pair<int, string>(1, "apple"));// m.insert(make_pair<int, string>(2, "banana"));// m.insert(make_pair<int, string>(3, "orange"));// m.insert(make_pair<int, string>(4, "grape"));// 使用insert方法和map<int, string>::value_type插入元素// m.insert(map<int, string>::value_type(1, "apple"));// m.insert(map<int, string>::value_type(2, "banana"));// m.insert(map<int, string>::value_type(3, "orange"));// m.insert(map<int, string>::value_type(4, "grape"));// 使用初始化列表来初始化map<int, string>map<int, string> m2 = {{1, "apple"},{2, "banana"},{3, "orange"},{4, "grape"}};// 使用insert方法插入一个新元素m2.insert({5, "pear"});// 遍历并输出map<int, string>中的元素for (auto i : m2) {cout << i.first << " " << i.second << endl;}return 0;
}

initializer_list

std::initializer_list 是 C++11 引入的一种标准库类型,
用于表示一组相同类型的数据。它通常用于支持初始化列表的构造函数或其他函数参数。
std::initializer_list 可以方便地传递一组值,而不需要显式地使用数组或向量。

std::initializer_list 的元素是只读的,因此不需要在参数列表中显式地添加 const 关键字。
std::initializer_list 本身的设计就是为了提供一种只读的访问方式。

示例 1:使用 std::initializer_list 初始化容器

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

示例 2:自定义类的构造函数使用 std::initializer_list

#include <iostream>
#include <initializer_list>class MyClass {
public:MyClass(std::initializer_list<int> initList) {for (int value : initList) {std::cout << value << " ";}}
};int main() {MyClass obj = {1, 2, 3, 4, 5};return 0;
}

示例 3:函数参数使用 std::initializer_list

#include <iostream>
#include <initializer_list>void printList(std::initializer_list<int> list) {for (int value : list) {std::cout << value << " ";}
}int main() {printList({1, 2, 3, 4, 5});return 0;
}
注意事项
std::initializer_list 是只读的,不能修改其内容。
std::initializer_list 的元素类型必须是相同的。
std::initializer_list 的构造函数是隐式的,因此可以直接用于初始化。

统一初始化风格

#include <iostream>
#include <vector>
using namespace std;
int main()
{int i = 3;int ii{3};int arr[] = {1,2,3};int arr2[] {1,2,3};vector<int> vi = {1,2,3};vector<int> vi2{1,2,3};return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Linux安全与高级应用(七)深入Linux Shell脚本编程:循环与分支结构的高级应用
  • 【算法】装箱问题
  • Apache Kylin分布式的分析数据仓库
  • pdf怎么加密码怎么设置密码?pdf加密码的几种设置方法
  • Python的安装环境以及应用
  • 日撸Java三百行(day17:链队列)
  • Adobe Premiere Pro 2024 v24.5.0.057 最新免费修改版
  • Flink Maven 依赖
  • gorm入门——如何实现分页查询
  • LVS(Linux virual server)详解
  • 密码学基础-为什么使用真随机数(True Random Number Generators)
  • 【Git】Git安装_配置
  • VisionPro二次开发学习笔记4-使用C#创建绘图图形
  • React(三):PDF文件在线预览(简易版)
  • Qt ts文件详解
  • AngularJS指令开发(1)——参数详解
  • DOM的那些事
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • learning koa2.x
  • leetcode46 Permutation 排列组合
  • Linux下的乱码问题
  • PAT A1017 优先队列
  • PHP的Ev教程三(Periodic watcher)
  • Sass 快速入门教程
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 后端_ThinkPHP5
  • 简单易用的leetcode开发测试工具(npm)
  • 巧用 TypeScript (一)
  • 如何编写一个可升级的智能合约
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • puppet连载22:define用法
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • # 飞书APP集成平台-数字化落地
  • #if 1...#endif
  • #VERDI# 关于如何查看FSM状态机的方法
  • #WEB前端(HTML属性)
  • (1)无线电失控保护(二)
  • (11)MATLAB PCA+SVM 人脸识别
  • (aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (回溯) LeetCode 77. 组合
  • (五)IO流之ByteArrayInput/OutputStream
  • (一)、python程序--模拟电脑鼠走迷宫
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • .NET Core 中的路径问题
  • .Net Remoting(分离服务程序实现) - Part.3
  • .Net 代码性能 - (1)
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET基础篇——反射的奥妙
  • .NET开源纪元:穿越封闭的迷雾,拥抱开放的星辰