如何在C中实现惰性求值?

18 投票
9 回答
4175 浏览
提问于 2025-04-15 15:27

举个例子,

下面这段Python代码:

def multiples_of_2():
  i = 0
  while True:
    i = i + 2
    yield i

我们怎么把它转换成C语言的代码呢?

补充说明:我想把这段Python代码转换成C语言中类似的生成器,并且要有next()函数。我并不是想知道怎么在C语言中写一个函数来输出2的倍数。2的倍数只是用来说明C语言中懒惰求值生成器的问题。

9 个回答

2

正如Will提到的,像Python这样的语言可以自动保存生成器在连续调用之间的状态。而C语言没有这个机制,所以你需要自己来处理。Greg也指出,这种“通用”的做法并不简单,适合有经验的人。传统的C语言做法是,你需要自己定义和维护状态,并在方法中传入和传出。也就是说:

struct multiples_of_two_state {
       int i;
       /* all the state you need should go in here */
};

void multiples_of_two_init(struct multiples_of_two_state *s) {
    s->i = 0;
}

int multiples_of_two_next(struct multiples_of_two_state *s) {
    s->i += 2;
    return s->i;
}

/* Usage */
struct multiples_of_two_state s;
int result;
multiples_of_two_init(&s);
for (int i=0; i<INFINITY; i++) {
    result = multiples_of_two_next(&s);
    printf("next is %d", result);
}
6

我最近找到了一篇不错的文章,讲的是C语言中的协程,里面介绍了一种实现方法。不过,这个内容可不是给胆小的人看的。

20

你可以试着把这个放在一个 struct 里:

typedef struct s_generator {
    int current;
    int (*func)(int);
} generator;

int next(generator* gen) {
    int result = gen->current;
    gen->current = (gen->func)(gen->current);
    return result;
}

然后你可以用下面的方式来定义你的倍数:

int next_multiple(int current) { return 2 + current; }
generator multiples_of_2 = {0, next_multiple};

你可以通过调用下面的代码来获取下一个倍数:

next(&multiples_of_2);

撰写回答