C语言的异常处理——setjmp


       C语言实现类似JAVA的异常处理,需用用到标准库中的setjmp.h。

       在导入了setjmp.h之后,我们就可以利用里面定义的类型jmp_buf来设置锚点,也就是可能会出现异常的位置,相当于java的try。


       jmp_buf结构体里面存放了寄存器的状态,setjmp(buf)在第一次执行的时候一定是返回0,int setjmp(jmp_buf envbuf)。跟他配合使用的是longjmp(jmp_buf envbuf,int value)。

     当可能出现异常时,我们可以用if(0 == setjmp(buf))设置一个锚点,将异常处理的代码放到else里面。

if(0 == setjmp(buf))

{

      //可能出现异常的代码

}

else

{

    //异常处理代码

}


        当出现异常是,我们用longjmp(buf,value),这样程序将会还原buf里面的环境,程序又会回到if条件判断,但是这次0 == setjmp(buf)一定为假,所以执行的异常处理代码。

      longjmp的第二个参数如果设成0,会自动变为1。所以setjmp()只有第一次设置锚点时才有可能返回0。通过longjmp的第二个参数,我们可以判断异常的类型。

      下面的code就是用了enum表示异常的类型,将异常处理单独提出作为一个函数。

      另外需要注意的是,没一个锚点必须单独声明一个jmp_buf类型的变量,也就是说jmp_buf变量是不能共享使用的。java中的throw固定是返回上一个锚点,但是在C里面,返回到哪个锚点是码农说了算的,所以用的时候要慎重,建议不要做出longlongjmp()这样的跳转。





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

#define TRY(buf,exp) exp = setjmp(buf);if(exp == 0)
#define CATCH else
#define THROW(buf,exp) longjmp(buf,exp)

//every try has a jmp_buf
jmp_buf buf;
jmp_buf buf_f;
void f();
void g();

//we use a enum to represent all exceptions
typedef enum exp
{
    none,
    exp_main,
    exp_f,
    exp_g
}EXP;

EXP exp_kind;

void exception(EXP exp_kind)
{
    switch (exp_kind)
    {
        case exp_main:
            printf("world\n");
            break;
        case exp_f:
            printf("from f()\n");
            break;
        case exp_g:
            printf("form g()\n");
            break;
        default:
            printf("this is default!!!\n");
    }

}

int main()
{
    exp_kind = none;

    TRY(buf,exp_kind)
    {
        printf("Hello,");
        f();
    }
    CATCH
    {
        printf("this is main exception\n");
        exception(exp_kind);
    }
}

void g()
{
    THROW(buf_f,exp_g);
}

void f()
{
    exp_kind = none;
    
    TRY(buf_f, exp_kind)
    {
        g();
    }
    CATCH
    {
        printf("this f() exception\n");
        exception(exp_kind);   
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值