紧接上一篇错误,看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 mistakeint 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';}
虽然写的有点重复,但是逻辑上正确。
下一篇我们用来这些学到的知识来调试一个简单的程序,来排除这些错误。