c语言setjmp与longjmp函数

来源:互联网 发布:win8好壁纸软件 编辑:程序博客网 时间:2024/05/07 15:34
我们都知道在一个函数内进行跳转,可以使用goto语句,但是如果要在函数之间跳转goto是不能完成的。要想完成函数之间的跳转我们需要借助setjmp和longjmp这两个函数连实现,这都包含在头文件setjmp.h中
函数原型:
        1. int setjmp(jmp_buf env):此函数的功能是将函数在此处的上下文保存在jmp_buf结构体中,以供longjmp从此结构体中恢复。参数env即为保存上下文的jmp_buf结构体变量。如果直接调用该函数返回值为0,若该  函数从longjmp调用返回,返回值为非零,用longjmp函数提供。通过该返回值,我们可以判定setjmp是第一次调用还是从其他地方跳转过来的。
        2.void longjmp(jmp_buf env, int val):此函数的功能是从jmp_buf结构体中恢复由setjmp函数保存的上下文。该函数不返回,而是从setjmp函数返回(longjmp不直接返回,而是从setjmp函数中返回,longjmp执行完后,程序就像是从setjmp函数返回一样)。参数env是由setjmp函数保存过的上下文,参数val表示从longjmp函数传递给setjmp函数的返回值,如果val值为0,setjmp将返回1,否则返回val。

例如:

      

        #该程序运行的结果为:

         i = 0         i = 2

    在c语言中没有像java、c#等面向对象语言的异常处理机制,但是我们同样可以使用setjmp和longjmp这两个函数来模拟实现该功能。
    例如:   
        #include <stdio.h>        #include <setjmp.h>        #define TRY do{ jmp_buf ex_buf__; switch( setjmp(ex_buf__) ){ case 0: while(1){        #define CATCH(x) break; case x:        #define FINALLY break; } default:        #define ETRY } }while(0)        #define THROW(x) longjmp(ex_buf__, x)        #define FOO_EXCEPTION (1)        #define BAR_EXCEPTION (2)        #define BAZ_EXCEPTION (3)        int        main(int argc, char** argv)        {           TRY           {              printf("In Try Statement\n");              THROW( BAR_EXCEPTION );              printf("I do not appear\n");           }           CATCH( FOO_EXCEPTION )           {              printf("Got Foo!\n");           }           CATCH( BAR_EXCEPTION )           {              printf("Got Bar!\n");           }           CATCH( BAZ_EXCEPTION )           {              printf("Got Baz!\n");           }           ETRY;           return 0;        }
    参考资料
        http://en.wikipedia.org/wiki/Setjmp.h
        http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html
        http://www.cnblogs.com/hazir/p/c_setjmp_longjmp.html
0 0
原创粉丝点击