适合具备 C 语言基础的 C 教程(十二)
时间:2021-08-19 15:49:33
手机看文章
扫描二维码
随时随地手机看文章
[导读]引言在前面的教程中,叙述了模板函数以及模板类的相关概念,在本节教程中,笔者将着重叙述 C中的异常机制,所谓异常,是程序在执行期间产生的问题,异常提供一种转移程序控制权的方式。而且异常处理主要涉及到三个关键字:try、catch、throw,下面将对异常这个概念进行详细叙述。异常的...
引言
在前面的教程中,叙述了模板函数以及模板类的相关概念,在本节教程中,笔者将着重叙述C
中的异常机制,所谓异常,是程序在执行期间产生的问题,异常提供一种转移程序控制权的方式。而且异常处理主要涉及到三个关键字:try、catch、throw,下面将对异常这个概念进行详细叙述。异常的引入
为什么要引入异常这个机制呢,假设有如下一个调用关系:A ----> B ----> C
那如果说是,C
函数中出现了一个问题,那要将这个问题找到,就需要在 C
函数里返回一个值,然后根据这个值一级一级地向上处理,有多少层就要往上传递多少层,下面是伪代码示意图:int C()
{
return XXX;
}
int B()
{
if (C())
{...}
else
return -Err;
}
int A()
{
if (B())
{...}
else
{/*处理问题*/}
}
由上述这样一个伪代码可以看出,如果通过返回值这样地方式来处理子函数出现地问题的时候,那么当函数调用很深的时候,这种处理方式的弊端也就显现出来了,代码会看起来很冗长,且略显复杂,所以也就有了异常处理机制。异常处理机制
在最开始讲述这个概念的时候,我们依旧采用刚刚所述的那个背景,A ----> B ----> C
,再有了异常机制之后,我们就可以用异常的处理机制来解决这个问题,那基于这样一个背景,同样是C
函数里出现了问题,我们用依据话来概括异常,也就是函数A捕捉函数C发出的异常。我们将上述这句话进行剖析也就剖析成如下这样几句话:- 1、谁捕捉异常?A
- 2、谁抛出异常?C
- 3、捕捉到异常怎么处理?随A
void C()
{
throw 1;
}
void B()
{
C();
}
void A()
{
try
{
B();
}
catch (i)
{
cout<<"catch exception "<endl;
}
}
上述代码啥意思呢,try
后面接一个函数调用,它的意思实际也就是说,试着运行一下B()
,如果B()
中存在问题,那么就捕获这个错误,这里的catch
和C()
函数里的throw 1
是所对应起来的。程序运行结果如下所示:也就说,throw
的值是多少,那么这里捕获的变量也就是多少。我们继续丰富上面的代码,如果说抛出的异常有很多个该如何进行处理呢?我们同样是基于刚才的背景进行叙述,函数之间的调用关系跟上述一样,我们给出各个函数的代码:void C(int i)
{
int a = 1;
double b= 1.2;
float c = 1.3;
if (i == 0)
{
cout<<"In C, it is OK"<<endl;
}
else if (i == 1)
throw a;
else if (i == 2)
throw b;
else
throw c;
}
void B(int i)
{
cout<<"call C ..."<<endl;
C(i);
cout<<"After call C"<<endl;
}
void A(int i)
{
try
{
B(i);
}
catch (int j)
{
cout<<"catch int exception "<endl;
}
catch (double d)
{
cout<<"catch double exception "<endl;
}
catch (...){
cout<<"catch other exception "<<endl;
}
}
我们会根据传入到 B()
中的参数,依次抛出不同类型的异常,然后去设置不同的捕获方式,在编写捕获代码的时候,涉及到其他的这个选项,可以用...
来替代,下面是主函数的代码,:int main(int argc, char **argv)
{
int i;
if (argc != 2)
{
cout<<"Usage: "<<endl;
cout<0]<<" <0|1|2|3>"<<endl;
return -1;
}
i = strtoul(argv[1], NULL, 0);
A(i);
return 0;
}
其中上述中的主函数中的argc
表示的是当前输入的参数个数,而argv[1]
表示的是输入的第二个参数,通过strtoul
将字符串转换为整型。下面是函数运行的结果:通过上述可以看到运行程序时输入的命令是./exception3 2
,那么这个时候也就是说argc
的值等于2
,而argv[0]
的值等于./exception3
(字符串),argv[1]
的值等于2
(字符)。上述中,我们讲述了异常处理机制时在扔出各个类型的异常时的处理方法,在整个C
教程中,贯穿始终的一直是类
这个概念,那么对于C
来说,抛出异常的时候可以抛出类
异常么,答案是可以的
。下面我们就来看一个抛出类
异常的代码,代码如下所示,首先是类的代码:class MyException
{
public:
void what(void) {cout << "This is MyException" << endl;}
};
紧接着,我们来编写各个函数的代码:void C(int i)
{
int a = 1;
double b= 1.2;
float c = 1.3;
if (i == 0)
{
cout<<"In C, it is OK"<<endl;
}
else if (i == 1)
throw a;
else if (i == 2)
throw b;
else if (i == 3)
throw c;
else if (i == 4)
throw MyException();
}
void B(int i)
{
cout<<"call C ..."<<endl;
C(i);
cout<<"After call C"<<endl;
}
void A(int i)
{
try
{
B(i);
}
catch (int j)
{
cout<<"catch int exception "<endl;
}
catch (double d)
{
cout<<"catch double exception "<endl;
}
catch (MyException