C语言异常处理之 setjmp()和longjmp()
2018-06-18 03:49:29来源:未知 阅读 ()
异常处理之除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\n",divide(5,0)); } else if(ret==1) //异常操作 { printf("ERR\n"); } return 0; }
运行打印:
ERR
缺陷在于:
- 若需要两个函数之间跳转,必然要使用全局变量jmp_buf env
- 跳转使得代码可读性降低
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:实验环境的搭建
- 关于各种不同开发语言之间数据加密方法(DES,RSA等)的互通的 2020-06-07
- C语言程序结构 2020-05-31
- 解析一下C++的异常处理 2020-05-15
- 每日干货丨C++语言主流开发工具推荐! 2020-04-28
- C语言实现经典游戏——扫雷! 2020-04-17
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash