c++:迭代器(Iterator)

目录

🚪什么是迭代器?

🔧 迭代器的本质

为什么不用普通数组或下标?

STL容器的迭代器并不是共用一个类型!

迭代器的类型(Iterator Categories)

📦 常见容器的迭代器类型

✅ 迭代器最常用的动作

🚸 初学者推荐写法:使用 auto 和 范围for


🚪什么是迭代器?

迭代器 = “智能指针”,用来一个一个地访问容器中的元素

你可以想象迭代器像是容器中的“手指”或“光标”:

  • 指着某个元素

  • 可以向前走(甚至有些还能往后走)

  • 能取出或修改元素

 示例对比:用数组 vs 用迭代器

int arr[] = {10, 20, 30};
for (int i = 0; i < 3; i++) {std::cout << arr[i];
}

改成 vector + 迭代器写法: 

std::vector<int> v = {10, 20, 30};
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {std::cout << *it;
}
  • v.begin():返回指向第一个元素的迭代器

  • v.end():返回“超出最后一个元素的下一个位置”的迭代器

  • *it:表示取出当前指向的元素

  • ++it:移动到下一个元素

🔧 迭代器的本质

迭代器是一个类类型(不是基本类型)

虽然它看起来像指针(用 *it 解引用,用 ++it 移动),但它本质上是一个 C++ 类对象,封装了访问容器内部元素的逻辑。

🚩你可以这样理解:

指针迭代器
访问数组元素访问容器元素
*ptr 获取值*it 获取元素
是内建类型是类类型(有重载了 *, ++, == 等操作符)

🎓 举个例子看看类型:

std::vector<int> v = {1, 2, 3};
auto it = v.begin();
  • it 实际的类型是 std::vector<int>::iterator

  • 你可以打印:

std::cout << typeid(it).name() << std::endl;

输出可能是:__gnu_cxx::__normal_iterator<int*, std::vector<int>>

🔍 它是一个内部实现的类,封装了指针行为,但比裸指针更安全、更通用。


为什么不用普通数组或下标?

STL 有很多不同的容器:链表、哈希表、红黑树……
它们里面的元素并不一定支持下标 [],但每种容器都提供了“迭代器”接口,你可以统一方式遍历。

容器支持下标?支持迭代器?
vector
list
set
map

每个容器都有自己专属的迭代器类型,std::vector<T>::iterator  这种写法是访问这个类型的一种方式。

STL容器的迭代器并不是共用一个类型!

容器类型对应迭代器类型
std::vector<T>std::vector<T>::iterator
std::list<T>std::list<T>::iterator
std::set<T>std::set<T>::iterator
std::map<K,V>std::map<K,V>::iterator
std::vector<int>::iterator it;  // vector 的迭代器
std::list<double>::iterator it2;  // list 的迭代器

