异常小结

转载 2007年10月09日 09:55:00
 
一.        为什么要使用异常:
因为在程序的执行过程中总会遇到许多可以预知或不可以预知的错误事件,例如:由于内存耗尽导致内存分配失败、文件操作失败、内存越界、数组越界、除零等。因此,程序员总需要在程序中不断加入if语句,来判断是否有异常出现,如果有,就必须要及时处理。这样一来,程序的可读性就差了很多,总有许多与真正工作无关的代码。
使用C++的异常处理机制有以下的优点:
1.  把错误处理和真正的工作分开;
2.  代码更容易组织,更清晰,复杂的工作任务更容易实现;
3.  安全,不至于一些小的疏忽而使程序以外崩溃了。
 
二.        常用的异常:
1.C++异常处理机制:try-catch
(1)       概念:关键字try表示定义一个受监控、受保护的程序代码块;关键字catch与try遥相呼应,定义当try block(受监控的程序块)出现异常时,错误处理的程序模块,并且每个catch block都带一个参数,这个参数的数据类型用于异常对象的数据类型进行匹配;而throw则是检测到一个异常错误发生后向外抛出一个异常事件,通知对应的catch程序块执行对应的错误处理。
(2)  示例:
#include "stdafx.h"
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
cout << "In main" << endl;
try
{
cout << "In try block, before throw a exception!" << endl;
throw 1;
cout << "In try block, after throw a exception!" << endl;
}
catch (int& value)
{
cout << "In catch block, the exception value is: " << value << endl;
}
 
cout << "Press any key to exit!" << endl;
getchar();
return 0;
}
结果显示:
In main
In try block, before throw a exception!
In catch block, the exception value is: 1
Press any key to exit!
 
#include "stdafx.h"
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
cout << "In main" << endl;
try
{
cout << "In try block, before throw a exception!" << endl;
int* p = NULL;
*p = 13;
cout << "In try block, after throw a exception!" << endl;
}
catch (...)
{
cout << "In catch block, find exception" << endl;
}
 
cout << "Press any key to exit!" << endl;
getchar();
return 0;
}
结果显示:
In main
In try block, before throw a exception!
In catch block, find exception
Press any key to exit!
 
 
2. C语言的SHEStructured Exception Handling结构化异常处理):与C++的异常处理机制相对应,C语言提供了__try、__except、__finally、__leave组成的结构化异常处理。
(1)       try—except:程序在执行受监控的代码(即__try{}中的代码)的过程中,如果没有出现异常,则转入__except(){}之后的代码模块中继续执行;否则,如果出现异常,那么控制流将进入__except后面的表达式中,先计算这个表达式的值,再根据这个值来作出相应的处理,这个值有3种情况:
(a)       EXCEPTION_CONTINUE_EXECUTION-1:异常被忽略,控制流将在异常出现的点后继续执行;
(b)       EXCEPTION_CONTINUE_SEARCH (0):异常不被识别,也即当前的__except模块不是这个异常错误所对应的正确的异常处理模块,系统将继续到上一层的try-except域中继续查找一个恰当的__except模块。
(c)       EXCEPTION_EXECUTE_HANDLER (1):异常已经被识别,控制流将进入到__except模块中。
 
示例1
#include "stdafx.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
puts("hello");
 
__try
{
puts("In try");
int* p = NULL;
*p = 45;
puts("after exception!");
}
__except (puts("In filter"), 1)
{
puts("In except");
}
 
puts("world");
getchar();
return 0;
}
结果如下:
hello
In try
In filter
In except
World
可见,并没有执行异常点之后的代码,而是进入了__except之后的异常处理。
 
示例2:
#include "stdafx.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
int j, zero;
 
puts("hello");
 
__try
{
puts("In try");
zero = 0;
j = 10;
j = 45 / zero;
printf("can go to here? j=%d /n", j);
}
__except(puts("In filter"), zero = 1, -1)
{
puts("In except");
}
 
puts("world");
 
puts("Press any key to continue...");
getchar();
return 0;
}
结果显示如下:
hello
In try
In filter
Can go to here? j = 45
World
可见,并没有处理_except后面的模块,而是继续执行异常点之后的代码。
 
(2)       try-finally:用于有效地保证资源的清除。
(a)       不管在任何情况下,在离开当前的作用域时,finally块区域内的代码都会被执行到;
(b)       try-finally语句的作用相当于面向对象中的析构函数;
(c)       使用__leave来代替try块中的goto和return:__leave的作用是离开当前的try块。
示例1:
#include "stdafx.h"
#include <stdio.h>
 
void test()
{
puts("hello");
__try
{
int* p;
puts("In try");
 
// 直接跳出当前的__try作用域
__leave;
puts("after __leave");
p = 0;
*p = 25;
}
__finally
{
// 这里会被执行吗?当然
puts("In Finally");
}
 
puts("world");
}
 
