嵌入式学习-C嘎嘎-Day06

ops/2024/11/25 21:16:58/

嵌入式学习-C嘎嘎-Day06

1. 什么是异常?

2. 抛出异常

3. 捕获异常

4. 标准异常族

5. 异常捕获技巧

5.1 捕获基类异常

5.2 多重捕获

1. 什么是异常?

异常是程序在运行期间产生的问题,即没有语法错误,出现的是逻辑错误,C++提供了一种转移程序控制权的方式:

  • 异常经过程序员正确处理,继续运行;
  • 异常没有经过程序员正确处理,运行终止。

例如之前使用string的at函数,范围越界的问题等。

处理异常的方式有两种:

  • 抛出异常 throw
  • 捕获异常 try-catch

2. 抛出异常

使用throw关键字可以抛出一个异常对象,throw可以抛出任何类型的异常对象,抛出到当前代码调用的上一级。

#include <iostream>using namespace std;double divide(double a,double b)
{if(b == 0)throw "除数不能为0!!!";return a/b;
}int main()
{
    cout << divide(3,2) << endl; // 1.5
    cout << divide(2,0) << endl; // 终止运行    cout << "程序运行结束" << endl;return 0;
}

3. 捕获异常

捕获异常分为try代码块和catch代码块,try块中放置可能抛出异常的代码,catch块放置异常类型匹配的代码,处理逻辑如下:

情况1:抛出异常并捕获成功

#include <iostream>using namespace std;double divide(double a,double b)
{
    if(b == 0)
        throw "除数不能为0!!!";
    return a/b;
}int main()
{
    try
    {
        cout << divide(2,0) << endl;
        cout << "A" << endl;
    }catch(const char* e)
    {
        cout << e << endl;
        // 正常开发下,需要修复逻辑错误
    }
    cout << "程序运行结束" << endl;
    return 0;
}

情况2:抛出异常,捕获失败

#include <iostream>using namespace std;double divide(double a,double b)
{
    if(b == 0)
        throw "除数不能为0!!!";
    return a/b;
}int main()
{
    try
    {
        cout << divide(2,0) << endl;
        cout << "A" << endl;
    }catch(int e)
    {
        cout << e << endl;
        // 正常开发下,需要修复逻辑错误
    }
    cout << "程序运行结束" << endl;
    return 0;
}

情况3:没有抛出异常,正常直接try块结束。

#include <iostream>using namespace std;double divide(double a,double b)
{
    if(b == 0)
        throw "除数不能为0!!!";
    return a/b;
}int main()
{
    try
    {
        cout << divide(2,1) << endl;
        cout << "A" << endl;
    }catch(int e)
    {
        cout << e << endl;
        // 正常开发下,需要修复逻辑错误
    }
    cout << "程序运行结束" << endl;
    return 0;
}

异常如果不在当前层次进行处理,也可以交给上一级进行处理,但是如果主函数中还没有正确处理,则程序终止。

#include <iostream>using namespace std;double divide(double a,double b)
{
    if(b == 0)
        throw "除数不能为0!!!";
    return a/b;
}void test()
{
    try
    {
        cout << divide(2,0) << endl;
        cout << "A" << endl;
    }catch(int e)
    {
        cout << "B" << endl;
        cout << e << endl;
        // 正常开发下,需要修复逻辑错误
    }
}int main()
{
    try
    {
        test();
    }catch(const char* e)
    {
        cout << "C" << endl;
        cout << e << endl;
        // 正常开发下,需要修复逻辑错误
    }
    cout << "程序运行结束" << endl;
    return 0;
}

4. 标准异常族

C++为常见的异常类型进行层次划分,通过继承实现。

使用标准异常族需要引入头文件 #include <stdexcept>

自定义异常类型应该通过继承加入上面的结构。

#include <iostream>
#include <stdexcept> // 头文件using namespace std;class ZeroException:public exception
{
public:
    // throw() 是异常规格说明,表示what函数不会抛出任何异常
    const char* what() const throw()
    {
        return "除数不能为0!!!";
    }
};double divide(double a,double b)
{
    if(b == 0)
        throw ZeroException();
    return a/b;
}int main()
{
    try
    {
        cout << divide(2,0) << endl;
        cout << "A" << endl;
    }catch(const ZeroException& e)
    {
        cout << e.what() << endl;
        // 正常开发下,需要修复逻辑错误
    }
    cout << "程序运行结束" << endl;
    return 0;
}

5. 异常捕获技巧

5.1 捕获基类异常

所有抛出的派生类异常对象都可以被其基类异常类型捕获。

