← 学习库 C++程序设计教程 本册目录

第19章 异常处理

原书第 271 页

第19章 突发事件的救急——异常处理

每一件事情都不可能是十全十美的,再是C++的高手也好,设计开发出的C++程序在运行中也可能会出现一些预料不到的错误情况,如死机(即程序停在某处,不往下执行了),程序死循环(即程序不停地在某段执行),程序运行时跑飞了(即不按预定程序运行),人为操作时出错了,计算机本身出现了某些故障,等等,这些异常情况都是有可能出现的,那该怎么办呢?C++对于这些异常情况的处理办法是:要么把这些异常情况抛弃掉,然后继续执行,要么转到它处执行,要么停机处理异常情况。别小看了这个异常处理,它在程序的可行性、可靠性、稳定性、实用性等性能上起到了至关重要的作用,甚至是决定性的作用。C++在这些方面有什么高超技艺呢?请往下浏览吧。

19.1 错误输入了所规定字符的异常情况处理的例题详解

【例 19-1】要求在程序运行时输入十进制数字的字符,并打印出来。如果误输入了非十进制数字的字符,请对这种情况进行异常处理,试编写程序实现。

1. 用心分析人想通,机随人行写提纲

同样是按照 “人定胜机,机随人行” 的法则编程。

人的做法是:输入一个字符,看这个字符是不是十进制数字,若是,则写下来;若不是,则提示输入了非十进制数字。

2. 对号入座写文章,头脑运行改文章

根据上述提纲,结合 C++ 的异常处理语句,对号入座写文章——编写 C++ 源程序代码。

首先,在程序中应该有测试异常的语句块,当测试到输入的字符是非十进制数字这种异常情况时,就要把这个异常抛掷掉——把它抛给捕获、处理异常的语句块进行处理。

本例中先定义一个测试异常的 try 语句块,然后定义另一个处理异常的 catch 语句块,这个 catch 语句块对 try 语句块测试到的且由 “throw ab;” 语句抛掷过来的异常情况进行处理。

程序代码如下:

//ex19-1.cpp
#include<ctype.h>
#include<iostream>
using namespace std;

void dig()
{
    char ab;
    try //定义测试异常的 try 语句块
    {
        cout<<"请输入一位十进制数字"<<endl;
        cin>>ab;
原书第 272 页
if (isdigit (ab)==0) //如果输入的字符是非十进制数字
    throw ab; //抛掷异常变量 ab

cout<<ab<<endl;
}

catch(char)//定义处理异常的 catch 语句块,处理异常变量 ab 带来的异常

{
cout<<"输入了非十进制数字,应该在西文方式输入十进制数字"<endl;//进行异常处理
}
}
void main()
{
dig();
}

在异常处理中,因为要判断是否为 0~9 的阿拉伯数字,所以要先接收从键盘输入的信息,本例中用字符变量 ab 来接收。

本例中使用了 isdigit 这个测试字符是否为十进制数的函数,若测试到字符为非十进制数,该函数返回 0。

将写出的程序与上述提纲分析比照,并用人脑跟踪运行,直至认为正确(即可以完成题目的功能,也符合C++的语法及规定),就可以转入下一步了。

3. C++帮助且裁判,人定胜机凯歌扬

将上面的程序输入计算机→编译→连接→如果无错→运行[→调试修改→如果无错→运行]。

上机实验记录如表19-1所示。

表 19-1 上机实验记录表
出错现象出错原因解决办法
: identifier 'isdigit'因为没有包括 ctype.h加 “#include<ctype>”
Cannot open include file: 'ctype': No such file or directory不能打开包括文件 ctype将 “#include<ctype>” 改为\n“#include<ctype.h>”
missing ‘.' before type 'char'在类型 char 之前丢失了分号将整个异常处理程序段改为:\nchar ab;\ntry\n{ if(isdigit(i)==0) throw ab;\n cout<<ab<<endl;\n} catch(char ab)
"i": undeclared identifier没有声明 i加上 “cin>>ab;”,将整个异常处理程序段改为:\nchar ab;\ntry\n{ cin>>ab;\n if(isdigit(ab)==0) throw ab;\n cout<<ab<<endl;\n} catch(char ab) 此错纠正
原书第 273 页

