zoukankan      html  css  js  c++  java
  • 第六十三课、C语言的异常处理

    一、异常处理

    1、异常的概念

    (1)、程序在运行过程中可能产生异常

    (2)、异常(Exception)和Bug的区别

    A、异常是程序运行时可预料的执行分支

    B、Bug是程序中的错误,是不被预期的运行方式

    2、异常(Exception)和Bug的对比

    (1)异常

    A、运行时产生除0的情况

    B、需要打开的外部文件存在

    C、数组访问越界

    (2)、Bug

    A、使用野指针

    B、堆数组使用结束后未释放

    C、选择排序无法处理长度为0的数组

    3、C语言经典处理方式:if....else.....

    #include <iostream>
    
    using namespace std;
    
    double divide(double a, double b, int* valid)
    {
        const double delta = 0.000000000000001;
        double ret = 0;
        
        if(!((-delta < b) && (b < delta)))
        {
            ret = a / b;
            *valid = 1;  //正常
        }
        else
        {
            *valid = 0;    //除0错误
        }
        return ret;
    }
    
    int main()
    {
        int valid = 0;
        double r = divide(1, 0, &valid); //当第3个参数为NULL时,还是会出问题
        
        if(valid)
        {
            cout << "r = " << r << endl;
        }
        else 
        {
            cout << "Divide by zero..." << endl;
        }
          
        return 0;
    }

     4、缺陷

    (1)、divide函数有三个参数,难以理解其用法

    (2)、divide函数调用后必须判断valid代表的结果

    A、当valid为true时,运算结果正常

    B、valid为false时,运行结果出现异常

    二、优化方式

    1、通过setjmp()和longjmp()进行优化

    (1)、int  setjmp(jmp_buf env)

    A、将当前上下文保存在jmp_buf结构体中

    (2)void setjmp(jmp_buf env, int val)

    A、从jmp_buf结构体中恢复setjmp()保存上下文

    B、最终从setjmp()函数调用点返回,返回值为val

    #include <iostream>
    #include <csetjmp>  //for setjmp、longjmp();
    
    using namespace std;
    
    static jmp_buf env;  //须定义全局的上下文环境
    
    double divide(double a, double b)
    {
        const double delta = 0.000000000000001;
        double ret = 0;
        
        if(!((-delta < b) && (b < delta)))
        {
            ret = a / b;
        }
        else
        {
            longjmp(env, 1); //当错误发生时会跳转到setjmp那么的代码
                             //处,重新执行setjmp并把其的返回值设为1
        }
        return ret;
    }
    
    int main()
    {
         
        if(setjmp(env) == 0) //先保存上下文环境,刚调用时返回值为0
        {
            double r = divide(1, 0);    
            cout << "r = " << r << endl;
        }
        else 
        {
            cout << "Divide by zero..." << endl;
        }
          
        return 0;
    }

    2、缺陷:setjmp()和longjmp()的引入

    (1)、必须涉及到使用全局变量

    (2)、暴力跳转导致代码可读性降低

    (3)、本质还是if...else...的处理方式

    三、小结

    (1)、程序中不可避免的会发生异常

    (2)、异常是在开发阶段就可以预见的运行时问题

    (3)、C语言中通过经典的if-else

    (4)、C++中存在更好的异常处理方式

  • 相关阅读:
    瓦力完成图
    树莓派学习笔记(6):让Raspbian支持中文、禁用休眠
    树莓派学习笔记(5):成功实现NAS家庭服务器(流媒体播放、文件共享及下载机)
    检测QQ在线状态脚本(20141022测试成功)
    树莓派学习笔记(4):利用yeelink实现在线硬件状态监控
    vi-vim :删除、撤销、恢复删除、复制删除
    sqlachemy中批量删除的问题
    vim 删除一整块,vim 删除一整行
    vim显示行号、语法高亮、自动缩进、添加下划线的设置
    CentOs6.7 python2.6升级到2.7.11
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6379101.html
Copyright © 2011-2022 走看看