C语言中的迭代器
C语言中的迭代器的实现方式。
迭代器可以通过一个对象,以一定的序列返回容器对象的内容。在Python中实现迭代器协议要求类实现__iter__
方法,且返回一个特殊的迭代器对象,这个迭代器对象实现了__next__
方法,并且能通过抛出StopIteration
异常来标识迭代器的完成。在C语言中,并没有类似Python中的迭代协议,我们需要自己实现。有被迭代的容器各种各样,迭代器并不是万能的,一般是一种容器对象对于一种迭代器实现。
本文想简述Python中迭代协议的使用,然后在讲述C语言中迭代器的实现。
体会下Python中的实现
以斐波那契数列为例:
1 | class Fib: |
__iter__
特殊方法返回迭代器对象,就是Fib类的实例对象,这个对象实现了__next__
,每次迭代的逻辑就在其中实现:斐波那契数列的定义。
实现了迭代协议后,通过创建实例就可以使用:
1 | def test(): |
这个迭代器会一直计算下去,除非外界主动终止。如果只想输出部分序列,可以使用迭代器切片。
1 | import itertools |
对比下,通过函数的实现更简单:
1 | def fib(n): |
当然也可以改为生成器方法,每次yield一个斐波那契数。
在C语言下,我们也能实现以上优雅的迭代。
C语言下的迭代器
方便起见,我们假定迭代器的对象是双链表链表。可以支持头或尾两个方向开始迭代。在实现思路上我们模仿Python的实现。创建、获取迭代对象(__iter__
),通过next方法获取下一个输出,通过循环获取所有输出(for i in iter
)。
结点和链表的定义:
1 | typedef struct Node { |
迭代对象
1 | typedef struct listIter { |
创建迭代对象
1 | listIter *listGetIterator(list *list, int direction) { |
实现类似Python中的__next__
,获取迭代器的一个输出
1 | Node *listNext(listIter *iter) { |
通过循环“开启”迭代器:
1 | void main(void) { |
使用类似于Python迭代协议的思路:解决C语言中迭代容器的问题。类似地,其他的数据结构也可以利用上述的思路,不同的是数据结构迭代算法的实现思路不一样。当然,不存在通用的适合任何数据结构的迭代器,因为每个迭代器都需要知道给定数据结构(如序列、树、图)的构造进而定制遍历方式。
转载请包括本文地址:https://allenwind.github.io/blog/4388
更多文章请参考:https://allenwind.github.io/blog/archives/