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
    • 跳转使得代码可读性降低
  • 相关阅读:
    第四章 源代码的下载和编译 心得笔记
    第三章 Git使用入门 心得笔记
    第二章 搭建Android开发环境 心得笔记
    第一章 Android系统移植与驱动开发概述 心得笔记
    第十章
    第九章
    第八章
    第七章
    第六章
    第五章的体会
  • 原文地址:https://www.cnblogs.com/lifexy/p/8820562.html
Copyright © 2011-2022 走看看