(续)

出错现象出错原因解决办法
试图在“cout<"输入了非十进制数字,应该在西文方式输入十进制数字"<<endl;" 语句后加“cin>>i;" 是不行的因为,如果再发生输入错误的情况,则不能进行异常处理,且不能运行正常情况下应该运行的语句“cout<<ab<<endl;"将 catch 语句块改为:\n{ catch(char ab)\ {\ncout<<"输入了非十进制数字,应该在西文方式输入十进制数字"<<endl;}
warning C4101: 'ab': unreferenced local variable warning C4700: local variable 'ab' used without having been initialized因为没有参考和利用到 ab 的值去掉 catch(char ab)中的 ab,至此,全部错误被纠正

运行结果:

请输入一位十进制数字

d

输入了非十进制数字,应该在西文方式输入十进制数字

请输入一位十进制数字

6

6

结果正确。

19.2 勤奋实践,总结评分

19.2.1 习题

1.对输入身份证号码的出错次数大于3次这种异常情况进行处理,并设计出处理后的结果,试编写程序完成这个工作。

  1. 有一个程序声明数组为 “int array1[10];”,当引用数组元素 array1[10]时,会发生什么情况?这种情况如何处理?请写出处理这种情况的程序。
  1. 在银行的自动取款机取款时,取款金额大于存款余额是异常情况之一,为了避免银行受损失,请用异常处理设计一个程序解决这个问题。

4.程序中要求输入大写字母时,有时输入了小写字母,如何让计算机自动地进行异常处理?请编写程序实现。

分别输入大、小写字母,观察异常处理的结果,直至程序能正确地处理这些异常情况。

  1. 在程序运行时要求输入名称,但一般小心按下了〈Enter〉键,该异常情况如何处理?请编程实现。
  1. 在程序中,当应该输入数字时,却输入了其他字符,怎么办?请编程解决。
  1. 当在程序运行中需要输入时,按错了键,又按〈Enter〉键确认了,使得输入的信息不正确,如果这种情况下想当场挽救,该如何处理?请编写程序解决这个问题。
原书第 274 页
  1. 在程序第一次运行时想读文件,往往文件打不开,这时如何处理该异常,以使得程序能正常运行?试编程实现。

9\. 当用堆申请动态空间时,申请不到,请编写程序处理这种异常情况。

  1. 如果在网上购物,当扣款金额扣多了或扣少了时,该如何处理,以使得顾客和商场避免不必要的损失。请编程解决这个问题。
19.2.2 思考题
  1. 当除数为0产生溢出时,如何用异常处理来解决?
  1. 当数据计算的结果超出了预料的大致范围时,该如何处理?请编写程序实现。
19.2.3 总结评分,继续提高

浏览、体验了例题、习题和思考题之后,说说自己的体会和收获,并认真总结,请按表19-2给自己评判一下能得多少分。

表19-2 总结评分表
成绩ABCD不足的原因改进的方法备注
C++知识完全理解和会用基本理解和会用肤浅理解和会用基本不理解和不会用
程序原创(独立编程)的比例(%)≥9080~8960~79< 60

不论得分多少,大家都要总结经验,扬长避短,勤奋努力,不断提高。

最后浏览一下本章的第4节,可以先考考自己,然后再浏览,以便使重点知识掌握得更牢固。

19.3 异常处理知识

C++对于突发事件的应急处理分为三部曲:检查—抛掷—捕捉。如何奏响异常处理的三部曲呢?下面一一道来。

19.3.1 在什么情况下用到异常处理

在什么情况下都应该用到异常处理,因为在何时何地运行程序都可能会有突发事件(异常情况)发生。这么做是不是过于谨小慎微了?不是的,确实应该这样做。正所谓不打无准备之仗,更何况计算机的运行速度如此之快,计算机的软、硬件控制在生产、工作、生活中如此重要,所以更加不能疏忽。

