当前位置:首页 > 公众号精选 > wenzi嵌入式软件
[导读]引言在前面的教程中,叙述了模板函数以及模板类的相关概念,在本节教程中,笔者将着重叙述 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()中存在问题,那么就捕获这个错误,这里的catchC()函数里的throw 1是所对应起来的。程序运行结果如下所示:

image-20210226110245582
也就说,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], NULL0);

    A(i);

    return 0;
}
其中上述中的主函数中的argc表示的是当前输入的参数个数,而argv[1]表示的是输入的第二个参数,通过strtoul将字符串转换为整型。下面是函数运行的结果:

image-20210226162409999
通过上述可以看到运行程序时输入的命令是./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 
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭
关闭