首页 > 代码库 > setjmp()和longjmp()
setjmp()和longjmp()
1.语言没有异常处理机制,可以使用setjmp和longjmp进行模拟,另外,goto语句不能在函数间跳转,可以使用setjmp和longjmp完成函数间的跳转。
使用setjmp()函数需要包含头文件<setjmp.h>
setjmp()函数用于建立本地的jmp_buf缓冲区并初始化,用于将来跳转到这个地方。
longjmp()函数恢复jmp_buf变量所保存的信息,longjmp()之后返回setjmp()处执行。
1.1使用setjmp处理异常的例子:
# include <stdio.h> # include <setjmp.h> # include <stdlib.h> jmp_buf jmp; int main(void) { int a,b; scanf("%d%d",&a,&b); if(setjmp(jmp)) { printf("division error\n"); system("pause"); return -1; } if(b==0) longjmp(jmp,1); else printf("the result is %d\n",a/b); system("pause"); return 0; }
1.2 setjmp用于函数间的跳转:
#include <stdio.h> #include <setjmp.h> # include <stdlib.h> jmp_buf buf; void f() { int n; scanf("%d",&n); if(n==1) longjmp(buf,1); //把1送入setjmp的返回值 } void main(void) { if(setjmp(buf)==1) printf("1 is input\n"); else f(); system("pause"); }
2.setjmp和longjmp对变量的影响
2.1
setjmp和longjmp的执行过程:
2.2
setjmp和longjump对全局变量和局部变量的影响:在编译器优化的条件下,局部变量的值会回到setjmp调用之前的取值,而全局变量不会。为了使得变量不受setjmp的影响,可以把这个变量声明为全局变量,也可以加上volatile关键字。这个结果是在ubuntu中编译程序得到的,在其它系统或者编译器情形下,结果可能会有不同。
# include <stdio.h> # include <stdlib.h> # include <setjmp.h> int globalvar; jmp_buf buf; int main() { volatile int volvar; int localvar; globalvar=1,volvar=2,localvar=3; if(setjmp(buf)) { printf("globalvar is %d,volvar is %d,localvar is %d\n",globalvar,volvar,localvar); //调用longjmp()之后的变量取值 system("pause"); return 1; } globalvar=11,volvar=12,localvar=13; printf("globalvar is %d,volvar is %d,localvar is %d\n",globalvar,volvar,localvar); //调用longjmp()之前的变量取值 longjmp(buf,1); system("pause"); return 0; }
使用gcc –o test test.c编译,得到以下结果
globalvar is 11,volvar is 12,localvar is 13
globalvaris 11,volvar is 12,localvar is 13
使用gcc –O –o test test.c编译,得到以下结果:
globalvar is 11,volvar is 12,localvar is 13
globalvaris 11,volvar is 12,localvar is 3