当然,平时编写的习题等较小的程序可以不考虑它,但是对实时控制系统、实际应用软件等,不但不可或缺,还必须严肃对待。

原书第 275 页
19.3.2 关于异常处理

1. 什么叫异常处理

异常处理就是处理事先估计到的程序运行时可能会出现的阻碍程序正确运行的错误。

异常处理是通过执行一段程序(或函数),来对异常情况进行处理的。所谓处理,并不是像在编译、连接、调试程序时把语法错误全部改正,而是抛弃掉这个异常(运行时的错误),然后继续执行或转到它处执行,让这些异常情况不再干扰整个程序的运行。就像人一样,带病也可以坚持工作,例如,脚痛,但可以带着这个病用手做工作。

但有时异常太严重了,无法带病坚持工作,异常处理就会把这些异常抛给系统,系统会采取终止程序运行等办法来进行处理。

2. 异常处理的程序编写

因为异常处理是对程序运行中的错误进行处理,自然也要以程序的方式实现,即在运行程序的过程中,通过运行异常处理的程序段(或函数),去进行异常处理。

那异常处理的程序是何面貌呢?

异常处理的程序结构是一个三部曲:检查异常—抛掷异常—捕捉、处理异常。当异常处理程序检查到异常情况时,就马上把它抛掷出去,另外处理。抛掷给谁?抛掷给捕捉程序段,由捕捉程序段来处理这些异常情况。这样就把不良因素消灭在了萌芽状态,防范了突发事件的发生。

异常处理程序的语法格式如下:

try//检查异常

{
    要检查异常情况的程序段
    if(是异常情况)
        throw 发生异常的任一个变量名;//把发生异常的变量名抛掷掉
    [else](不是异常情况)//else 视情况加或不加
    {正常情况下的程序段②}
}

catch(throw 抛掷来的变量名的数据类型 [接收异常变量值的变量名③])

//捕捉、处理 throw 抛掷来的异常;③是当需要该值时才加上
{
    进行异常处理的程序段
}

后续语句段

在上述格式中需注意以下几点。

1)try 和 catch 语句块的花括号必不可少。

2)throw(抛掷)语句必在try语句块中,即一旦发现异常目标就要马上抛掷出去。

3)必须要有 catch 语句块,而且 catch 语句块必然是紧跟在 try 语句块之后,这样才能快速捕捉到异常目标并进行异常处理。

4)在某个异常处理的 try--catch 语句块中,只能有一个 try(即 try 语句块不能嵌套),但

原书第 276 页

catch 语句块可以有多个,即检查某种异常情况时,只能由一个检验人员(try)进行检查,然后抛掷(throw)给一个或多个处理部门(catch)去处理。但多个 try—catch 语句块可以并列,即可以由多个检查人员去分头检查多种异常情况,然后分别抛掷给多个处理部门去处理。

5)try、throw 和 catch 三者缺一不可,它们是一个团队,是一个完整的异常处理的结构,必须携手并肩,才能取胜。

6)当低一层的处理部门处理不了某个异常情况时,就会把这个异常情况再抛掷给高一层的部门去处理,这种情况的语法格式如下(注意要遵循上述原则)。

Image

这种形式可以有多层。

7)关于“后续语句段”的写法请见下方3中的第(2)点。

3. 异常处理的运行实现

(1)异常处理程序的运行、实现过程。

从 try 进入异常处理程序,先检查有无异常情况,然后再进行下一步的动作,具体分以下两种情况。

1)如果发现敌情(即有异常情况),就按如下步骤进行。

① 将出现敌情(异常)的变量名抛掷(throw)给捕捉、处理敌情(异常)的部门(catch)进行处理。

② catch 捕捉到这个敌情(异常)后,就进行异常处理。

③ 异常处理完后就不再执行正常情况下的程序段②了,而是从 catch 语句块之后的“后续语句段”往下执行。

2)如果没有敌情(即没有异常情况),就按如下步骤进行。

① 执行正常情况下的程序段②。