#include <iostream>
#include <stdexcept> // 头文件using namespace std;void poly_except()
{
    int a = 1;
    if(a == 1)
    {
        throw out_of_range("hah");
    }else {
        throw domain_error("随便");
    }
}int main()
{
    try
    {
        poly_except();
    }catch(const logic_error& e)
    {
        cout << e.what() << endl;
        // TODO 修复逻辑代码
    }    cout << "程序运行结束" << endl;
    return 0;
}

5.2 多重捕获

可以使用多个catch块配合try块进行异常捕获,catch的顺序要求派生类异常先捕获,基类异常后捕获

#include <iostream>
#include <stdexcept> // 头文件using namespace std;void poly_except()
{
    int a = 2;
    if(a == 1)
    {
        string s;
        s.at(-1);
    }else {
        throw underflow_error("f");
    }
}int main()
{
    try
    {
        poly_except();
    }catch(const out_of_range& e)
    {
        cout << "A" << endl;
    }catch(const domain_error& e)
    {
        cout << "B" << endl;
    }catch(const logic_error& e)
    {
        cout << "C" << endl;
    }catch(const exception& e)
    {
        cout << "D" << endl;
    }    cout << "程序运行结束" << endl;
    return 0;
}

还可以单独使用一个...捕获所有异常,但是不推荐。

#include <iostream>
#include <stdexcept> // 头文件using namespace std;void poly_except()
{
    int a = 2;
    if(a == 1)
    {
        string s;
        s.at(-1);
    }else {
        throw "fdfdfd";
    }
}int main()
{
    try
    {
        poly_except();
    }catch(...)
    {
        cout << "A" << endl;
    }
    cout << "程序运行结束" << endl;
    return 0;
}

C++的异常处理机制并不完善,是否使用取决于开发团队的要求。


http://www.ppmy.cn/ops/136668.html

相关文章

HarmonyOS Next 浅谈 发布-订阅模式

HarmonyOS Next 浅谈 发布-订阅模式 前言 其实在目前的鸿蒙应用开发中&#xff0c;或者大前端时代、vue、react、小程序等等框架、语言开发中&#xff0c;普通的使用者越来越少的会碰到必须要掌握设计模式的场景。大白话意思就是一些框架封装太好了&#xff0c;使用者只管在它…

河道水位流量一体化自动监测系统:航运安全的护航使者

在广袤的水域世界中&#xff0c;航运安全始终是至关重要的课题。而河道水位流量一体化自动监测系统的出现&#xff0c;如同一位强大的护航使者&#xff0c;为航运事业的稳定发展提供了坚实的保障。 水位传感器&#xff1a;负责实时监测河道的水位变化。这些传感器通常采用先进的…

基于Java Springboot汽车4s店管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

国土变更调查拓扑错误自动化修复工具的研究

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、拓扑错误的形成原因 1.边界不一致 2.不规则图形 3.尖锐角 4.局部狭长 5.细小碎面 6.更新层相互重叠 二、修复成果展示 1.边界不一致 2.不规则图形 3.尖锐角 4.局部狭…

IEC61850读服务器目录命令——GetServerDirectory介绍

IEC61850标准中的GetServerDirectory命令是变电站自动化系统中非常重要的一个功能&#xff0c;它主要用于读取服务器的目录信息&#xff0c;特别是服务器的逻辑设备节点&#xff08;LDevice&#xff09;信息。以下是对GetServerDirectory命令的详细介绍。 目录 一、命令功能 …

Linux 进程概念与进程状态

目录 1. 冯诺依曼体系结构2. 操作系统&#xff08;Operator System&#xff09;2.1 概念2.2 设计OS的目的2.3 系统调用和库函数概念 3. 进程概念3.1 描述进程 - PCB3.2 task_struct3.3 查看进程3.4 通过系统调用获取进程标识符PID&#xff0c; PPID3.5 通过系统调用创建fork 4.…

数据结构-图的遍历

一.深度优先搜素 遍历&#xff1a;把图中的每一个顶点访问一遍 把自己所能看见灯任意点亮然后依次进行点亮操作,当自己所能看见的灯全都被点亮&#xff0c;也不能直接从节点退出&#xff0c;而是回退然后继续进行上述操作 当所有的灯都被点亮了,一定要原路返回直到返回到出口…

C++之旅-set和map掌握篇

目录 前言 1.set的使用 1.1set类的介绍 1.2 set的构造和迭代器 1.3 set的增删查 1.4 代码练习 1.4.1 set的构造&#xff0c;插入与删除 1.4.2 set 的find的使用样例&#xff0c;与erase结合 1.4.3 set获取区间值函数的应用 1.5 multiset和set的差异 1.6 set强化练习&…