【setjmp和longjmp 】 C语言的非局部跳转:setjmp和longjmp(跨函数长跳转)
非局部跳转<setjmp.h>
头文件<setjmp.h>中的说明提供了一种避免通常的函数调用和返回顺序的途径,特别的,它允许立即从一个多层嵌套的函数调用中返回。
8.1 setjmp
#include <setjmp.h>
int setjmp(jmp_buf env);
8.2 longjmp
#include <setjmp.h>
void longjmp(jmp_buf env, int val);
宏longjmp()用于恢复由最近一次调用setjmp()时保存到env的状态信息。当它执行完时,程序就象setjmp()刚刚执行完并返回非0值val那样继续执行。包含setjmp()宏调用的函数一定不能已经终止。所有可访问的对象的值都与调用longjmp()时相同,唯一的例外是,那些调用setjmp()宏的函数中的非volatile自动变量如果在调用setjmp()后有了改变,那么就变成未定义的。
jmp_buf是setjmp.h中定义的一个结构类型,其用于保存系统状态信息。宏函数setjmp会将其所在的程序点的系统状态信息保存到某个jmp_buf的结构变量env中,而调用函数longjmp会将宏函数setjmp保存在变量env中的系统状态信息进行恢复,于是系统就会跳转到setjmp()宏调用所在的程序点继续进行。这样setjmp/longjmp就实现了非局部跳转的功能。
先看一下setjmp和longjmp这两个函数的用法吧。
函数名:
函数原型:int _Cdecl setjmp(jmp_bufjmpb);
作用:
形参:
返回值:
函数名:
函数原型:void _Cdecl longjmp(jmp_buf jmpb, int retval);
作用:
形参:
返回值:
(
jmp_buf是setjmp.h中定义的一个结构类型,其用于保存系统状态信息。宏函数setjmp会将其所在的程序点的系统状态信息保存到某个jmp_buf的结构变量env中,而调用函数longjmp会将宏函数setjmp保存在变量env中的系统状态信息进行恢复,于是系统就会跳转到setjmp()宏调用所在的程序点继续进行。这样setjmp/longjmp就实现了非局部跳转的功能。
)
再来看看它的使用例子吧。
#include<stdio.h>
#include<conio.h>
#include<setjmp.h>
void longjmpfun(jmp_buf jumpPointer);
int main(void)
{
}
void longjmpfun(jmp_buf jumpPointer)
{
}
运行结果:
Function "setjmp" return value: 0
Be about to call longjmp...
Be in longjmpfun
Function "setjmp" return value: 10
一个简单的例子:
详细参考:http://www.cnblogs.com/lienhua34/archive/2012/04/22/2464859.html
下面我们来看一个简单的例子。
1 #include <stdio.h>2 #include <setjmp.h> 3 4 jmp_buf jump_buffer; 5 6 void func(void) 7 { 8 printf("Before calling longjmp\n"); 9 longjmp(jump_buffer, 1); 10 printf("After calling longjmp\n"); 11 } 12 void func1(void) 13 { 14 printf("Before calling func\n"); 15 func(); 16 printf("After calling func\n"); 17 } 18 int main() 19 { 20 if (setjmp(jump_buffer) == 0){ 21 printf("first calling set_jmp\n"); 22 func1(); 23 }else { 24 printf("second calling set_jmp\n"); 25 } 26 return 0; 27 }
代码的运行结果如下
lienhua34@lienhua34-laptop:~/program/test$ ./testfirst calling set_jmpBefore calling funcBefore calling longjmpsecond calling set_jmp
需注意的问题:
#include <stdio.h>
#include <signal.h>
jmp_buf buf;
void handler(int signal)
{
}
int main()
{
#include<setjmp.h>
#include <stdio.h>
#include <signal.h>
sigjmp_buf buf;
void handler(int signal)
{
}
int main()
{
}
2011-04-14
http://blog.csdn.net/jim_wei/article/details/6324113