头文件<setjmp.h>定义了宏setjmp,并且为了绕过正常的函数调用和返回规则声明了一个函数和一个类型。
1、类型jmp_buf
它是一个数组类型,适合存储恢复一个调用环境所需的信息。
2、宏setjmp
int setjmp(jmp_buf env);
说明:宏setjmp将它的调用环境保存在它的jmp_buf类型的参数中,以供后面longjmp使用。
返回值:如果返回一个来自直接的调用,则宏setjmp返回0;如果返回一个来自longjmp的调用,则宏setjmp返回一个非0值。
3、函数longjmp
void longjmp(jmp_buf enb,int val);
说明:函数longjmp使用jmp_buf参数来恢复宏setjmp最近一次调用保存的环境;如果没有这样的调用或包含宏setjmp调用的函数已经在其前终止执行,则行为未定义。
返回值:在longjmp完成之后,程序会继续执行。函数longjmp不能让宏setjmp返回0,如果val是0,则宏setjmp返回1。
例:
#include <assert.h>
#include <setjmp.h>
#include <stdio.h>
static int ctr;
static jmp_buf b0;
static void jmpto(int n)
{
longjmp(b0,n);
}
static char *stackptr(void)
{
char ch;
return (&ch);
}
static int tryit(void)
{
jmp_buf b1;
char *sp=stackptr();
ctr=0;
switch(setjmp(b0))
{
case 0:
assert(sp==stackptr());
assert(ctr==0);
++ctr;
jmpto(2);
break;
case 1:
assert(sp==stackptr());
assert(ctr==2);
++ctr;
break;
case 2:
assert(sp==stackptr());
assert(ctr==2);
++ctr;
switch(setjmp(b1))
{
case 0:
assert(sp==stackptr());
assert(ctr==3);
++ctr;
longjmp(b1,-7);
break;
case -7:
assert(sp==stackptr());
assert(ctr==4);
++ctr;
jmpto(3);
case 5:
return (13);
default:
return (0);
}
case 3:
longjmp(b1,5);
break;
}
return (-1);
}
int main()
{
assert(tryit()==13);
printf("sizeof(jmp_buf)=%u\n",sizeof(jmp_buf));
puts("SUCCESS testing <setjmp.h>");
return (0);
}