异常处理之除0情况

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

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

其实这个函数还有瑕疵,当我们调用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\n",divide(5,0));
    }
    else if(ret==1) //异常操作
{
      printf("ERR\n");
}
return 0;
}

运行打印:

ERR

缺陷在于:

  • 若需要两个函数之间跳转,必然要使用全局变量jmp_buf env
  • 跳转使得代码可读性降低

C语言异常处理之 setjmp()和longjmp()的更多相关文章

  1. C语言中setjmp与longjmp学习笔记

    C语言中setjmp与longjmp学习笔记 一.基础介绍 头文件:#include<setjmp.h> 原型:  int setjmp(jmp_buf envbuf) ,然而longjm ...

  2. 【转】浅析C语言的非局部跳转:setjmp和longjmp

    转自 http://www.cnblogs.com/lienhua34/archive/2012/04/22/2464859.html C语言中有一个goto语句,其可以结合标号实现函数内部的任意跳转 ...

  3. C语言再学习之 setjmp与longjmp

    前不久在阅读Quake3源代码的时候,看到一个陌生的函数:setjmp,一番google和查询后,觉得有必要针对setjmp和longjmp这对函数写一篇blog,总结一下. setjmp和longj ...

  4. C 语言中 setjmp 和 longjmp

    在 C 语言中,我们不能使用 goto 语句来跳转到另一个函数中的某个 label 处:但提供了两个函数——setjmp 和 longjmp来完成这种类型的分支跳转.后面我们会看到这两个函数在处理异常 ...

  5. 非本地跳转之setjmp与longjmp

    非本地跳转(unlocal jump)是与本地跳转相对应的一个概念. 本地跳转主要指的是类似于goto语句的一系列应用,当设置了标志之后,可以跳到所在函数内部的标号上.然而,本地跳转不能将控制权转移到 ...

  6. 第63课 C语言异常处理

    1. 异常的概念 (1)程序在运行过程中可能产生异常 (2)异常(Exception)与Bug的区别 ①异常是程序运行时可预料的执行分支 ②Bug是程序是的错误,是不被预期的运行方式 2. 异常和Bu ...

  7. setjmp()、longjmp() Linux Exception Handling/Error Handling、no-local goto

    目录 . 应用场景 . Use Case Code Analysis . 和setjmp.longjmp有关的glibc and eglibc 2.5, 2.7, 2.13 - Buffer Over ...

  8. c语言异常处理机制

    异常处理机制:setjmp()函数与longjmp()函数 C标准库提供两个特殊的函数:setjmp() 及 longjmp(),这两个函数是结构化异常的基础,正是利用这两个函数的特性来实现异常. 所 ...

  9. setjmp和longjmp

    此文是学习 C专家编程 中的笔记. setjmp和longjmp是C语言所独有的,它们部分弥补了C语言有限的转移能力. 函数说明(来自wiki百科): int setjmp(jmp_buf env) ...

随机推荐

  1. 设置npm的registry

    .原npm地址 npm config set registry http://registry.npmjs.org .设置国内镜像 a.通过config命令 npm config set regist ...

  2. 2017年7月最新浏览器市场份额,IE8份额仅剩个位数

    数据来源为百度统计所覆盖的超过150万的站点,样本为2017年6月1日-2017年6月30日最新一个月的数据. 统计如下: 其中IE8的份额为9.83%,首次降至个位数.在所有IE版本中,份额最高的是 ...

  3. 背水一战 Windows 10 (118) - 后台任务: 后台下载任务(任务分组,并行或串行执行,组完成后通知)

    [源码下载] 背水一战 Windows 10 (118) - 后台任务: 后台下载任务(任务分组,并行或串行执行,组完成后通知) 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 ...

  4. [Swift]创建CoreData的两种方式

    一.CoreData介绍 CoreData主要分为两部分: 上层是模型层,模型层有NSManagedObjectContext上下文管理着, 底层则是由SQLite实现的持久化部分,通过NSPersi ...

  5. Oracle merge合并更新函数

    本博客介绍一下Oracle merge合并函数,业务场景:新增数据的时候要先查询数据库是否已经有改数据,有数据就更新数据,没数据才新增数据,这是很常见的业务场景,如果是用Oracle数据库的话,其实直 ...

  6. springmvc的Controller里实现转发的同时弹出提示对话框

    以前写servlet时就用到这个,但是现在学了springMVC+hibernate后就不知道怎么实现了,后来在网上找了好多,看了好多,最后经过自己实践成功的如下: 1.首先是Controller控制 ...

  7. Java多线程可以分组,还能这样玩!

    前面的文章,栈长和大家分享过多线程创建的3种方式<实现 Java 多线程的 3 种方式>. 但如果线程很多的情况下,你知道如何对它们进行分组吗? 和 Dubbo 的服务分组一样,Java ...

  8. 浅谈HTTP Keep-Alive

    背景是一次线上故障 项目类型vue ssr 与server的数据交互用的http内网域名方案 在5月发生了一次线上CPU100%的问题,直接导致了NodeServer 500. 最终解决办法是: 1. ...

  9. Docker Ubuntu中安装ping ifconfig命令

    Ubuntu 容器环境安装ping ifconfig 进入容器执行:ifconfig ping 没有该命令 apt-get update ###命令 ifconfig apt-get install ...

  10. Android--UI之ViewStub

    前言 按照最近博客的路线,继续讲Android的UI开发.今天讲解一下ViewStub控件,惰性装载控件.在本篇博客中,将了解到ViewStub的常用属性.方法,以及注意事项.最后将以一个简单的Dem ...