为什么不统一一个 iterator 类型呢?
👉 因为不同容器的内部结构不同(如数组 vs 链表 vs 红黑树),它们的迭代器行为也不同。比如:

  • vector 支持随机访问 (it + 3)

  • list 只支持前后移动(++it, --it

 

迭代器的类型(Iterator Categories)

STL 根据迭代器的能力,把迭代器分成 五类,从弱到强如下:

类型功能示例容器
InputIterator单向只读istream_iterator
OutputIterator单向只写ostream_iterator
ForwardIterator单向读写forward_list
BidirectionalIterator可双向移动list, set, map
RandomAccessIterator支持随机访问 it+n, it1-it2vector, deque, array

💡 STL 算法会根据迭代器的种类选择最优的操作方式。

 

📦 常见容器的迭代器类型

容器支持的迭代器类型
vector, deque, array随机访问迭代器(RandomAccessIterator)
list双向迭代器(BidirectionalIterator)
forward_list单向迭代器(ForwardIterator)
set, map, multimap, multiset双向迭代器(BidirectionalIterator)
unordered_map, unordered_set同样为双向迭代器

随机访问迭代器(vector): 

std::vector<int> v = {1, 2, 3, 4};
auto it = v.begin();
std::cout << *(it + 2);  // 输出:3

 双向迭代器(list):

std::list<int> l = {1, 2, 3};
auto it = l.end(); --it;
std::cout << *it;  // 输出:3

 单向迭代器(forward_list):

std::forward_list<int> fl = {1, 2, 3};
auto it = fl.begin();
++it;  // 可以前进,但不能后退


✅ 迭代器最常用的动作

操作含义
it = container.begin()取得起始位置的迭代器
it != container.end()判断是否结束
++it移动到下一个元素
*it获取当前指向的元素
std::vector<int> nums = {5, 10, 15};
for (auto it = nums.begin(); it != nums.end(); ++it) {std::cout << *it << " ";
}
操作说明
--it移动到上一个元素(双向或更强迭代器)
it == it2, it != it2比较两个迭代器
it + n, it - n随机访问(仅支持随机访问迭代器)
std::distance(it1, it2)两个迭代器之间的距离
std::advance(it, n)将迭代器移动 n 个位置(支持不同迭代器类型)

🚸 初学者推荐写法:使用 auto范围for

从 C++11 开始,可以让写法更简单!

✅ 用 auto 简化迭代器声明:

for (auto it = nums.begin(); it != nums.end(); ++it)

✅ 更简单的方法:范围for(推荐):

范围 for 是 C++11 引入的一种简洁写法,用于遍历容器或数组。它让你不需要写迭代器、不需要用下标,直接访问每一个元素。 

for (元素类型 变量名 : 容器) {// 使用变量名代表当前元素
}

传统写法(使用迭代器): 

std::vector<int> v = {1, 2, 3, 4};
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {std::cout << *it << "\n";
}

 范围 for 写法:

std::vector<int> v = {1, 2, 3, 4};
for (int x : v) {std::cout << x << "\n";
}

 范围 for 背后的原理:

for (auto it = v.begin(); it != v.end(); ++it) {int x = *it;...
}

所以它仍然依赖迭代器,只不过帮你“自动写好了”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/82323.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【文件系统—散列结构文件】

文章目录 一、实验目的实验内容设计思路 三、实验代码实现四、总结 一、实验目的 理解linux文件系统的内部技术&#xff0c;掌握linux与文件有关的系统调用命令&#xff0c;并在此基础上建立面向随机检索的散列结构文件&#xff1b;## 二、实验内容与设计思想 实验内容 1.设…

力扣26——删除有序数组中的重复项

目录 1.题目描述&#xff1a; 2.算法分析&#xff1a; 3.代码展示&#xff1a; 1.题目描述&#xff1a; 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对…

ggplot2 | GO barplot with gene list

1. 效果图 2. 代码 数据是GO的输出结果&#xff0c;本文使用的是 metascape 输出的excel挑选的若干行。 # 1. 读取数据 datread.csv("E:\\research\\scPolyA-seq2\\GO-APA-Timepoint\\test.csv", sep"\t") head(dat)# 2. 选择所需要的列 dat.usedat[, c(…

学习搭子,秘塔AI搜索

什么是秘塔AI搜索 《秘塔AI搜索》的网址&#xff1a;https://metaso.cn/ 功能&#xff1a;AI搜索和知识学习&#xff0c;其中学习部分是亮点&#xff0c;也是主要推荐理由。对应的入口&#xff1a;https://metaso.cn/study 推荐理由 界面细节做工精良《今天学点啥》板块的知…

【C语言】--指针超详解(三)

目录 一.数组名的理解 二.使用指针访问数组 三.一维数组传参的本质 四.冒泡排序 五.二级指针 六.指针数组 6.1--指针数组的定义 6.2--指针数组模拟二维数组 &#x1f525;个人主页&#xff1a;草莓熊Lotso的个人主页 &#x1f3ac;作者简介&#xff1a;C方向学习者 &…

Linux防火墙

1.防火墙是一种位于内部网络与外部网络之间的网络安全系统&#xff0c;它依照特定的规则&#xff0c;允许或限制传输的数据通过&#xff0c;以保护内部网络的安全。以下从功能、分类、工作原理等方面为你详细讲解&#xff1a; 功能访问控制&#xff1a;这是防火墙最主要的功能。…

嵌入式培训之C语言学习完(十七)结构体、共用体、枚举、typedef关键字与位运算

目录 一、结构体&#xff08;struct关键字&#xff09; &#xff08;一&#xff09;声明一个结构体数据类型 &#xff08;二&#xff09;结构体的成员初始化与赋值 a、结构体变量赋值 b、结构体成员初始化 c、结构体的定义形式 &#xff08;三&#xff09;考点&#xff…

Python字典:数据操作的核心容器

在Python编程生态中&#xff0c;字典&#xff08;dict&#xff09;是最常用且功能强大的内置数据结构之一。它以键值对&#xff08;Key-Value Pair&#xff09;的形式存储数据&#xff0c;为快速查找、灵活映射关系提供了天然支持。无论是数据清洗、算法实现还是Web开发&#x…

按位宽提取十六进制值

需求&#xff1a;给出一个十六进制值&#xff0c;要求提取high和low位之间的值。比如16ha0f0&#xff0c;这是一个16bit宽的十六进制数0xa0f0&#xff0c;提取[15:12]范围内的值。 def extract_bits(value, high, low):"""从 value 中提取 [high:low] 位的值:p…

LeRobot 项目部署运行逻辑(六)——visualize_dataset_html.py/visualize_dataset.py

可视化脚本包括了两个方法&#xff1a;远程下载 huggingface 上的数据集和使用本地数据集 脚本主要使用两个&#xff1a; 目前来说&#xff0c;ACT 采集训练用的是统一时间长度的数据集&#xff0c;此外&#xff0c;这两个脚本最大的问题在于不能裁剪&#xff0c;这也是比较好…

SSTI模版注入

1、概念 SSTI是一种常见的Web安全漏洞&#xff0c;它允许攻击者通过注入恶意模板代码&#xff0c;使服务器在渲染模板时执行非预期的操作。 &#xff08;1&#xff09;渲染模版 至于什么是渲染模版&#xff1a;服务器端渲染模板是一种Web开发技术&#xff0c;它允许在服务器端…

关于点胶机的精度

一、精度&#xff1a; 1:X/y轴定位精度常通在5个丝左右&#xff0c;Z轴在3个丝左右&#xff0c; 如果采用伺服电机丝杆配置&#xff0c;可提升至于个2丝左右。 2&#xff1a;胶水控制精度&#xff1a;通过喷阀驱动器&#xff0c;气压等参数&#xff0c;实现胶量控制&#xf…

gitee推送更新失败问题记录:remote: error: hook declined to update refs/heads/master

问题描述&#xff1a; gitee推送更新时&#xff0c;提示&#xff1a; 解决方法&#xff1a; 登录Gitee&#xff0c;进入【个人主页】 点击【个人设置】 更改邮箱的配置&#xff0c;如下&#xff1a; 更改“禁止命令行推送暴露个人邮箱”&#xff0c;将其关闭&#xff1a;

Java如何获取电脑分辨率?

以下是一个 Java 程序示例&#xff0c;用于获取电脑的主屏幕分辨率&#xff1a; import java.awt.*; public class ScreenResolutionExample { public static void main(String[] args) { // 获取默认的屏幕设备 GraphicsDevice device GraphicsEnvironm…

WPF 3D图形编程核心技术解析

一、三维坐标系系统 WPF采用右手坐标系系统&#xff0c;空间定位遵循&#xff1a; X 轴 → 右 Y 轴 → 上 Z 轴 → 观察方向 X轴 \rightarrow 右\quad Y轴 \rightarrow 上\quad Z轴 \rightarrow 观察方向 X轴→右Y轴→上Z轴→观察方向 三维坐标值表示为 ( x , y , z ) (x, y,…

【库(Library)、包(Package)和模块(Module)解析】

在Python中&#xff0c;**库&#xff08;Library&#xff09;、包&#xff08;Package&#xff09;和模块&#xff08;Module&#xff09;**是代码组织的不同层级&#xff0c;而import语句的导入行为与它们密切相关。以下是详细对比和解释&#xff1a; &#x1f4e6; 1. 核心概…

裸机上的 printf:在无操作系统环境下构建 C 标准库

在嵌入式开发和底层系统编程领域&#xff0c;裸机开发是一项极具挑战性但又至关重要的任务。想象一下&#xff0c;在没有操作系统支持的情况下&#xff0c;让 C 语言的标准库函数&#xff0c;如printf正常工作&#xff0c;这听起来是不是很有趣又充满挑战&#xff1f;今天&…

基于STM32F103的智能机械臂识别与控制项目(课件PPT+源代码)

以下是基于 STM32F103 的智能机械臂识别与控制项目的详细介绍&#xff1a; 项目概述 该项目以 STM32F103 为核心控制器&#xff0c;结合多种传感器和技术&#xff0c;实现了机械臂的智能识别与控制功能&#xff0c;可完成仓库货物的识别、搬运等任务&#xff0c;并支持多种控…

Codeforces Round 1023 (Div. 2)

Dashboard - Codeforces Round 1023 (Div. 2) - Codeforces 一个构造问题&#xff0c;我把最大的数放在一个数组&#xff0c;其余数放在另一个数组&#xff0c;就能保证gcd不同 来看代码&#xff1a; #include <bits/stdc.h> using namespace std;int main() {int t;ci…

6.01 Python中打开usb相机并进行显示

本案例介绍如何打开USB相机并每隔100ms进行刷新的代码,效果如下: 一、主要思路: 1. 打开视频流、读取帧 self.cam_cap = cv2.VideoCapture(0) #打开 视频流 cam_ret, cam_frame = self.cam_cap.read() //读取帧。 2.使用定时器,每隔100ms读取帧 3.显示到Qt的QLabel…