Loading docs/lang/csl/container.md +1 −5 Original line number Diff line number Diff line Loading @@ -45,11 +45,7 @@ ### 迭代器 STL 容器中的元素都可以用迭代器指向。 迭代器是一种类似指针的东西,可以通过 `containerName<typeName,...>::iterator` 来声明,通过 `*it` 来访问所指向的元素,通过 `++` / `--` 来访问下一个/上一个元素(向前迭代器不能 `--` )。 迭代器分为输入/输出/向前/双向/随机访问迭代器、正向/反向迭代器。 请参考 [迭代器](./iterator.md) 。 ### 共有函数 Loading docs/lang/csl/iterator.md +30 −12 Original line number Diff line number Diff line 在 STL 中,迭代器(Iterator)是用来访问和检查 STL 容器中元素的对象,它的行为模式和指针类似,甚至有不少容器的迭代器类型就是指针。但是它封装了一些有效性检查,并且提供了统一的访问格式。迭代器尽管在使用上与常规的下标访问效果相似,但是由于部分 STL 容器(如 `std::list` )的下标访问有很大的开销,这时在顺序访问的情况下迭代器会比下标访问更加高效。类似的概念在其他很多高级语言中都存在,如 Python 的 `__iter__` 函数,C# 的 `IEnumerator` 。 在 STL 中,迭代器(Iterator)用来访问和检查 STL 容器中元素的对象,它的行为模式和指针类似,但是它封装了一些有效性检查,并且提供了统一的访问格式。类似的概念在其他很多高级语言中都存在,如 Python 的 `__iter__` 函数,C# 的 `IEnumerator` 。 ## 使用方法 ## 基础使用 迭代器听起来比较晦涩,其实迭代器本身可以看作一个数据指针。迭代器主要支持两个运算符:自增和解引用(单目 `*` 运算符),其中自增用来移动迭代器,解引用可以获取或修改它指向的元素。 最常用的使用方法是用迭代器替换普通的 `for` 循环,例如下列代码中两个循环的效果是一致的。(假设已经引用了 `std` 空间中的相关类型) 迭代器听起来比较晦涩,其实迭代器本身可以看作一个数据指针。迭代器主要支持两个运算符:自增 ( `++` ) 和解引用(单目 `*` 运算符),其中自增用来移动迭代器,解引用可以获取或修改它指向的元素。 指向某个 [STL 容器](./container.md) `container` 中元素的迭代器的类型一般为 `container::iterator` 。 迭代器可以用来遍历容器,例如,下面两个 for 循环的效果是一样的: ```cpp vector<int> data(10); Loading @@ -20,14 +23,29 @@ for (vector<int>::iterator iter = data.begin(); iter != data.end(); iter++) 在 STL 的定义中,迭代器根据其支持的操作依次分为以下几类: - InputIterator:只要求支持拷贝、自增和解引访问 - OutputIterator:只要求支持拷贝、自增和解引赋值 - ForwardIterator:即同时满足 InputIterator 和 OutputIterator 的要求 - BidirectionalIterator:在 ForwardIterator 的基础上支持自减(即反向访问) - RandomAccessIterator:在 BidirectionalIterator 的基础上支持加减运算和比较运算(即随机访问) - InputIterator(输入迭代器):只要求支持拷贝、自增和解引访问。 - OutputIterator(输出迭代器):只要求支持拷贝、自增和解引赋值。 - ForwardIterator(向前迭代器):同时满足 InputIterator 和 OutputIterator 的要求。 - BidirectionalIterator(双向迭代器):在 ForwardIterator 的基础上支持自减(即反向访问)。 - RandomAccessIterator(随机访问迭代器):在 BidirectionalIterator 的基础上支持加减运算和比较运算(即随机访问)。 ???+note "为什么输入迭代器叫输入迭代器?" “输入”指的是“可以从迭代器中获取输入”,而“输出”指的是“可以输出到迭代器”。 “输入”和“输出”的施动者是程序的其它部分,而不是迭代器自身。 其实这个“分类”并不互斥——一个“类别”是可以包含另一个“类别”的。例如,在要求使用向前迭代器的地方,同样可以使用双向迭代器。 不同的 [STL 容器](./container.md) 支持的迭代器类型不同,在使用时需要留意。 指针满足随机访问迭代器的所有要求,可以当作随机访问迭代器使用。 ## 相关函数 很多 [STL 函数](./algorithm.md) 都使用迭代器作为参数。 不同的 STL 容器支持的迭代器类型不同,在使用时需要留意。 可以使用 `next(it)` 获取向前迭代器 `it` 的后继。 ## 获取途径 可以使用 `prev(it)` 获取双向迭代器 `it` 的前驱。 STL 容器一般支持从一端或两端开始的访问,以及对 [const 修饰符](../const.md) 的支持。例如容器的 `begin()` 函数可以获得指向容器头部的迭代器,而 `rbegin()` 函数可以获得指向容器尾部的元素的反向迭代器。 [STL 容器](./container.md) 一般支持从一端或两端开始的访问,以及对 [const 修饰符](../const.md) 的支持。例如容器的 `begin()` 函数可以获得指向容器第一个元素的迭代器, `rbegin()` 函数可以获得指向容器最后一个元素的反向迭代器, `cbegin()` 函数可以获得指向容器第一个元素的 const 迭代器, `end()` 函数可以获得指向容器尾端(“尾端”并不是最后一个元素,可以看作是最后一个元素的后继;“尾端”的前驱是容器里的最后一个元素,其本身不指向任何一个元素)的迭代器。 Loading
docs/lang/csl/container.md +1 −5 Original line number Diff line number Diff line Loading @@ -45,11 +45,7 @@ ### 迭代器 STL 容器中的元素都可以用迭代器指向。 迭代器是一种类似指针的东西,可以通过 `containerName<typeName,...>::iterator` 来声明,通过 `*it` 来访问所指向的元素,通过 `++` / `--` 来访问下一个/上一个元素(向前迭代器不能 `--` )。 迭代器分为输入/输出/向前/双向/随机访问迭代器、正向/反向迭代器。 请参考 [迭代器](./iterator.md) 。 ### 共有函数 Loading
docs/lang/csl/iterator.md +30 −12 Original line number Diff line number Diff line 在 STL 中,迭代器(Iterator)是用来访问和检查 STL 容器中元素的对象,它的行为模式和指针类似,甚至有不少容器的迭代器类型就是指针。但是它封装了一些有效性检查,并且提供了统一的访问格式。迭代器尽管在使用上与常规的下标访问效果相似,但是由于部分 STL 容器(如 `std::list` )的下标访问有很大的开销,这时在顺序访问的情况下迭代器会比下标访问更加高效。类似的概念在其他很多高级语言中都存在,如 Python 的 `__iter__` 函数,C# 的 `IEnumerator` 。 在 STL 中,迭代器(Iterator)用来访问和检查 STL 容器中元素的对象,它的行为模式和指针类似,但是它封装了一些有效性检查,并且提供了统一的访问格式。类似的概念在其他很多高级语言中都存在,如 Python 的 `__iter__` 函数,C# 的 `IEnumerator` 。 ## 使用方法 ## 基础使用 迭代器听起来比较晦涩,其实迭代器本身可以看作一个数据指针。迭代器主要支持两个运算符:自增和解引用(单目 `*` 运算符),其中自增用来移动迭代器,解引用可以获取或修改它指向的元素。 最常用的使用方法是用迭代器替换普通的 `for` 循环,例如下列代码中两个循环的效果是一致的。(假设已经引用了 `std` 空间中的相关类型) 迭代器听起来比较晦涩,其实迭代器本身可以看作一个数据指针。迭代器主要支持两个运算符:自增 ( `++` ) 和解引用(单目 `*` 运算符),其中自增用来移动迭代器,解引用可以获取或修改它指向的元素。 指向某个 [STL 容器](./container.md) `container` 中元素的迭代器的类型一般为 `container::iterator` 。 迭代器可以用来遍历容器,例如,下面两个 for 循环的效果是一样的: ```cpp vector<int> data(10); Loading @@ -20,14 +23,29 @@ for (vector<int>::iterator iter = data.begin(); iter != data.end(); iter++) 在 STL 的定义中,迭代器根据其支持的操作依次分为以下几类: - InputIterator:只要求支持拷贝、自增和解引访问 - OutputIterator:只要求支持拷贝、自增和解引赋值 - ForwardIterator:即同时满足 InputIterator 和 OutputIterator 的要求 - BidirectionalIterator:在 ForwardIterator 的基础上支持自减(即反向访问) - RandomAccessIterator:在 BidirectionalIterator 的基础上支持加减运算和比较运算(即随机访问) - InputIterator(输入迭代器):只要求支持拷贝、自增和解引访问。 - OutputIterator(输出迭代器):只要求支持拷贝、自增和解引赋值。 - ForwardIterator(向前迭代器):同时满足 InputIterator 和 OutputIterator 的要求。 - BidirectionalIterator(双向迭代器):在 ForwardIterator 的基础上支持自减(即反向访问)。 - RandomAccessIterator(随机访问迭代器):在 BidirectionalIterator 的基础上支持加减运算和比较运算(即随机访问)。 ???+note "为什么输入迭代器叫输入迭代器?" “输入”指的是“可以从迭代器中获取输入”,而“输出”指的是“可以输出到迭代器”。 “输入”和“输出”的施动者是程序的其它部分,而不是迭代器自身。 其实这个“分类”并不互斥——一个“类别”是可以包含另一个“类别”的。例如,在要求使用向前迭代器的地方,同样可以使用双向迭代器。 不同的 [STL 容器](./container.md) 支持的迭代器类型不同,在使用时需要留意。 指针满足随机访问迭代器的所有要求,可以当作随机访问迭代器使用。 ## 相关函数 很多 [STL 函数](./algorithm.md) 都使用迭代器作为参数。 不同的 STL 容器支持的迭代器类型不同,在使用时需要留意。 可以使用 `next(it)` 获取向前迭代器 `it` 的后继。 ## 获取途径 可以使用 `prev(it)` 获取双向迭代器 `it` 的前驱。 STL 容器一般支持从一端或两端开始的访问,以及对 [const 修饰符](../const.md) 的支持。例如容器的 `begin()` 函数可以获得指向容器头部的迭代器,而 `rbegin()` 函数可以获得指向容器尾部的元素的反向迭代器。 [STL 容器](./container.md) 一般支持从一端或两端开始的访问,以及对 [const 修饰符](../const.md) 的支持。例如容器的 `begin()` 函数可以获得指向容器第一个元素的迭代器, `rbegin()` 函数可以获得指向容器最后一个元素的反向迭代器, `cbegin()` 函数可以获得指向容器第一个元素的 const 迭代器, `end()` 函数可以获得指向容器尾端(“尾端”并不是最后一个元素,可以看作是最后一个元素的后继;“尾端”的前驱是容器里的最后一个元素,其本身不指向任何一个元素)的迭代器。