迭代器模式
本课属于 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 是数组,也无需了解索引的工作原理。这种抽象让你以后可以轻松更改底层数据结构,例如从数组改为链表,而无需更改使用迭代器的代码。
挑战
简单让我们构建一个 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遍历元素,并将每个元素单独打印在一行上。
程序将接收以下输入:
- 数组中的元素数量
- 每行一个整数值
使用迭代器模式打印所有元素:遍历循环中不能直接通过数组索引访问元素!
当输入依次为 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;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C 在线编译器