Unix程序跳转—setjmp与longjmp

来源:互联网 发布:linux编程获取串口参数 编辑:程序博客网 时间:2024/05/20 18:43

       在C语言中,不允许使用跳越函数的goto语句。而执行这种跳转功能的是函数setjmp和longjmp。这两个函数对于处理发生在很深的嵌套函数调用中的出错情况非常有用。换句话说,它可以直接跳跃多层调用回到某个指定的地方。并且在执行跳转时,会抛弃一些栈。

函数原型:

#include <setjmp.h>

int setjmp(jmp_buf env);

void longjmp(jmp_buf env, int val);

 

返回值:

setjmp若直接调用则返回0,若从longjmp返回则为该函数的第二个参数val。也就是说,setjmp函数一次调用,多次返回。


参数说明:

setjmp的参数env是一个特殊类型jmp_buf。这一数据类型是某种形式的数组,其中存放在调用longjmp时能用来恢复栈状态的所有信息。一般情况下,env变量是个全局变量,因为需从另一个函数中引用它(即longjmp、setjmp中都要使用)。


实例程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>

static int flag;
static jmp_buf env;

void first();
void second();
void third();

int main()
{
      int ret;
      scanf("%d", &flag);
      ret = setjmp(env);
      switch(ret)
      {
            case 0:
            {
                  printf("this is setjmp\n");
                  break;
            }
            case 1:
            {
                  printf("this is return from second\n");
                  flag = 0;
                  break;
            }
            case 2:
            {
                  printf("this is return from third\n");
                  flag = 0;
                  break;
            }
      }
   
      first();
      return 0;
}

void first()
{
      switch(flag)
      {
            case 0:
                 break;
           case 1:
                 second();
                  break;
            case 2:
                  third();
                  break;
      }
}

void second()
{
      longjmp(env, 1);
}

void third()
{
      longjmp(env, 2);
}


执行结果:


程序说明:

       在first函数中,通过判断全局变量flag来调用second或者third函数,在second和third函数中调用了longjmp,分别返回不同的值。而在setjmp中,我们通过判断返回值来输出信息。一个setjmp函数可以对应多个longjmp函数。从结果中可知,每次运行都打印了两次信息,由此可知,setjmp返回了两次。如果我们将红色部分的代码注释掉,再次编译运行,可以发现程序陷入死循环(因为会不断调用longjmp函数)。

      在使用setjmp和longjmp时,一定要注意避免上述的死循环。此外,setjmp与longjmp会被一些信号打断,我们可以使用sigsetjmp和siglongjmp函数组来代替setjmp和longjmp函数组。


0 0
原创粉丝点击