C++基础:异常

紧接上一篇错误,看C++如何应对这些错误问题,与现代编程语言类型,C++也提供了一种错误处理机制:异常。
异常:
为了保证检测到的错误不会被遗漏,异常处理的的基本思想是把错误检测(在被调函数中完成)和错误处理(在主调函数中完成)分离。
异常就是把各种最好的,错误处理方法,组合在一起,来处理函数检测出来错误的方法。

异常的基本思想:如果一个函数发现一个自己不能处理的错误,它不是正常返回,而抛出(throw)一个异常来表示错误的发生。任何一个直接或者简介的函数调用者都可以捕捉这一异常,并确定应该如何处理。函数可以用try语句来处理异常:把所要处理的异常情况罗列在catch语句后面。如果出现一个没有被任何调用函数处理处理的异常,程序终止运行。

参数错误:

#include"std_lib_facilities.h"

class Bad_area{};/一个专门报告area()错误的类

//caculate the area of a rectangle;
//throw an exception if arguments occured mistake

int area (int length, int width){
    if (length < 0 || width < 0) throw Bad_area();
    return length* width;
}

int main()
try{
    int x = -1;
    int y = 2;
    int area1 = area(x,y);
}
catch (Bad_area) {
    cerr << "Oops! bad arguments to area()\n";
}

上面的错误处理是针对所有对area()的调用,如何处理错误和检测错误是分离的:main()不知道那个函数做了throw Bad_area()的动作,area()不知道那个函数会捕捉它所抛出的Bad_area异常。
在这里插入图片描述
cerr与cout的,用法相同,只是它是专门用于错误输出的。缺省的情况下,cerr和cout都输出到屏幕上。但是cerr没有优化更合适的错误信息输出,在一些操作系统中它可以被转向到其他输出目标,例如一个文件中。使用cerr也有助于我们编写与错误相关的文档。因此我们使用cerr作为错误输出。

范围错误

在ector篇中提到范围说是前闭后开的半开区间[low,high),今天我们来看利用异常的知识,看看访问最后一个地址,看是不是真的如此。

#include"std_lib_facilities.h"

int main()
try{
    vector<int> v ;
    for (int x; cin >> x;) 
        v.push_back(x);
    for (int i = 0; i <= v.size(); ++i)
        cout << "v[" << i << "] = " << v[i]<<'\n';
}catch (out_of_range){
    cerr << "Oops! Range error \n";
    
    return 1;
}

在这里插入图片描述看来确实如此,输入6个数字后,我们用|结束,其实只要不是int类型都可以结束。

列举一个简单的输入错误例子,用异常抛出,在catch捕捉解决 C++

#include"std_lib_facilities.h"

//4---------
    

int main()
try{
    double d = 0;
    cin >> d;
    if (!cin) runtime_error("couldn`t read a double in 'some_function()';");
    return 0;
}
catch (runtime_error err) {
    cerr << "Runtime error: " << err.what() << '\n';
    return 1;
}

在这里插入图片描述
返回到1,但是编译器没有输出我们预想的错误信息,对于runtime_error这个函数还不熟悉。

窄化错误

逻辑错误

#include"std_lib_facilities.h"


//5.-------------------------------------------------------------------------------
int main()
{
    vector<double> temps;

    for (double temp; cin >> temp;)
        temps.push_back(temp);

    double sum = 0;
    double high_temp = 0;
    double low_temp = 0;
 
    for (int x: temps)
    {
        if (x > high_temp)  high_temp = x;
        if (x < low_temp) low_temp = x;   
        sum += x;
    }

    cout << " The high temperature is " << high_temp << '\n';
    cout << " The low temperature is " << low_temp << '\n';
    cout << " The average temperature is " << sum / temps.size() << '\n';
}

在这里插入图片描述我们明明没有输入0,最低的温度怎么会是0呢?这个就是逻辑错误。我们在写这个代码时,初始化最低最高温度时就为0,所以这里就会有个限制,如果你输入的温度没有低于等于我们初始化最低温度low_temp=0度的,那么最低温度永远不可能正确。

在深入思考一下,如果这个初始化的温度设置为以下值,估计在没有了解这个程序的情况下很难有输出正确值。

   double high_temp = -1000;
   double low_temp = +1000;

那么怎么解决这个逻辑错误呢?很简单,再写一个读入,然后把这个值赋值给最高最低值,这样记录的就是我们读入的值了,而不是那个初始化的值。

#include"std_lib_facilities.h"


//5.-------------------------------------------------------------------------------
int main()
{
    vector<double> temps;

    double sum = 0;
    double high_temp = 0;
    double low_temp = 0;

    double temp;
    cin >> temp;
    high_temp = low_temp = temp;

    for (temp; cin >> temp;)
        temps.push_back(temp);

    for (int x: temps)
    {
        if (x > high_temp)  high_temp = x;
        if (x < low_temp) low_temp = x;   
        sum += x;
    }

    cout << " The high temperature is " << high_temp << '\n';
    cout << " The low temperature is " << low_temp << '\n';
    cout << " The average temperature is " << sum / temps.size() << '\n';
    
}

在这里插入图片描述虽然写的有点重复,但是逻辑上正确。

下一篇我们用来这些学到的知识来调试一个简单的程序,来排除这些错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值