在C语言中,goto语句只允许函数内使用,不允许在函数间使用。而执行这种跳转功能的是函数setjmp和longjmp,这两个函数对于处理很深的嵌套函数调用中的出错情况非常有用。
(1)setjmp函数原型
所需头文件 | #include <setjmp.h> |
函数说明 | setjmp用来保存堆栈环境,然后将目前的地址做一个记号,而在程序其他地方调用longjmp时便会直接跳跃到这个记号位置。然后还原堆栈环境,继续程序执行。setjmp首次返回0,代表已作好记号。若返回非0值代表由longjmp()跳转回来 |
函数原型 | int setjmp(jmp_buf env) |
函数传入参数 | env:保存堆栈环境,要求声明为全局变量 |
函数返回值 | 返回0代表已保存好目前堆栈环境,随时可供longjmp()调用,若返回非0值则代表是由longjmp()返回 |
(2)longjmp函数原型
所需头文件 | #include <setjmp.h> |
函数说明 | longjmp会还原到由setjmp保存的堆栈环境。然后跳转到setjmp()之后继续程序的流程 |
函数原型 | void longjmp(jmp_buf env, int val) |
函数传入参数 | env: setjmp所保存的堆栈环境 |
val: 是提供setjmp()的返回值,此值不可为0,若为0系统自动以1代替 | |
函数返回值 | 无 |
(3)setjmp与longjmp函数使用范例
longjmp.c源代码如下:
#include <stdio.h>
#include <setjmp.h>
jmp_buf env ;
int test()
{
printf("Before longjmp()/n") ;
longjmp(env, 123456) ;
printf("After longjmp()/n") ;
return 0 ;
}
int main()
{
int val ;
int i = 1234 ;
if ( ( val = setjmp( env )) != 0 )
{
printf("longjmp call!/n") ;
printf("val=%d, i=%d/n", val, i ) ;
return 0 ;
}
i = 5678 ;
test() ;
return 0 ;
}
编译 gcc longjmp.c –o longjmp。
执行./longjmp,执行结果如下:
Before longjmp()
longjmp call!
val=123456, i=5678
摘录自《深入浅出Linux工具与编程》