嵌入式学习-C嘎嘎-Day06

news/2024/11/21 23:52:29/

嵌入式学习-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/news/1548885.html

相关文章

使用MATLAB进行随机信号处理

MATLAB是一款强大的数学计算软件&#xff0c;广泛应用于工程、科学和经济等领域。其中&#xff0c;随机信号处理是MATLAB其中一个重要的应用领域。本文将探讨随机信号的基本概念、生成方法以及MATLAB中如何处理随机信号。 1.随机信号的基本概念 随机信号是指信号的大小或形状…

How to install rust in Ubuntu 24.04

How to install rust in Ubuntu 24.04 Install Install 可以采用如下命令安装rust curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh具体如下&#xff1a; lwkqwfys:~$ curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh info: downloading instal…

python基础知识(七)——写入excel

一、写入excel 写入数据到excel wb load_workbook("testcase_api_wuye.xlsx") #打开一个已经存在的excel文件 sh wb["register"] #识别某一个表单 sh.cell(row 2,column 8).value "pass" #写入数据&#xff0c;单元格的值赋值 wb.sav…

Kotlin深度面试题:协程、密封类和高阶函数

文章目录 知识回顾前言源码分析1.面试题目1&#xff1a;Kotlin中的协程与线程的区别是什么&#xff1f;如何在Android中使用协程进行异步编程&#xff1f;2.面试题目2&#xff1a;Kotlin中的扩展函数和扩展属性是什么&#xff1f;如何在Android开发中使用它们&#xff1f;3. 面…

编译安装 openssl-3.0.14

编译和安装 OpenSSL 3.0.14 的步骤如下&#xff1a; 1. 下载 OpenSSL 源码 首先&#xff0c;从 OpenSSL 的官方网站下载所需版本的源代码。你可以使用 wget 或 curl 命令来下载&#xff1a; wget https://www.openssl.org/source/openssl-3.0.14.tar.gz或者 curl -O https:…

【国产MCU系列】-GD32F470-通用同步异步收发器(USART)

通用同步异步收发器(USART) 文章目录 通用同步异步收发器(USART)1、USART与UART介绍2、GD32F4的USART2.1 GD32F4的USART介绍与特性2.2 GD32F4的USART寄存器列表3、USART数据发送与接收与配置3.1 数据帧格式与配置3.2 波特率发生与配置3.3 UART发送器配置与步骤3.4 UART接收…

【大选】2024年美国总统选举数据分析可视化

前言 • &#x1f453; 可视化主要使用 Plotly • &#x1f50e; 数据处理主要使用 pandas • &#x1f449; 本文是我自己在和鲸社区的原创 1.项目背景描述 2024年美国大选是该国政治生活中的重要事件&#xff0c;吸引了全球的关注。本报告通过对选举数据的分析&#xff0c…

Web导出Excel表格

背景&#xff1a; 1. 后端主导实现 流程&#xff1a;前端调用到导出excel接口 -> 后端返回excel文件流 -> 浏览器会识别并自动下载 场景&#xff1a;大部分场景都有后端来做 2. 前端主导实现 流程&#xff1a;前端获取要导出的数据 -> 常规数据用插件处理成一个e…