首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C语言实现收益

问用C语言实现收益
EN

Stack Overflow用户
提问于 2013-07-05 05:24:40
回答 2查看 14.9K关注 0票数 12

例如:

代码语言:javascript
复制
int getNext(int n) {
    while (TRUE) {
        n = n+1;
        yield n;
    }
}

int main() {
    while (TRUE) {
        int n = getNext(1);
        if (n > 42)
           break;
        printf("%d\n",n);
    }
}

这样上面的代码将打印从1到42的所有数字。我想让yield把getNext的地址改成yield之后的指令。但是我不知道如何保存上下文(寄存器/变量),因为堆栈将被调用者函数遍历。

注意:

我意识到上面的代码可以很容易地通过静态变量实现,但这不是重点。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-05 15:52:23

你可以这样做,即使在可移植的C中也是如此。下面是一个简单的例子(gcc -Wall gen.c):

代码语言:javascript
复制
#include <stdbool.h>
#include <stdio.h>
#include <setjmp.h>

#define YIELD(func, n) if (! setjmp(func##_gen_jmp)) {  \
      func##_ret = n;                                   \
         longjmp(func##_caller_jmp, 1);                 \
  }


#define GENERATOR(ret, func, argt, argv)        \
  static jmp_buf func##_caller_jmp;             \
  static jmp_buf func##_gen_jmp;                \
  static bool func##_continue=false;            \
  static ret func##_ret;                        \
                                                \
  void func##__real(argt argv);                 \
                                                \
  ret func(argt argv) {                         \
    if (!func##_continue) {                     \
    func##_continue=true ;                      \
      if (! setjmp(func##_caller_jmp)) {        \
        func##__real(argv);                     \
      } else {                                  \
        return func##_ret;                      \
      }                                         \
    }                                           \
     else {                                     \
      longjmp(func##_gen_jmp,1);                \
    }                                           \
    return 0;                                   \
  }                                             \
  void func##__real(argt argv)



GENERATOR(int, getNext, int, n) {
  static int counter;

  counter = n;
    while (true) {
        counter = counter+1;
        YIELD(getNext, counter);
    }
}

int main() {
    while (true) {
      int n = getNext(1);
        if (n > 42)
           break;
        printf("%d\n",n);
    }
    return 0;
}
票数 18
EN

Stack Overflow用户

发布于 2013-07-05 09:00:54

你正在寻找的东西被称为“协程”,并且(至少不是没有失去通用性--在有限的情况下,请参阅另一种方法)在可移植C中是不可能的。你可以通过许多技巧来伪造它们;请参阅http://en.wikipedia.org/wiki/Coroutine#Implementations_for_C中的几个。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17478264

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档