② 执行完后就从 try 语句块里出来了,但不执行 catch 语句块(因为没有敌情),而是直接从 catch 语句块之后的“后续语句段”往下执行。

(2) 关于后续语句段

后续语句段要与 catch 的异常处理段和正常程序段②等一起进行通盘设计,其主要有如下 3 种情况。

1)如果想将病治好,就返回原来有病的程序段再次运行,如果运行后病依然存在,则再次返回有病的程序段运行,如此循环往复,直到将病治好为止,治好后程序就继续按原有的正常情况执行了。例如,需要输入正整数时,如果反复输入字幕或负数,则一直会进行异常处理,直到输入了正整数时才会按原有的正常情况继续往下执行,如例19-3和例19-4。

原书第 277 页

2)带病转去其他语句段运行,即运行与原来病情无关的程序段,也就是忍着脚痛,做与脚痛无关的工作。例如,转去有病程序段的备用程序段,执行其他程序。读者也可将例19-3和例19-4改写为这种方式的程序。

3)无法带病运行,这是因为病情太严重,无法治好或不能忍受,就只能终止程序的运行了。例如,用 exit(1)、exit(0)、abort 等终止程序的运行。

【例 19-2】有一个表达式 $ y = \sqrt{x} $ ( $ x \geq 0 $),x 是在程序执行时从键盘输入的,有可能会输入负数给 x,这是一种人为引起的异常错误,应进行处理。请编写该异常处理程序。

(1)用心分析人想通,机随人行写提纲

同样是按照 “人定胜机,机随人行” 的法则编程。

人的做法是:输入一个数,看这个数是不是大于等于 0 的十进制数,若是,则输入正确;若不是,则提示输入的不是大于等于 0 的十进制数。

(2)对号入座写文章,头脑运行改文章

根据上述的提纲,结合 C++ 的异常处理语句,对号入座写文章——编写 C++ 源程序代码。编写的异常处理程序如下:

//ex19-2.cpp
#include<math.h>
#include<iostream>
using namespace std;

void dig()
{
    double x;
    double y;
    try //定义测试异常的 try 语句块
    {
        cout<<"请输入大于等于 0 的十进制数"<endl;
        cin>>x;
        if (x<0) //如果输入的不是大于等于 0 的十进制数 throw x;//抛掷异常
        y=sqrt(x);
        cout<<"y="<<y<<endl;
    }
    catch(double)//定义处理异常的 catch 语句块
    {
        cout<<"输入的不是大于等于 0 的十进制数"<endl;
    }
}

void main()
{
    dig();
}
原书第 278 页

按照异常处理的原理,将写出的程序与上述提纲分析比照,并用人脑跟踪运行,直至认为正确(即可以完成题目的功能,也符合 C++ 的语法及规定),就可以转入下一步了。

(3)C++帮助且裁判,人定胜机凯歌扬

将上面的程序输入计算机→编译→连接→如果无错→运行[→调试修改→如果无错→运行]。

第一次运行结果:

请输入大于等于0的十进制数

-1

输入的不是大于等于0的十进制数

第二次运行结果:

请输入大于等于0的十进制数

4

y=2

果均正确。

结果均正确。

19.3.3 如何运用异常处理

对于异常情况,要千方百计地撒下天罗地网,把它们消灭在萌芽状态。就像宇宙飞船一样,它们能成功运行的一个重要原因就是将一切异常情况都未雨绸缪地考虑到了,并设计出了防范这些异常情况的各种硬件装置和软件程序。

同样,在设计开发 C++ 程序软件时,也应该认真负责、科学谨慎、实事求是、大胆创新、“先知先觉”地把一切隐患找出来,并采取对策进行异常处理。

怎样才能做到呢?具体分以下5步。

1)首先,软件开发人员要在开发阶段尽可能多地找出异常情况,并且对应地设置异常处理环节。

2)请专家来鉴定、提意见、找异常,以改进提高软件质量。

3)软件开发人员要在实际使用环境中多次运行软件,查找出尽可能多的异常并对其进行处理。

4)让实际操作软件的人员在实际使用环境中多次运行软件,查找出尽可能多的异常并反馈给设计开发者。