void main()
{
__try
{
test();
}
__except(1)
{
puts("In except");
}
 
puts("press any key to continue...");
getchar();
}
结果显示如下:
hello
In try
In finally
World
可见,使用__leave跳出当前的try块之后,后面的语句没有被执行,但是,还是执行了finally块!使用goto和return语句代替__leave,效果一样,还是会执行finally块。
示例2:
#include "stdafx.h"
 
#include <stdio.h>
#include <stdlib.h>
 
void main( void )
{
__try
{
char* p1;
char* p2;
 
__try
{
puts("do p1 malloc");
p1 = (char*)malloc(10);
puts("do p2 malloc");
p2 = NULL;
*p2 = 'a';
puts("After exception!");
}
__finally
{
if(p1)
{
free(p1);
puts("free p1");
}
if (p2)
{
free(p2);
puts("free p2");
}
}
}
__except(puts("In except finter"), 1)
{
puts("In exception!");
}
 
puts("press any key to continue...");
getchar();
}
结果显示如下:
do p1 malloc
do p2 malloc
In except filter
Free p1
In except
 
示例3:msdn的例子
#include <stdio.h>
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
   puts("in filter.");
   if (code == EXCEPTION_ACCESS_VIOLATION) {
      puts("caught AV as expected.");
      return EXCEPTION_EXECUTE_HANDLER;
   }
   else {
      puts("didn't catch AV, unexpected.");
      return EXCEPTION_CONTINUE_SEARCH;
   };
}
int main()
{
   int* p = 0x00000000;   // pointer to NULL
   puts("hello");
   __try{
      puts("in try");
      __try{
         puts("in try");
         *p = 13;    // causes an access violation exception;
      }__finally{
         puts("in finally. termination: ");
         puts(AbnormalTermination() ? "/tabnormal" : "/tnormal");
      }
   }__except(filter(GetExceptionCode(), GetExceptionInformation())){
      puts("in except");
   }
   puts("world");
}

数据结构课程总结

我想了好多,不知道从何写起,不是不知道写什么,而是想说的太多,不知道从何写起。。那就想到什么就说什么吧。   先说说我对慕课的看法吧,贺老师的翻转课堂不是我第一次接触慕课这个平台(不是智慧树),我第...
  • big_ice
  • big_ice
  • 2016年12月17日 21:38
  • 749

HTML5学习小结

HTML5是用于取代1999年所制定的 HTML4.01和XHTML1.0标准的HTML标准版本。 HTML5的第一份正式草案已于2008年1月公布;2012年12月,规范已经正式定稿。 W3C计...
  • gaojinshan
  • gaojinshan
  • 2014年03月27日 16:10
  • 1982

异常知识点小结

异常: 是什么?是对问题的描述。将问题进行对象的封装。 ------------ 异常体系: Throwable |--Error |--Exception |--RuntimeExce...
  • u010834071
  • u010834071
  • 2014年07月09日 22:20
  • 401

Java异常处理小结

[引用请注明出处:http://blog.csdn.net/bhq2010/article/details/9109809] 最近一个月都在做demo,对Java的异常处理有了一点感受,小结在这里,其...
  • bhq2010
  • bhq2010
  • 2013年06月17日 11:49
  • 2550

c++异常处理小结

c++语言本身或者标准程序库跑出的所有异常,都派生自基类exception.这是其他数个标准异常的基类,他们共同构成一个类体系。               这些标准异常类别分为三组: ...
  • hyp1977
  • hyp1977
  • 2016年07月19日 11:56
  • 260

java 异常小结

异常大体分为编译异常和运行异常两类,如果用软件开发(如Eclipse)编译异常在写代码时得到提醒, 而运行异常需要在运行时才能得到提示。 算术异常类:ArithmeticExecpti...
  • wen1158646729
  • wen1158646729
  • 2015年07月06日 15:10
  • 281

JAVA中异常处理小结

工作两年多啦!写程序中遇到的异常也不计其数,自己能解决的,不能解决的!终于有时间,也想对怎样处理JAVA中的异常做个小结:          JAVA中处理异常最常用方法的无非就是抛出异常并交给调用...
  • u011407281
  • u011407281
  • 2015年10月16日 15:36
  • 197

python 异常小结

1.Python异常类 异常 描述 NameError 尝试访问一个没有申明的变量 ZeroDivisionError 除数为0 SyntaxErr...
  • vicunana
  • vicunana
  • 2016年11月30日 11:03
  • 179

Java中异常小结

异常:就是不正常。程序在运行时出现的不正常情况。其实就是程序中出现的问题。这个问题按照面向对象思想进行描述,并封装成了对象。因为问题的产生有产生的原因、有问题的名称、有问题的描述等多个属性信息存在。当...
  • qq_29854077
  • qq_29854077
  • 2015年07月26日 23:12
  • 144

“异常处理”学习小结

在我经历过的项目中,很少使用异常处理;对于问题的调试与追踪,基本上都是基于错误码和日志信息。         这里的学习总结来自于>和网络,有很多问题的理解还需要实践经验。 在C语言中处理异常...
  • Since20140504
  • Since20140504
  • 2015年09月23日 10:01
  • 996
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:异常小结
举报原因:
原因补充:

(最多只允许输入30个字)