错误

2017-07-30 15 views
1

我试图用setjmp()longjmp(),以使c语言像fibonacci生成序列(即使用yield关键字实现在python):错误

#include <setjmp.h> 
#include <stdio.h> 

jmp_buf mainTask, childTask; 
void child(void); 
int main(void) { 
    long i = 1; 
    if (!setjmp(mainTask)) { 
     printf("%ldth Parent\n", i++); 
     child(); 
    } 
    for (int j = 0;j < 9;j++) { 
     printf("%ldth Parent\n", i++); 
     if (!setjmp(mainTask)) { 
      longjmp(childTask, 1); 
     } 
    } 
} 
void child (void) { 
    int c = 0; 
    long i = 1; 
    long j = 1; 
    long k = 0; 
    for (;;) { 
     printf("i is:%ld j is:%ld\n", i, j); 
     k = i + j; 
     if(i <= j) 
      i = k; 
     else 
      j = k; 
     c++; 
     printf("%dth fib number:%ld\n", c, k); 
     if (!setjmp(childTask)) longjmp(mainTask, 1); 
    } 
} 

它只适用于第一个数字。

*更新: 我预计2,3,5,8,13,... 但它产生2,和的nextS是不正确的(15digits不正确的数字)

+0

你能否用实际以及预期的输出来编辑你的问题? –

+2

我真的希望你这样做只是为了实验。因为没有一个理智的程序员会为了生产代码而创建像这样的意大利面代码。 –

+0

你的想法是正确的。我想挑战自己 – arianpress

回答

2

不幸的是你的程序有不确定的行为:当其中变量被宣布为一个函数调用是在正常或自动变量被销毁。

引用ISO 9899:1999,7.13.2.1的longjmp功能,第2款规定:

longjmp功能恢复由最近的 的setjmp宏的相同的调用调用保存的环境该程序与相应的参数 jmp_buf有关。如果出现了没有这样的调用,或如果包含 的setjmp宏调用的功能已经终止执行208)在临时,或者如果 调用的setjmp宏的是一个标识符与所述范围内的可变 修改后的类型和执行已经在此期间留下了该范围,的行为未定义

[...]

208)。例如,通过执行return陈述或,因为另一longjmp呼吁已经引起早些时候设定的嵌套调用的功能 转移到setjmp调用。

(重点煤矿。)

 longjmp(childTask, 1); 

声明main尝试在child控制转移到setjmp调用,但调用child已经返回(通过longjmp(mainTask, 1))。

这不容易解决。 C不允许您同时运行两个活动函数。从功能返回后(使用returnlongjmp),您不能重新输入该呼叫。

+0

谢谢你强烈而清楚的解释。 :) –

0

为了解决这个error,你必须使用static variableglobal variable。在程序运行时,一个static变量仍保留在内存中。

#include <setjmp.h> 
#include <stdio.h> 

jmp_buf mainTask, childTask; 
void child(void); 
int main(void) { 
    long i = 1; 
    if (!setjmp(mainTask)) { 
     printf("%ldth Parent\n", i++); 
     child(); 
    } 
    for (int j = 0;j < 9;j++) { 
     printf("%ldth Parent\n", i++); 
     if (!setjmp(mainTask)) { 
      longjmp(childTask, 1); 
     } 
    } 
} 
void child (void) { 
    static int c = 0; 
    static long i = 1; 
    static long j = 1; 

    long k = 0; 
    for (;;) { 
     printf("i is:%ld j is:%ld\n", i, j); 
     k = i + j; 
     if(i <= j){ 
      i = k; 
     } 
     else{ 
      j = k; 
     } 
     c++; 
     printf("%dth fib number:%ld\n", c, k); 
     if (!setjmp(childTask)) longjmp(mainTask, 1); 
    } 
} 
+0

它的工作原理,但我认为一种不需要全局变量的方法 – arianpress

+0

ok @arianpress。我解决了 。现在你可以试试这种方式。 :) –

+1

你的代码仍然有未定义的行为。看到我的答案。 – melpomene