5)综合以上多种异常情况,周密分析、研究,制定异常处理的规划、任务,最后在软件调试中调整并定案。

【例 19-3】对求 n 个学生平均分的程序的异常情况进行处理。设这 n 个学生的成绩从键盘输入,并存放在数组中,学生人数也从键盘输入。

可以对以下异常情况进行处理:

1)输入的学生人数不是正整数,有可能输入了非数字、0、负数、小数、汉字、字母等。

2)输入的学生成绩不是大于等于0的十进制数。

原书第 279 页

解题如下:

(1)用心分析人想通,机随人行写提纲

同样是按照 “人定胜机,机随人行” 的法则编程。

1)对于题目中的第一种异常,人的做法是:输入一个数,看这个数是不是正数,再看其是否是整数,若是,则正确;若不是,则提示输入正整数。重复上述过程直至输入正确为止。

或者用另外一种做法:输入一个数,先判别第一位字符是否为数字 1~9,若不是,则抛掷异常,即提示重新输入十进制正整数;若是,则继续判断该数第二位之后的字符,若全是数字 0~9,则该数是正整数,否则,抛掷异常,即提示重新输入十进制正整数。重复上述过程直至输入正确为止。

第二种做法更简单些。

2)对于题目中的第二种异常,因为成绩采用的是大于等于 0 的十进制数,而大于等于 0 的十进制数是由 10 个阿拉伯数字(0~9)和小数点(可能有也可能没有)组成的,所以,人的做法是:输入一个数,判别该数是否由 10 个阿拉伯数字和小数点组成,若是,则正确;若不提,则提示输入大于等于 0 的十进制数。重复上述过程直至输入正确为止。

3)求平均分,人的做法是:把每个学生的分数相加得总分,平均分=总分/学生人数,然后输出平均分。

(2)对号入座写文章,头脑运行改文章

根据上述提纲,结合 C++ 的异常处理语句,对号入座写文章——编写 C++ 源程序代码。程序代码如下:

//ex19-3-6.cpp
#include<stdlib.h>
#include<iostream.h>
#include<string.h>

const int N=10;

void delay1(int dtime)//延时
{
    for(int i=0;i<dtime;i++)
        for(int j=0;j<100000;j++)
}

double scoave(double *strp2,int n1)//计算平均分
{
    double ave1=0;
    for(int i=0;i<n1;i++)
        ave1+=strp2[i];
    ave1/=n1;
    return ave1;
}

void main()
{
    int n;
    double ave;
}
原书第 280 页

char *strp;

strp=c;

size_t len1;

in1:try///定义测试输入人数的异常情况的 try 语句块

{
    cout<<"请输入学生人数"<<endl;
    cin>>c;
    strp=c;//指针回移到字符数组的首部
    delay1(1000);
    len1=strlen(strp);
    for(int i=0;i<2;i++)
    {
        if(*strp>=49&&*strp<=57)
            for(int j=0;j<len1;j++)
                if(*strp>=48&&*strp<=57)
                strp++;
            else
                throw strp; //如果所输入的数第二位之后的字符不是数字 0~9,
                //就抛掷异常
            else
            throw strp;//如果所输入数的第一位字符不是数字 1~9,就抛掷异常
            strp=c;
        }
        strp=c;//指针回移到字符数组的首部
        n=atoi(strp);//将字符串转换成整数赋给 n
        cout<<"人数="<<n<<endl;
    }
    catch(char *)//定义处理输入人数的异常情况的 catch 语句块
    {
        cout<<"输入了非十进制正整数,应该在西文方式输入十进制正整数,"
        <<"请重新输入"<<endl;//进行异常处理
    }
}

double scof[N];
double *strp2;
strp2=scof;
char c2[10];
char *p;
p=c2;

size_t len2;

