Menu
CoddyTech

迭代器模式

本课属于 Coddy C 学习旅程的“面向对象编程”单元。第 56 课,共 61 课。

迭代器模式提供了一种按顺序访问集合元素的方式,同时不暴露集合的底层结构。你不直接向用户提供数组的访问权限,而是提供一个对象,让它知道如何一次遍历一个数据元素。

迭代器通常需要两条信息:集合的引用和当前位置。在 C 中,我们创建一个结构体来保存这些状态:

typedef struct {
    int* data;      // 指向数组的指针
    int size;       // 元素总数
    int current;    // 当前位置
} IntIterator;

迭代器提供了两个关键函数。has_next() 检查是否还有元素可读取,next() 返回当前元素并向前移动位置:

int has_next(IntIterator* it) {
    return it->current < it->size;
}

int next(IntIterator* it) {
    return it->data[it->current++];
}

使用迭代器看起来很简洁,也隐藏了数组的细节:

IntIterator it = create_iterator(numbers, 5);
while (has_next(&it)) {
    printf("%d\n", next(&it));
}

调用者无需知道 numbers 是数组,也无需了解索引的工作原理。这种抽象让你以后可以轻松更改底层数据结构,例如从数组改为链表,而无需更改使用迭代器的代码。

challenge icon

挑战

简单

让我们构建一个 NumberList 迭代器:一种简洁的抽象,让你可以遍历整数集合,而不必暴露底层数组结构。

你需要将代码组织在三个文件中:

  • iterator.h:定义一个 IntIterator 结构体,其中包含指向整数数组的指针、集合的总大小以及当前位置。声明三个函数:create_iterator(接收数组指针和大小,并返回一个已初始化的迭代器)、has_next(检查是否还有元素)和 next(返回当前元素并推进位置)。别忘了添加包含保护!
  • iterator.c:实现迭代器函数。create_iterator 函数应按值返回一个 IntIterator,并将当前位置设为 0。还有元素可读取时,has_next 函数返回 1,否则返回 0。next 函数返回当前位置的元素,然后递增位置。
  • main.c:读取元素数量,然后将每个整数值读入数组。为这个数组创建一个迭代器,然后使用 while 循环和 has_next、next 遍历元素,并将每个元素单独打印在一行上。

程序将接收以下输入:

  1. 数组中的元素数量
  2. 每行一个整数值

使用迭代器模式打印所有元素:遍历循环中不能直接通过数组索引访问元素!

当输入依次为 4、10、20、30、40 时,输出示例:

10
20
30
40

当输入依次为 3、-5、0、100 时,输出示例:

-5
0
100

当输入依次为 1、42 时,输出示例:

42

迭代器隐藏了数据的存储方式。你的主循环只需询问“还有吗?”和“给我下一个”,无需了解数组索引或内存布局。

亲手试试

#include <stdio.h>
#include "iterator.h"

int main() {
    int n;
    scanf("%d", &n);
    
    int arr[n];
    
    // TODO:将 n 个整数值读入数组
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    
    // TODO:为数组创建一个迭代器
    
    // TODO:使用 while 循环,通过 has_next 和 next 遍历数组
    // 并将每个元素单独打印在一行
    // 在遍历循环中,不要直接使用数组索引!
    
    return 0;
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C 在线编译器