• 第六十三课、C语言的异常处理


    http://www.cnblogs.com/gui-lin/p/6379101.html

    一、异常处理

    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++中存在更好的异常处理方式

  • 相关阅读:
    让IT工作者过劳的13个坏习惯zz
    WPF Radio button的解决方案
    程序退出的各种方法,如何关闭多线程。
    文本框输入自动切换输入法问题
    在外部js文件中读取带母版页的子页当中控件的值
    Showwindow/FindWindow/PostMessage 转
    vb读取字节中的某一位
    C# 禁止windows程序重复运行的两种基本方法
    C# DllImport的用法(转)
    sqlserver存储过程中sql语句连接及datetime字段的处理
  • 原文地址:https://www.cnblogs.com/feng9exe/p/7246719.html
Copyright © 2020-2023  润新知