zoukankan      html  css  js  c++  java
  • C语言异常处理之 setjmp()和longjmp()

    异常处理之除0情况

    相信大家处理除0时,都会通过函数,然后判断除数是否为0,代码如下所示:

    double divide(doublea,double b)
    {
        const double delta = 0.00000000001;         //由于浮点数不精确,所以需要定义个很小的数  
    
        if(!((-delta<b)&&(b<delta)))
        {
            return  a/b ;
        } 
        else 
        { 
           return 0; 
        }  
    }

    其实这个函数还有瑕疵,当我们调用divide(0,1)时,返回值也是0,在程序运行时,根本无法判断返回值0是不是除法为0的原因.

    其实可以通过setjmp()和longjmp()配合使用

    描述

    • 和goto很相似, 但是可以从一个函数到另外一个函数的跳转,常常用在异常处理上面.
    • 这两个函数需要正确使用,否则会破坏程序顺序执行方式
    • 头文件 #include <setjmp.h>

    setjmp()和longjmp()

    int setjmp(jmp_buf env);

    将当前上下文保存在jmp_buf结构体中(入栈),并返回0

    void longjmp(jmp_buf env,int val);

    从env变量jmp_buf结构体中恢复setjmp()保存的上下文(出栈,并跳转)

    由于跳转,所以会从setjmp函数调用点返回,返回值为val

     

     

    跳转机制 (以 mian()函数 divide()函数 为例):

    mian()函数 调用了 setjmp(env) ,将上下文(入栈)保存在env中,并返回0.

    接着调用 divide()函数 进行除法操作.

    进入 setjmp()函数 后,由于发现除法为0,所以使用 longjmp(env,1)函数 ,恢复 setjmp() 保存的上下文,也就是直接返回到了 main()函数 处理 setjmp(env) 的时候,并返回异常值1

     

    代码实现:

    #include <stdio.h>
    #include <setjmp.h>
    jmp_buf env;
    double divide(double a,double b) { const double delta = 0.00000000001; //由于浮点数不精确,所以需要定义个很小的数 if(!((-delta<b)&&(b<delta))) { return a/b ; } else { longjmp(env,1); //直接跳转到23行,ret=setjmp(env)代码处,并返回异常值(1) return 0; } } int main( ) { int ret; ret=setjmp(env); //手动调用 setjmp(),将返回正常值(0),    if(!ret) //正常操作     {       printf("5/0=%lf ",divide(5,0));     }     else if(ret==1) //异常操作 {       printf("ERR "); } return 0; }

    运行打印:

    ERR

      

    缺陷在于:

    • 若需要两个函数之间跳转,必然要使用全局变量jmp_buf env
    • 跳转使得代码可读性降低
  • 相关阅读:
    Vue路由机制
    谷歌浏览器打不开应用商店的解决方法
    Vue报错——Component template should contain exactly one root element. If you are using vif on multiple elements, use velseif to chain them instead.
    Vue.js学习之——安装
    Vue使用axios无法读取data的解决办法
    关于localstorage存储JSON对象的问题
    2013年整体计划
    个人喜欢的警语收集
    Linux防火墙的关闭和开启
    Flex修改title 转载
  • 原文地址:https://www.cnblogs.com/lifexy/p/8820562.html
Copyright © 2011-2022 走看看