资源描述
*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,本资料仅供参考,不能作为科学依据。谢谢。本资料仅供参考,不能作为科学依据。本资料仅供参考,不能作为科学依据。谢谢。本资料仅供参考,不能作为科学依据。,第七章,错误调试和异常处理,1/55,在程序设计中不可防止地出现各种各样错误,能够采取两类方法加以处理:,使用C#调试工具找出其中错误并加以更正,尽可能使程序正确;,在程序中加入异常处理语句,使程序含有容错功效,2/55,本章主要内容,错误分类,程序调试,异常处理,3/55,在C#程序设计中错误分成以下两类:,7.1 错误分类,语法错误,运行错误,4/55,在C#程序设计中错误分成以下两类:,7.1 错误分类,语法错误,运行错误,5/55,7.1 错误分类,语法错误,也称为编译错误,是因为不正确地编写代码而产生。,6/55,7.1 错误分类,7/55,7.1 错误分类,语法错误,也称为编译错误,是因为不正确地编写代码而产生。,8/55,在C#程序设计中错误分成以下两类:,7.1 错误分类,语法错误,运行错误,9/55,在C#项目运行期间,当一个语句试图执行一个不能执行操作时,就会发生运行错误。如数据溢出、数组下标越界等。,7.1 错误分类,10/55,7.1 错误分类,11/55,7.1 错误分类,12/55,7.1 错误分类,13/55,7.1 错误分类,另外还有一个运行错误,从语法上看,全部程序代码都是有效,但运行结果不正确,这一类错苏属算法设计错误,是最难纠正,必须使用C#调试工具进行错误排查。,14/55,7.2 程序调试,C#提供了强大程序调试功效,使用其调试环境能够有效地完成程序调试,从而有利于发觉运行错误。,调试工具,“调试”工具栏,“调试”菜单,15/55,7.2 程序调试,C#提供了强大程序调试功效,使用其调试环境能够有效地完成程序调试,从而有利于发觉运行错误。,选择“试图”,“工具栏”“调试”菜单命令,在工具栏中出现,“调试”工具栏,16/55,7.2 程序调试,“调试”菜单,17/55,7.2 程序调试,1.开始调试,“,开启调试,”命令:运行到断点。,“,逐语句,”/“,逐过程,”命令:开启并执行,在第一行中止。,“,运行到光标处,”命令:开启并运行到断点或光标位置。,18/55,7.2 程序调试,2.设置断点,方法一:用鼠标右键单击某代码行,从出现快捷菜单中选择“断点”“插入断点”命令(设置断点)或者“断点”“删除断点”(取消断点)。,方法二:将光标移至需要设置断点语句处,按F9键。,方法三:直接用鼠标单击下列图中灰色区域,即可在对应行设置断点。,19/55,7.2 程序调试,20/55,7.2 程序调试,3.定位错误,当某行代码出现错误时,该错误会自动添加到“错误列表”和“输出”窗口中,能够使用“错误列表”或“输出”窗口来查找代码中错误。,操作:双击“错误列表”或“输出”窗口中项,则光标自动跳到代码编辑中中对应犯错行。,C#语言中或在编码错误下显示一条波浪线,将鼠标悬停在带有波浪线标识代码上可显示一条消息,其中对错误进行了描述。,21/55,7.2 程序调试,4.调试过程,先在某行设置断点,然后在调试器中按F5键运行应用程序,应用程序会在该行停顿,此时能够检验任何给定变量值,或观察执行跳出循环时间和方式,按F10或F11逐行单步执行代码。,22/55,7.2 程序调试,在C#程序中止情况下,能够将鼠标放在希望观察,执行过,语句变量上面,调试器就会自动显示执行到断点时该变量值,也能够在某个对象上单击鼠标右键,从弹出快捷菜单中选择“快速监视“命令,即可观察到对象中各个元素值。,5.显示调试信息,23/55,7.2 程序调试,5.显示调试信息,24/55,7.3 异常处理,异常也是错误一个,它结果是造成程序不能正确运行。如系统瓦解、程序非正常退出、死循环等。,异常发生原因可能是代码本身问题,也可能是外部环境问题,如用户误操作、操作系统错误、内存资源不足、硬件故障、无法连接网络或数据库等。,异常发生时,假如没有给定异常处理程序,则程序将停顿运行,并显示一条错误信息。,通常对异常处理方法有两种:,25/55,7.3 异常处理,异常处理方式,使用代码检验(if-else),设置异常处理语句(try-catch),26/55,7.3 异常处理,异常处理方式之一,使用代码检验(if-else),static void Main(),Console.Write(请输入整数x:);,int x=int.Parse(Console.ReadLine();,Console.Write(请输入整数y:);,int y=int.Parse(Console.ReadLine();,int result=30/(x-2)/(y-x)/(5-y);,Console.WriteLine(30/(x-2)/(y-x)/(5-y)=0,result);,引例:计算表示式值:,30,(x-2)(y-x)(5-y),Chap7/P7_1,该程序可能出现未处理,输入字符串格式异常,和,除数为0,异常,27/55,7.3 异常处理,28/55,static void Main(),Console.Write(请输入整数x:);,int x=int.Parse(Console.ReadLine();,if(x=2),Console.WriteLine(x值不能为2);,else,Console.Write(请输入整数y:);,int y=int.Parse(Console.ReadLine();,if(y=x),Console.WriteLine(x和y值不能相等);,else,if(y=5),Console.WriteLine(y值不能为5);,else,int result=30/(x-2)/(y-x)/(5-y);,Console.WriteLine(30/(x-2)/(y-x)/(5-y)=0,result);,该程序中使用if语句检验除数为0异常。,Chap7/P7_2,29/55,程序中可能出现输入字符串格式异常2条语句:,int x=int.Parse(Console.ReadLine();,int y=int.Parse(Console.ReadLine();,可采取以下语句代替进行异常检验:,Chap7/P7_2,int x;,while(!int.TryParse(Console.ReadLine(),out x),Console.WriteLine(“输入字符串格式错误,请重新输入x值!”);,int y;,while(!int.TryParse(Console.ReadLine(),out y),Console.WriteLine(“输入字符串格式错误,请重新输入y值!”);,30/55,7.3 异常处理,异常处理方式之二,设置异常处理语句(,try-catch,),static void Main(),try,Console.Write(请输入整数x:);,int x=int.Parse(Console.ReadLine();,Console.Write(请输入整数y:);,int y=int.Parse(Console.ReadLine();,int result=30/(x-2)/(y-x)/(5-y);,Console.WriteLine(30/(x-2)/(y-x)/(5-y)=0,result);,catch,Console.WriteLine(程序发生异常,请检验您输入是否有误。);,Chap7/P7_3,将可能出现异常语句置于try语句块中,将出现异常后处理语句置于catch语句块中,31/55,7.3 异常处理,C#中提供了4个关键字,try、catch、finally和throw来管理异常处理。,try,:用于执行可能造成异常操作;,catch,:用于定义异常处理程序;,finally,:用于在引发异常时释放资源;,throw,:用于显式引发异常。,32/55,C#中异常处理结构,trycatch语句,:,用于捕捉可能出现异常,其使用语法格式以下:,try,/可能产生异常程序代码,catch,(异常类型1 异常对象1),/处理异常类型1异常控制代码,catch,(异常类型n 异常对象n),/处理异常类型n异常控制代码,33/55,C#中异常处理结构,trycatch语句,程序发生异常后,控制权转到catch语句(捕捉异常),catch语句只能捕捉与之配套try代码段中发生异常,catch语句能够捕捉指定异常,可有多个,注意次序,try,/程序代码,catch,/处理异常代码,/后续语句,try,/程序代码,catch,/处理异常代码,/后续语句,Chap7/P7_4,34/55,C#中异常处理结构,try-catch-finally语句,可用一个或多个catch语句,finally语句在全部catch语句后,且只能出现一次,不论是否发生异常,finally语句总是被执行(清理异常),finally语句含有很高优先级,finally代码段中不允许使用return语句,Chap7/P7_6,35/55,static void Main(string args),int result=0;int count=0;,Console.WriteLine(,请依次输入,5,个整数,:);,for(int i=0;i 5;i+),result+=int.Parse(Console.ReadLine();,count+;,Console.WriteLine(“,您输入次数共为,0,次,错误次数为,1,次,”,count,count-5);,Console.WriteLine(“,求和结果为,:,0,”,result);,Console.ReadLine();,Chap7/P7_6,计算从控制台输入5个整数和,输出求和结果、输入总次数以及错误次数,该语句可能出现输入字符串格式异常,36/55,static void Main(string args),int result=0;int count=0;,Console.WriteLine(,请依次输入,5,个整数,:);,for(int i=0;i 5;i+),Console.WriteLine(“,您输入次数共为,0,次,错误次数为,1,次,”,count,count-5);,Console.WriteLine(,求和结果为0,:,result);,Console.ReadLine();,Chap7/P7_6,计算从控制台输入5个整数和,输出求和结果、输入总次数以及错误次数,try,result+=int.Parse(Console.ReadLine();,将可能出现异常语句置于try语句块中,catch(FormatException),Console.WriteLine(,输入不正确,请重新输入,:);,i-;,continue;,将出现异常后处理语句置于catch语句块中,37/55,static void Main(string args),int result=0;int count=0;,Console.WriteLine(,请依次输入,5,个整数,:);,for(int i=0;i 5;i+),Console.WriteLine(“,您输入次数共为,0,次,错误次数为,1,次,”,count,count-5);,Console.WriteLine(,求和结果为0,:,result);,Console.ReadLine();,Chap7/P7_6,L2_4_1L2_4L2_4_2,计算从控制台输入5个整数和,输出求和结果、输入总次数以及错误次数,try,result+=int.Parse(Console.ReadLine();,将可能出现异常语句置于try语句块中,catch(FormatException),Console.WriteLine(,输入不正确,请重新输入,:);,i-;,continue;,将出现异常后处理语句置于catch语句块中,finally,count+;,将清理工作语句置于finally语句块中,38/55,C#中异常处理结构,try-finally语句,不对异常进行处理,利用finally收尾,假如try代码段中发生异常,该异常在执行完finally语句后被抛出。,39/55,throw语句:显式抛出异常,用于对发生异常进行描述,throw 后跟一个异常类型对象,throw 语句有两种使用方式:,(1)直接抛出异常;,(2)在出现异常时,经过含有catch块对其进行处理并使用throw语句重新把这个异常抛出并让调用方法程序进行捕捉和处理。,throw语句使用语法格式以下:,throw 表示式;,其中表示式类型必须是System.Exception或从System.Exception 派生类类型,Chap7/P7_7,40/55,Demo1、Chap7/P7_7,class Program,static void Main(string args),try,fun();,catch(Exception err),Console.WriteLine(Main:0,err.Message);,static void fun(),int x=5,y=0;,try,x=x/y;,catch(Exception err),Console.WriteLine(fun:0,err.Message);,throw;,不带表示式throw语句只能用在catch块中,它重新抛出当前正在由catch块处理异常,41/55,异常层次结构,try,catch(Exception),catch(SystemException),catch(ArgumentException),catch(ArgumentNullException),Exception,SystemException,ArgumentException,ArgumentNullException,42/55,异常传输,当异常在try代码段中被引发时,程序控制权将在异常处理结构中转移,直至找到一个能够处理该异常catch语句,这个过程称为“,异常传输,”。异常传输步骤:,(1)假如当前异常处理结构中包含,能够处理,该异常catch语句,则程序控制权就转移给第一个这么catch语句,异常传输结束。,(2)假如没有找到能够处理该异常catch语句,则程序经过当前异常处理结构(假如存在finally代码段则执行它),(3)假如程序抵达更外层一个异常处理结构,则转到第(1)步。,(4)假如异常在当前组员方法中没有得处处理,则当前方法执行代码被终止;若当前方法是程序所在进程或线程主方法,则整个程序结束运行;不然,程序控制权转移给调用当前方法代码,重复第(1)步。,举例1:Chap7/P7_8,43/55,举例1:Chap7/P7_8,static void Main(string args),try,OutterMethod(0);,OutterMethod(1);,OutterMethod(2);,catch(Exception),Console.WriteLine(,发生普通异常,);,public static void OutterMethod(int x),if(x=2),throw new Exception();,try,MiddleMethod(x);,catch(ArithmeticException),Console.WriteLine(,发生算术异常,);,public static void MiddleMethod(int x),if(x=1),throw new ArithmeticException();,try,InnerMethod(x);,catch(DivideByZeroException),Console.WriteLine(,发生除法异常,);,public static void InnerMethod(int x),if(x=0),throw new DivideByZeroException();,44/55,异常传输,举例2:下面代码段最终引发异常有哪些?,try,try throw new FormatException();,catch throw new ArgumentNullException();,catch,try throw new,OverflowException,();,finally throw new,NullReferenceException,();,finally,try throw new ArgumentOutOfRangeException();,catch throw new,ApplicationException,();,45/55,异常传输,举例3:下面循环一共会被执行几次?,i=0;,while(i10),try throw new OverflowException();,catch(ArgumentException)i+=2;,catch(ArithmeticException)i+=4;,catch(Exception)i+=6;,finally i-;,7.3 异常处理,46/55,惯用异常类,Exception,:全部异常类基类,Chap7/,lx2,惯用结构函数形式:,(1)public Exception(),如:throw new Exception();,(2)public Exception(string message),如:throw new Exception(“文件打开抛出异常”);,捕捉这个结构函数错误消息需要使用Exception类Message属性。,47/55,惯用异常类,Exception,:全部异常类基类,Exception类公有属性(见P333 表14.1)及方法使用,。,(P14_9.cs),7.3 异常处理,48/55,惯用异常类型,SystemException,和,ApplicationException,都是由Exception类直接派生,SystemException是System命名空间中全部其它异常类基类,ApplicationException类表示应用程序发生致命性错误时所引发异常,7.3 异常处理,49/55,与参数相关异常类,7.3 异常处理,SystemException,ArgumentException,FormatException,ArgumentNullException,ArgumentOutOfRangeException,P14_10,50/55,与组员访问相关异常类,MemberAccessException,7.3 异常处理,SystemException,MemberAccessException,FieldAccessException,MethodAccessException,MissingMemberAccessException,51/55,与数组相关异常类,IndexOutOfRangeException,ArrayTypeMismatchException,RankException,这三个类都是由,SystemException,直接派生类,7.3 异常处理,52/55,与算术运算相关异常类,ArithmeticException派生出:,DivideByZeroException,NotFinitNumberException,OverflowException,7.3 异常处理,由,SystemException,直接派生,53/55,与内存和磁盘操作相关异常类,OutOfMemoryException,NullReferenceException,IOException,7.3 异常处理,这三个类都是由,SystemException,直接派生类,其中IOException直接派生出:,DirectoryNotFoundException,FileNotFoundException,EndOfStreamException,FileLoadException,PathTooLongException,54/55,标准和技巧,使用“良性”异常,简化异常信息,限定异常范围,准确捕捉异常,限制在方法中引发异常,在高层次处理异常,统计异常,7.3 异常处理,55/55,
展开阅读全文