1、单击以编辑,母版标题样式,单击以编辑母版文本样式,第二级,第三级,第四级,第五级,*,第,10,章 异常处理和命名空间,10.1,异常处理,10.2,命名空间和头文件命名规则,本章主要内容,10.1,异常处理,10.1.1,异常处理概述,10.1.2,异常处理的方法,本节主要内容,10.1,异常处理,10.1.1,异常处理概述,编译时的错误,程序中常见的错误,运行时的错误。,编译时的错误:,主要是语法错误,如关键字拼写错误、语句末尾缺分号、括号不匹配等。这类错误相对比较容易修正。,运行时的错误,:,有些是,不可预料,的,如算法出错,;,有些可以预料但却,无法避免,如内存空间不够,无法实现指定的
2、操作等,;,无法打开文件、数组下标越界等。,这类错误比较隐蔽,不易被发现。,程序在运行过程中出现的错误统称为,异常,对异常的处理称为,异常处理,。,例,10.1,传统的异常处理方法举例。,#include,using namespace std;,int,Div(int,x,int,y);/,函数,Div,的原型,int,main(),cout,7/3=Div(7,3),endl,;,cout,5/0=Div(5,0),endl,;,return 0;,int,Div(int,x,int,y)/,定义函数,Div,if(y=0),cout,除数为,0,错误,!,endl,;,exit(0);,
3、return,x/y,;,程序运行结果如下,:,7/3=2,除数为,0,错误,!,3=2,传统的异常处理方法,可以满足小型的应用程序需要,但无法保证程序的可靠运行,而且,采用,判断或分支语句,处理异常的方法,不适合大量异常的处理,更不能处理不可预知的异常。,传统的异常处理方法基本上是采取判断或分支语句来实现,。,10.1.2,异常处理的方法,C+,处理异常的办法是,:,如果在执行一个函数过程中出现异常,不在本函数中立即处理,而是发出一个信息,传给它的上一级,(,即调用函数,),来解决,如果上一级函数也不能处理,就再传给其上一级,由其上一级处理。,如此,逐级上传,如果到最高一级还无法处理,则终止
4、程序的运行。,C+,处理异常的机制是,由检查、抛出和捕获三个部分组成,分别由,三种语句,来完成,:,try,(,检查,),throw,(,抛出,),catch,(,捕获,),1.,异常的抛出,抛出异常使用,throw,语句,其格式如下,:,“,表达式”是表示抛出的异常类型,异常类型由表达式的类型来表示。,例如,含有,throw,语句的函数,Div,可写成,:,int,Div(int,x,int,y),if(y=0),throw y;,return,x/y,;/,当除数,y,不为,0,时,返回,x/y,的值,由于变量,y,的类型是,int,所以当除数,y,为,0,时,语句,throw,将抛出,i
5、nt,型异常,。该异常将由与之匹配的,catch,语句来捕获。,throw,表达式,;,2.,异常的检查和捕获,异常的检查和捕获使用,try,语句和,catch,语句,格式如式,:,try,被检查的复合语句,catch(,异常类型声明,1),进行异常处理的复合语句,1,catch(,异常类型声明,2),进行异常处理的复合语句,2,.,catch(,异常类型声明,n),进行异常处理的复合语句,n,例如,用于,处理除数为零异常,的,try_catch,语句如下,:,try /,检查异常,cout,7/3Div(7,3),endl,;/,被检查的复合语句,cout,5/0Div(5,0),endl,
6、catch(,int,)/,捕获异常,异常类型是,int,型,cout,除数为,0,错误,!,endl,;/,进行,异常处理,的复合语句,例,10.2,处理除数为零异常的程序。,#include,using namespace std;,int,Div(int,x,int,y);/,函数,Div,的原型,int,main(),try,/,检查异常,cout,7/3=Div(7,3),endl,;/,被检查的复合语句,cout,5/0=Div(5,0),endl,;,catch(,int,),/,捕获异常,异常类型是,int,型,cout,除数为,0,错误,!,endl,;/,进行异常处理的
7、复合语句,cout,end,endl,;,return 0;,int,Div(int,x,int,y),if(y=0),throw y;,/,抛出异常,当除数,y,为,0,时,/,语句,throw,将抛出,int,型异常,return,x/y,;/,当除数,y,不为,0,时,返回,x/y,的值,程序运行结果如下,:,7/3=2,除数为,0,错误,!,end,说明,:,(1),被检测的语句或程序段必须放在,try,块中,否则不起作用。,(2)try,和,catch,块中必须有用花括号括起来的复合语句,即使花括号内只有一个语句也不能省略花括号。,(3),一个,try_catch,结构中只能有一个,
8、try,块,但却可以有多个,catch,块,以便与不同的异常信息匹配。,catch,后面的括号中,一般只写异常信息的类型名。,例,10.3,有多个,catch,块的异常处理程序。,#include,using namespace std;,int,main(),double a=2.5;,try /,检查异常,throw a;,/,抛出异常,catch(int,)/,捕获异常,异常类型是,int,型,cout,异常发生!整数型!,endl,;,/,进行异常处理的复合语句,catch(double)/,捕获异常,异常类型是,double,型,cout,异常发生!双精度型!,endl,;,/,进行
9、异常处理的复合语句,cout,end,endl,;,return 0;,程序运行结果如下,:,异常发生!双精度型!,end,(4),如果在,catch,子句中没有指定异常信息的类型,而用了删节号“,”,则表示它可以捕获任何类型的异常信息,。,例,10.4,有删节号“,”,的异常处理程序。,#include,using namespace std;,void,func(int,x),if(x),throw x;,/,抛出异常,throw,抛出整型异常,int,main(),try /,检查异常,func(5);,cout,No here!,endl,;/,被检查的复合语句,catch(),/,捕
10、获异常,异常类型是任意类型,cout,任意类型异常,!,endl,;/,进行异常处理的复合语句,cout,end,endl,;,return 0;,程序运行结果如下,:,任意类型异常,!,end,(5),在某种情况下,在,throw,语句中可以不包括表达式,如,:,throw;,此时它将把当前正在处理的异常信息再次抛出,给其上一层的,catch,块处理。,(6)C+,中,一旦抛出一个异常,而程序又不捕获的话,那么系统就会调用一个系统函数,terminate,由它调用,abort,终止程序。,10.2,命名空间和头文件命名规则,10.2.1,命名空间,10.2.2,头文件命名规则,本节主要内容,
11、10.2.1,命名空间,*为什么要引入命名空间,一个大型软件通常是由多人合作完成的,不同的人分别完成不同的模块。,不同的人分别定义了函数和类,放在不同的头文件中。,有可能在不同的头文件中用了相同名字来定义的函数或类。这样在程序中就会,出现命名冲突,就会引起程序出错。,另外,如果在程序中用到第三方的库,也容易产生同样的问题。,为了解决这一问题,ANSI C+,引入了命名空间,用来处理程序中常见的同名冲突问题,。,*什么是命名空间,所谓命名空间,实际上就是一个由程序设计者命名的内存区域。,程序设计者可以根据需要,指定一些有名字的命名空间,,将各命名空间中声明的标识符与该命名空间标识符建立关联,保征
12、不同命名空间的同名标识符不发生冲突,。,*,声明命名空间的方法,在命名空间,NS,中定义了两个简单变量,i,和,j:,namespace NS,int,i=5;,int,j=10;,C+,中命名空间的作用,类似于操作系统中的目录和文件的关系,不同子目录中的文件可以同名。调用文件时应指出文件路径。,namespace,是定义命名空间的所必须写的关键字,NS,是,用户自己指定的命名空间的名字,花括号内是命名空间的作用域,*,标准命名空间,std,除了用户可以声明自己的命名空间外,C+,还定义了一个标准命名空间,std,。,using namespace std;,其含义就是使用标准命名空间,std
13、标准命名空间,std,的使用方法,(1),在源文件中使用“,using namespace std;”,语句。,例如:,#include,using namespace std;,int,main(),cout,”Welcome to C+!”,endl,;,return 0;,(2),在该标识符前面加上命名空间及作用域运算符“,:”,。,例如:,#include,int,main(),std:cout,”Welcome to C+!”,std:endl,;,return 0;,说明:,由于,C+,的早期版本中没有命名空间的概念,库中的有关内容也没有放在,std,命名空间中,因而,在程
14、序中不必对,std,进行声明。,但是,用标准的,C+,编程是应该对命名空间,std,的成员进行声明或限定的。,例,10.5,命名空间的使用举例。,#include,namespace University /,声明命名空间,名为,University,int,grade=3;,namespace,Highschool,/,声明命名空间,名为,Highschool,int,grade=4;,int,main(),std:cout,The,unversitys,grade is:,University:grade,std:endl,;,std:cout,The,highschools,grade
15、is:“,Highschool:grade,std:endl,;,return 0;,程序运行结果如下,:,The universitys grade is:3,The,highschools,grade is:4,10.2.2,头文件命名规则,在,C+,程序中使用头文件时,既可以采用,C+,中不带后缀的头文件,也可以采用,C,语言中带后缀的头文件。,1.,带后缀的头文件的使用,在,C+,程序中,如果使用带后缀,.h,的头文件,(C,语言的传统方法,),不必用命名空间,std,。只需在文件中包含所用的头文件即可。例如:,#include,2.,不带后缀的头文件的使用,使用,C+,中不带后缀的头
16、文件时,需要在程序中声明命名空间,std,。例如:,#include,#include,using namespace std;/,声明使用命名空间,std,C+,所用的头文件名通常是在,C,语言的相应的头文件名(但不包括后缀,.h,),之前加一字母,c,。,如:,例如:,#include /,相当于,C,程序中的,#include,#include /,相当于,C,程序中的,#include,using namespace std;/,声明使用命名空间,std,C,语言中头文件名,C+,中相应的头文件名,string.h,cstring,stdio.h,cstdio,例,10.6-1,输入三
17、角形的三条边长,求三角形的面积。当输入边的长度小于或等于,0,,或者当三条边都大于,0,,但不能构成三角形时,分别抛出异常,结束程序运行。,#include,#include,using namespace std;,double,triangle(double,a,double,b,double,c),double s=(a+b+c)/2;/,三角形面积计算函数,if(a+b,=,c|b+c,=,a|c+a,=b),throw 1.0;/,语句,throw,抛出,double,型异常,return,sqrt(s,*(s-a)*(,s-b,)*(,s-c,);,int,main(),doubl
18、e,a,b,c,;,try /,检查异常,cout,请输入三角形的三个边长,(a,、,b,、,c):abc;,if(a=0|b=0|c0&b0&c0),cout,a=a,b=b,c=c,endl,;,cout,三角形的面积,=,triangle(a,b,c,),endl,;,cout,请输入三角形的三个边长,(a,、,b,、,c):abc;,if(a,=0|b=0|c=0)throw 1;/,语句,throw,抛出,int,型异常,catch(double,)/,捕获异常,异常类型是,double,型,cout,这三条边不能构成三角形,异常发生,结束,!,endl,;,catch(int,)/
19、捕获异常,异常类型是,int,型,cout,边长小于或等于,0,,异常发生,结束,!,endl,;,return 0;,int,main(),double,a,b,c,;,try /,检查异常,cout,请输入三角形的三个边长,(a,、,b,、,c):abc;,if(a=0|b=0|c0&b0&c0),cout,a=a,b=b,c=c,endl,;,cout,三角形的面积,=,triangle(a,b,c,),endl,;,cout,请输入三角形的三个边长,(a,、,b,、,c):abc;,if(a,=0|b=0|c=0)throw 1;,/,语句,throw,抛出,int,型异常,catch(double,)/,捕获异常,异常类型是,double,型,cout,这三条边不能构成三角形,异常发生,结束,!,endl,;,catch(int,)/,捕获异常,异常类型是,int,型,cout,边长小于或等于,0,,异常发生,结束,!,endl,;,return 0;,程序运行结果如下,:,请输入三角形的三个边长,(a,、,b,、,c):,3 4 5,a=3,b=4,c=5,三角形的面积,=6,请输入三角形的三个边长,(a,、,b,、,c):,2 2 4,a=2,b=2,c=4,这三条边不能构成三角形,异常发生,结束,!,