cout<<"请按人数输入每个学生的成绩"<<endl;
for(int i=0;i<n;i++)
{
    in2:try//定义测试输入成绩的异常情况的 try 语句块
    {
        cin>>c2;
        delay1(1000);
    }
}
原书第 281 页
len2=strlen(p);
for(int j=0;j<len2;j++)
    if(*p>=48&&*p<=57||*p==46)
        p++;
    else
        throw p;//如果输入的字符不是数字0~9或小数点,就抛掷异常

p=c2;//指针回移到c2这个字符串的首部

strp2[i]=atof(p);//将字符串转换成双精度数赋给 strp2[i]

}

catch(char *)//定义处理输入成绩的异常情况的 catch 语句块

{
    cout<<"输入了非大于等于0的十进制数,应该在西文方式输入大于等于0的十进制数,"
    <<"请重新输入"<<endl;//进行异常处理
    goto in2;
}
for(i=0;i<n;i++)
    cout<<strp2[i]<<";
cout<<endl;

ave=scoave(strp2,n);//调用计算平均分的子函数

cout<<"平均分="<<ave<<endl;

上述程序中有以下几点需要注意。

1)在异常处理中,因为要判别是否是阿拉伯数字或小数点,而且要一个数字一个数字地进行判别,所以用字符数组 c 来接收从键盘输入的信息,同时为了方便判别,将字符指针 strp 指向该字符数组 c,即对接收的信息一位一位地判别。

2)为保险起见,两件异常情况的判别都多加了一个外循环,即共判别两个大轮。

3)在输入人数时,若第一位字符是数字 1~9,且第二位之后的字符全是数字 0~9,就用 atoi(strp)将其转换成整数;在输入成绩时,若字符全是 0~9 的阿拉伯数字或小数点,就用 atof(p)将字符串转换成双精度数。

4)为防止接收数据时时间不够,而程序又进入了下一句的情况出现,特意增加了延时“delay1(1000)”。

将写出的程序与上述提纲分析比照,并用人脑跟踪运行,直至认为正确(即可以完成题目的功能,也符合C++的语法及规定),就可以转入下一步了。

(3)C++帮助且裁判,人定胜机凯歌扬

将上面的程序输入计算机→编译→连接→如果无错→运行[→调试修改→如果无错→运行]。

运行结果:

请输入学生人数

10

人数=10

原书第 282 页

请按人数输入每个学生的成绩

60

r

输入了非大于等于0的十进制数,应该在西文方式输入大于等于0的十进制数,请重新输入

90

88

79

57

91

82

94

68

80

60 90 88 79 57 91 82 94 68 80

平均分=78.9

结果正确。

【例 19-4】题目和要求均同例 19-3,只是把输入人数的程序写成了子函数,对该子函数的异常处理分成两层来完成,请读者根据分层处理异常的语法格式来编写程序。

程序代码如下:

//ex19-3-7.cpp

#include<stdlib.h>
#include<iostream.h>
#include<string.h>
#include<process.h>

const int N=10;
void delay1(int dtime)//延时
{
    for(int i=0;i<dtime;i++)
        for(int j=0;j<100000;j++)
}

double scoave(double *strp2, int n1)//计算平均分
{
    double ave1=0;
    for(int i=0;i<n1;i++)
        ave1+=strp2[i];
    ave1/=n1;
    return ave1;
}

int inpeop()//输入人数子函数
{
    int n1;
    char c[10];
}
原书第 283 页

char *strp;

strp=c;

size_t len1;

try //定义测试输入人数的异常情况的低层 try 语句块

{
    cout<<"请输入学生人数"<<endl;
    cin>>c;
    delay1(1000);
    len1=strlen(strp);
    for(int i=0;i<2;i++)
    {
        if(*strp>=49&&*strp<=57)
            for(unsigned int j=0;j<len1;j++)
                if(*strp>=48&&*strp<=57)
                strp++;
            else
                throw strp; //如果所输入的数第二位之后的字符不是数字 0~9,
                //就抛掷异常
            else
            throw strp; //如果所输入数的第一个字符不是数字 1~9, 就抛掷异常
            strp=c;
        }
        strp=c;
        n1=atoi(strp); //将字符串转换成整数赋给 n
        cout<<"人数="<<n1<<endl;
        return n1;
    }

    catch(char *)//定义处理输入人数的异常情况的低层 catch 语句块
    {
        cout<<"输入了非十进制正整数,应该在西文方式输入十进制正整数,"
        <<"请重新输入"<<endl; //进行异常处理
        throw (strp); //将本层的异常情况抛掷给高一层进行处理
    }
}

