热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

第25节异常处理–上

-------------------------------------资源来源于网络,仅供自学使用,如有侵权,联系我必删.第一:异常处理初探所有的代码都有可能不按照预定义的

-------------------------------------资源来源于网络,仅供自学使用,如有侵权,联系我必删.

第一:

异常处理初探

 所有的代码都有可能 不按照 预定义的方式运行

 

? 这一组函数单纯的实现了四则运算
    ?  但是除法函数却总是会有意外 。。。

很明显 , 当除数为0 的时候 , Div 函数的调用将产生无法预见的错误

 

C 方式的解决方案

#include
#include using namespace std;double Div(double a, double b, bool* valid)//除法
{*valid = true;//向不知道是否为空valid指针空间里写入值if( (-0.000000001 }double Add(double a, double b)//加法
{return a + b;
}double Minus(double a, double b)//减法
{return a - b;
}double Multi(double a, double b)//乘法
{return a * b;
}int main(int argc, char *argv[])
{bool v &#61; false;cout<}

缺陷:
1) 每次调用 Div 函数后都必须判断结果是否合法
2) 参数 valid 如果没有指向合法的内存空间会产生错误

 

第二:

程序中会出现大量的处理异常的代码

 

 C 方式的典型调用代码

#include
#include using namespace std;int MemSet(void* dest, unsigned int length, unsigned char v)
{//指针合法性判断if( dest &#61;&#61; NULL )//指针不为空{return -1;}//项目需要,大小不小于4if( length <4 ){return -2;}//工程需求范围在0-9if( (v <0) || (v > 9) ){return -3;}//正常代码unsigned char* p &#61; (unsigned char*)dest;for(int i&#61;0; i}int main(int argc, char *argv[])
{int ai[5];double ad[4];char ac[3];int ret;//正常逻辑代码和异常处理代码混合在一起 &#xff0c; 导致代码迅速膨胀 &#xff0c; 难以维护ret &#61; MemSet(ai, sizeof(ai), 0);if( ret &#61;&#61; 0 ){}else if( ret &#61;&#61; -1 ){}else if( ret &#61;&#61; -2 ){}else if( ret &#61;&#61; -3 ){}//正常逻辑代码和异常处理代码混合在一起 &#xff0c; 导致代码迅速膨胀 &#xff0c; 难以维护ret &#61; MemSet(ad, sizeof(ad), 1);if( ret &#61;&#61; 0 ){}else if( ret &#61;&#61; -1 ){}else if( ret &#61;&#61; -2 ){}else if( ret &#61;&#61; -3 ){}//正常逻辑代码和异常处理代码混合在一起 &#xff0c; 导致代码迅速膨胀 &#xff0c; 难以维护ret &#61; MemSet(ac, sizeof(ac), 2);if( ret &#61;&#61; 0 ){}else if( ret &#61;&#61; -1 ){}else if( ret &#61;&#61; -2 ){}else if( ret &#61;&#61; -3 ){}cout <<"Press the enter key to continue ...";cin.get();return EXIT_SUCCESS;
}

缺陷:
正常逻辑代码和异常处理代码混合在一起 &#xff0c; 导致代码迅速膨胀 &#xff0c; 难以维护 。。。

 

第三

其它C 方式的异常处理方案
? go to 语句
? setjmp() longjmp()

#include
#include using namespace std;int MemSet(void* dest, unsigned int length, unsigned char v)
{if( dest &#61;&#61; NULL ){return -1;}if( length <4 ){return -2;}if( (v <0) || (v > 9) ){return -3;}unsigned char* p &#61; (unsigned char*)dest;for(int i&#61;0; i}int main(int argc, char *argv[])
{int ai[5];double ad[4];char ac[3];int ret &#61; 0;ret &#61; MemSet(ai, sizeof(ai), 0);if( ret !&#61; 0 ){goto ERROR;}ERROR:cout <<"Press the enter key to continue ...";cin.get();return EXIT_SUCCESS;
}

? 在C语言中可以使用上面两种解决方案将异常处理代码放到统一的地方 &#xff0c; 与正常逻辑代码分开
? 但在 C&#43;&#43; 中 &#xff0c; 这两种方法可能导致对象的构造函数或者析构函数得不到调用而引发错误

 

第四:

C&#43;&#43; 中的异常处理

?  C&#43;&#43; 中提供了 trycatch 语句块对可能产生异常的代码进行分开处理
    ?  try 语句块处理正常逻辑
    ?  catch 语句块处理异常
?  C&#43;&#43; 语言中通过 throw 语句引发一个异常

#include
#include using namespace std;#define DIV_ZERO_ERROR -1double Div(double a, double b)
{if( (-0.000000001 }int main(int argc, char *argv[])
{try//正常逻辑代码{cout<}

 

第五:

?  throw 语句用于将异常 “ 对象 ” 抛出
    ?  throw 语句将异常抛出 &#xff0c; 如果在当前函数中没有 try … catch语句能够处理该异常 &#xff0c; 则当前函数将立即返回
        ?  异常被传递到上层调用函数 &#xff0c; 仍然需要 try … catch 语句进行处理 &#xff0c; 如果上层函数也没有能力处理该异常 &#xff0c; 则异常继续向更上层函数的函数传递 。。。
?  如果在函数调用栈中的所有函数都无法处理抛出的异常 &#xff0c; 则程序异常中止

使用try…catch

#include
#include using namespace std;void MemSet(void* dest, unsigned int length, unsigned char v)
{if( dest &#61;&#61; NULL ){throw -1;}if( length <4 ){throw -2;}if( (v <0) || (v > 9) ){throw -3;}unsigned char* p &#61; (unsigned char*)dest;for(int i&#61;0; i}int main(int argc, char *argv[])
{int ai[5];double ad[4];char ac[3];try//正常代码:3个数组内存设置{MemSet(ai, sizeof(ai), 0);MemSet(ad, sizeof(ad), 1);MemSet(ac, sizeof(ac), 2);}catch(int e){cout<}

 

第六:

?  同一个 try 语句块可以跟上多个 catch 语句块
    ?  同一个 try 语句块可以抛出多种不同类型的异常
    ?  不同类型的异常由不同的 catch 语句块负责处理
?  异常被抛出后会自上而下逐一匹配 catch 语句块
    ?  异常匹配时 &#xff0c; 不会进行默认类型转换

try … catch 匹配示例

#include
#include using namespace std;int test(int i)
{if( i &#61;&#61; 1 ){throw -1; //int类型 异常}if( i &#61;&#61; 2 ){throw "ERROR"; //char*字符 异常}if( i &#61;&#61; 3 ){throw 0.5; //double类型 异常}if( i &#61;&#61; 4 ){throw &#39;d&#39;; //char字符型 异常}return i;
}int main(int argc, char *argv[])
{for(int i&#61;0; i<5; i&#43;&#43;){//一个try 对应 多个catch函数try{cout<}

 

小结

?   异常处理是程序中随处可见的情况

?  在工程实践中 &#xff0c; 大多数的代码都是用于处理异常的
?  异常处理的质量直接决定最终产品的质量
?  C&#43;&#43; 提供了 try … catch 语句用于将正常逻辑代码与异常处理代码进行分开处理


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • C语言判断正整数能否被整除的程序
    本文介绍了使用C语言编写的判断正整数能否被整除的程序,包括输入一个三位正整数,判断是否能被3整除且至少包含数字3的方法。同时还介绍了使用qsort函数进行快速排序的算法。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • 本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文介绍了最长上升子序列问题的一个变种解法,通过记录拐点的位置,将问题拆分为左右两个LIS问题。详细讲解了算法的实现过程,并给出了相应的代码。 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
author-avatar
手机用户2602881417
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有