错误可以分为两类:
编译时错误 – 在编译时发生的错误称为编译时错误,编译时错误包括库引用、语法错误。 运行时错误 - 也称为异常,在运行时捕获的异常会产生严重的问题。
异常会阻碍程序的正常执行,异常处理是在保证程序正常运行的情况下处理错误和异常的过程,例如,用户将一个数字除以零,虽然会成功编译,但会发生异常,导致我们的应用程序崩溃,为了避免这种情况,我们将在代码中使用异常处理。
在 C++ 中,异常处理是使用三个关键字完成的:
语法:
try
{
//保护代码
throw 表达式;
}
catch(异常类型)
{
//处理异常的代码
}
try
块可能抛出异常的代码写入在try
块中,然后,当代码发生错误时,该错误或异常将在 catch
块中被捕获。
catch
块catch
块用来捕获异常并处理,我们可以有多个 catch 块来处理不同类型的异常,并执行不同的操作。
throw
语句它用于向catch块抛出异常,即它用于传达有关错误的信息, throw
语句的操作数可以是任意的表达式,表达式的结果的类型决定了抛出的异常的类型。
让我们通过一个简单的例子来理解try、catch和throw的用法。
下面的程序编译成功,但程序在运行时失败,导致异常。
#include <iostream>
#include<conio.h>
using namespace std;
int main()
{
int a=10,b=0,c;
c=a/b;
return 0;
}
上面的程序能编译通过,但在运行时会崩溃,因为我们试图用 0 来除一个数,这是不可能的。
如何处理这种情况?我们可以使用异常处理,并且可以通过显示消息来通知用户不能将数字除以零。
try
、catch
和 throw
语句现在我们加入异常处理。
#include <iostream>
#include<conio.h>
using namespace std;
int main()
{
int a=10, b=0, c;
try
{
if(b == 0)
{
// 抛出异常表达式
throw "0不能作除数";
c = a/b;
}
}
catch(char* ex)
{
cout<<ex;
}
return 0;
}
以上实例输出结果:
0不能作除数
在上面的代码中,我们检查除数,如果它为零,我们将抛出异常消息,然后 catch
块捕获该异常并打印消息。
这样做程序不会崩溃,用户只会看到消息“0不能作除数”,这就是我们使用异常处理的原因。
catch
块下面的程序包含多个 catch
块,以不同的方式处理不同类型的异常。
#include <iostream>
#include<conio.h>
using namespace std;
int main()
{
int x[3] = {-1,2};
for(int i=0; i<2; i++)
{
int ex = x[i];
try
{
if (ex > 0)
// 抛出数字
throw ex;
else
// 抛出字符
throw 'ex';
}
catch (int ex) // 用于捕获int类型
{
cout << "数字异常\n";
}
catch (char ex) // 用于捕获字符或字符串
{
cout << "字符异常\n";
}
}
}
以上实例输出结果:
数字异常 字符异常
上面的示例中,如果数组x
中的整数值小于0,我们抛出一个数字作为异常,如果值大于0,那么我们抛出一个字符值作为异常,然后我们有两个不同的 catch
块来捕获这些异常。
catch
块下面的示例包含一个通用的 catch
块来捕获所有的异常,catch(...)
块负责处理所有类型的异常。
#include <iostream>
#include<conio.h>
using namespace std;
int main()
{
int x[3] = {-1,2};
for(int i=0; i<2; i++)
{
int ex=x[i];
try
{
if (ex > 0)
throw ex;
else
throw 'ex';
}
// 通用异常处理
catch (...)
{
cout << "异常处理\n";
}
}
return 0;
}
以上实例输出结果:
异常处理 异常处理
在上面的例子中,两个异常都被一个 catch
块捕获。
<exception> 下的 C++ 中有一些标准异常,我们可以在程序中直接使用它们,如下所示: