使用 setjmp() 和 longjmp() 创建斐波那契生成器序列时出错
error when creating fibonacci generator sequence using setjmp() and longjmp()
我正在尝试使用 setjmp()
和 [=15] 在 c
语言中制作类似于 fibonacci
生成器序列(使用 python
中的 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 不正确(15 位数字不正确)
要解决此问题 error
,您必须使用 static variable
或 global 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);
}
}
很遗憾,您的程序有未定义的行为。
引用 ISO 9899:1999,7.13.2.1 longjmp
函数 ,第 2 段:
The longjmp
function restores the environment saved by the most recent invocation of
the setjmp
macro in the same invocation of the program with the corresponding
jmp_buf
argument. If there has been no such invocation, or if the function containing
the invocation of the setjmp
macro has terminated execution208) in the interim, or if the
invocation of the setjmp
macro was within the scope of an identifier with variably
modified type and execution has left that scope in the interim, the behavior is undefined.
[...]
208) For example, by executing a return
statement or because another longjmp
call has caused a
transfer to a setjmp
invocation in a function earlier in the set of nested calls.
(强调我的。)
你的
longjmp(childTask, 1);
main
中的 语句试图将控制转移到 child
中的 setjmp
调用,但是对 child
的调用已经 returned(通过longjmp(mainTask, 1)
).
这不容易解决。 C 不允许您同时拥有两个活动函数 运行。一旦从一个函数中 return(通过使用 return
或 longjmp
),您将无法重新输入该调用。
我正在尝试使用 setjmp()
和 [=15] 在 c
语言中制作类似于 fibonacci
生成器序列(使用 python
中的 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 不正确(15 位数字不正确)
要解决此问题 error
,您必须使用 static variable
或 global 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);
}
}
很遗憾,您的程序有未定义的行为。
引用 ISO 9899:1999,7.13.2.1 longjmp
函数 ,第 2 段:
The
longjmp
function restores the environment saved by the most recent invocation of thesetjmp
macro in the same invocation of the program with the correspondingjmp_buf
argument. If there has been no such invocation, or if the function containing the invocation of thesetjmp
macro has terminated execution208) in the interim, or if the invocation of thesetjmp
macro was within the scope of an identifier with variably modified type and execution has left that scope in the interim, the behavior is undefined.[...]
208) For example, by executing a
return
statement or because anotherlongjmp
call has caused a transfer to asetjmp
invocation in a function earlier in the set of nested calls.
(强调我的。)
你的
longjmp(childTask, 1);
main
中的 语句试图将控制转移到 child
中的 setjmp
调用,但是对 child
的调用已经 returned(通过longjmp(mainTask, 1)
).
这不容易解决。 C 不允许您同时拥有两个活动函数 运行。一旦从一个函数中 return(通过使用 return
或 longjmp
),您将无法重新输入该调用。