void main()
{
    int n;
    double ave;
    try//定义测试输入人数的异常情况的高层 try 语句块
    {
        in1:n=inpeop();
    }
    catch(char *)//定义处理输入人数的异常情况的高层 catch 语句块
    {
        goto in1;
    }
}
原书第 284 页
double scof[N];
double *strp2;
strp2=scof;
char c2[10];
char *p;
p=c2;

size_t len2;

cout<<"请按人数输入每个学生的成绩"<<endl;
for(int i=0;i<n;i++)
{
    in2:try//定义测试输入成绩的异常情况的 try 语句块
    {
        cin>>c2;
        delay1(1000);
        len2=strlen(p);
        for(unsigned int j=0;j<len2;j++)
            if(*p>=48&&*p<=57||*p==46)
                p++;
                else
                throw p;//如果输入的字符不是数字 0~9 或小数点,就抛掷异常
        p=c2;//指针回移到 c2 这个字符串的首部
        strp2[i]=atof(p);//将字符串转换成双精度数赋给 strp2[i]
    }
    catch(char *)//定义处理输入成绩的异常情况的 catch 语句块
    {
        cout<<"输入了非大于等于0的十进制数,应该在西文方式输入大于等于0的十进制数,"<<"请重新输入"<<endl;//进行异常处理
        goto in2;
    }
}
for(i=0;i<n;i++)
    cout<<strp2[i]<<"";
cout<<endl;

ave=scoave(strp2,n);//调用计算平均分的子函数

cout<<"平均分="<<ave<<endl;

}

次运行结果:

请输入学生人数

10

人数=10

请按人数输入每个学生的成绩

60

原书第 285 页

输入了非大于等于0的十进制数,应该在西文方式输入大于等于0的十进制数,请重新输入

90

88

79

57

91

82

94

68

80

60 90 88 79 57 91 82 94 68 80

结果正确。

第二次运行结果:

请输入学生人数

w

输入了非十进制正整数,应该在西文方式输入十进制正整数,请重新输入

请输入学生人数

2

人数=2

请按人数输入每个学生的成绩

输入了非大于等于0的十进制数,应该在西文方式输入大于等于0的十进制数,请重新输入

90.50

输入了非大于等于0的十进制数,应该在西文方式输入大于等于0的十进制数,请重新输入

90.5

87.62

90.587.62

平均分=89.06

结果正确。

19.4 异常处理的亮点

1. 在什么情况下用异常处理的亮点

1)何时何地都要尽可能多地考虑是否应该添加异常处理。为了保证程序的可行性、可靠性、稳定性、实用性等性能,该加之处就一定要加上异常处理程序段。

2)从程序本身的运行、客观的条件、环境因素、人为因素等各方面去试验、设想、考证程序能否达到设计要求的性能指标。

2. 异常处理具体知识的亮点

1)根据前面所讲的设置异常处理的原则,规划并设计应添加的异常处理程序段。

2)合理设置检查异常段(try),正确设计抛掷异常句(throw)和捕捉、处理异常段(catch)。

3)正确书写异常处理的整套程序,注意 try、throw 和 catch 的整体结构及各自的作用。

原书第 286 页

4)捕捉、处理异常段(catch)的设计原则为:能挽救为上策,转到它处运行为中策,实在不能挽救才考虑终止程序运行,此为下策。

3. 运用异常处理的亮点

1)软件开发人员必须认真负责,做好充足的准备,严肃地对待异常情况。

2)要合理、正确、恰当地运用异常处理。

3)catch之后的后续语句段要设置得合情合理。

4)设置异常处理时,要做到多次运行试验、多方论证评价、周密分析研究。

← 第18章 输入与输出第20章 综合程序设计 →