我尝试使用fibonacci
和python
以c
语言制作setjmp()
生成器序列(使用longjmp()
中的yield关键字实现)之类的内容:
#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)
不幸的是,您的程序有不确定的行为。
引用ISO 9899:1999, 7.13.2.1 longjmp
功能,第2段:
longjmp
函数恢复最近调用的环境setjmp
宏在程序的相同调用中使用相应的jmp_buf
论点。如果没有这样的调用,或如果函数包含 调用setjmp
宏已终止执行 208)在临时中,或者如果setjmp
宏的调用在变量的标识符范围内 修改后的类型和执行已将该范围留在过渡期,行为未定义。[...]
208)例如,通过执行
return
语句或,因为另一个longjmp
调用导致了 转移到嵌套调用集早期函数中的setjmp
调用。
(强调我的。)
您
longjmp(childTask, 1);
main
中的语句尝试将控制转移到setjmp
中的child
调用,但是child
的调用已经返回(通过longjmp(mainTask, 1)
)。
这不容易解决。 C不允许您同时运行两个活动功能。从函数返回后(使用return
或longjmp
),您无法重新进入该调用。
答案 1 :(得分:0)
要解决此问题error
,您必须使用static variable
或global variable
。程序运行时,static
变量仍保留在内存中。当声明变量的函数调用结束时,将销毁normal或auto变量:
#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);
}
}