编译器视角下的 C++ 异常:探究 throw 与 catch 的编译原理
目录
0.写在前面
1.C++异常概念
异常的定义:
异常处理的基本组成部分:
1. throw表达式
2. try块
3. catch块
2. 异常的使用
异常的抛出和匹配原则:
在函数调用链中异常栈展开匹配原则:
3.异常的重新抛出
4.异常安全
异常安全的定义:
5.异常规范
6.自定义异常体系
7.C++标准库的异常体系
8.异常的优缺点
优点:
缺点:
0.写在前面
在C++中引入了一种处理错误的新方式,那就是异常。来想想C语言是如何处理错误的:
1. 返回错误码
函数在执行过程中遇到错误时,会返回一个特定的值来表示错误状态。通常,返回值为 0 表示正常执行,而负数或特定的非零值表示不同类型的错误。调用者需要检查函数的返回值,根据返回值来判断函数是否执行成功,并进行相应的处理。但是,如果有多个函数嵌套进去,错误码就需要层层返回,颇为麻烦。
2. 使用全局错误变量errno
errno
是一个全局整数变量,定义在<errno.h>
头文件中。当某些库函数执行失败时,会设置errno
为一个特定的错误码,不同的错误码代表不同的错误类型。可以使用strerror
函数将errno
转换为对应的错误信息字符串。
3. 使用assert函数
使用assert函数需要包含头文件<assert.h>,assert又称断言,可以来对输入的变量或者其他特殊关系进行断言,如果表达式为真那么不进行报错,如果表达式为假,那么就会强制终止程序,做的很决断。
下面将要介绍异常的使用和优缺点:
1.C++异常概念
异常的定义:
异常是程序在执行过程中出现的不正常情况,这些情况可能会导致程序无法按照正常流程继续执行。例如,除零错误、内存分配失败、文件打开失败等都属于异常情况。C++ 异常机制允许程序在出现异常时,能够将控制权从错误发生的位置转移到专门处理该异常的代码块。
异常处理的基本组成部分:
1. throw表达式
throw用于抛出异常。当程序中检测到异常情况时,可以使用throw语句抛出一个异常对象。这个异常对象可以是基本数据类型(如int,double等),也可以是自定义的类对象。
2. try块
try块包含可能抛出异常的代码。在try块中执行的代码如果抛出了异常,程序会立即停止当前try块的执行,转而寻找匹配的catch块。
3. catch块
catch块用于捕获和处理异常。当try块中抛出异常时,程序会在try块后面的catch块中寻找类型匹配的catch块。如果找到匹配的catch块,就会执行该catch块中的代码;如果没有找到匹配的catch块,最后会终止程序。
double Division(int a, int b)
{// 当b == 0时抛出异常if (b == 0)return "Division by zero condition!";elsereturn ((double)a / (double)b);
}
void Func()
{int len, time;cin >> len >> time;cout << Division(len, time) << endl;
}int main()
{try {Func();}catch (const string errmsg){cout << errmsg << endl;}return 0;
}
2. 异常的使用
异常的抛出和匹配原则:

上面可以看到,throw的类型不同,catch中的处理情况也不同!
补充:如果抛出异常的的代码不在try块内,那么异常不会被捕捉到;如果没有catch的类型与throw的类型相互匹配,那么异常就会捕捉失败,程序终止。

可以看到,在Func函数中直接被catch捕捉到了,那么main函数中的catch就没有机会再去捕捉了。

在Division中throw一个string对象,那么会做传值返回,string会发生拷贝生成临时对象,出函数后string被销毁。
在函数调用链中异常栈展开匹配原则:



3.异常的重新抛出
有时候我们不想立马处理异常,想要将异常留到最后处理,或写成日志,或统一处理该怎么办呢?这里可以这样使用:catch(...)搭配上throw;这样就可以接收任意了类型的throw并重新抛出任意类型的异常。
double Division(int a, int b)
{// 当b == 0时抛出异常if (b == 0){throw "Division by zero condition!";}return (double)a / (double)b;
}
void Func()
{// 这里可以看到如果发生除0错误抛出异常,另外下面的array没有得到释放。// 所以这里捕获异常后并不处理异常,异常还是交给外面处理,这里捕获了再// 重新抛出去。int* array = new int[10];try {int len, time;cin >> len >> time;cout << Division(len, time) << endl;}catch (...){cout << "delete []" << array << endl;delete[] array;throw;}// ...cout << "delete []" << array << endl;delete[] array;
}
int main()
{try{Func();}catch (const char* errmsg){cout << errmsg << endl;}return 0;
}
请注意:图中的代码在Division函数中如果不在throw;前加上对array的释放那么就会发生内存泄露,这里throw;后直接返回了main函数!
4.异常安全
异常安全的定义:
异常安全指的是当程序中抛出异常时,程序仍能保持一种合理、安全的状态。这包括保证资源的正确释放、数据的一致性以及程序的可继续执行性等。如果一个程序不具备异常安全性,那么在发生异常时可能会导致资源泄漏(如内存、文件句柄等未释放)、数据处于不一致状态(如对象的部分成员更新,部分未更新)等问题。
对于异常安全,要注意以下问题:
- 构造函数完成对象的构造和初始化,最好不要在构造函数中抛出异常,否则可能导致对象不完整或没有完全初始化
- 析构函数主要完成资源的清理,最好不要在析构函数内抛出异常,否则可能导致资源泄漏(内存泄漏、句柄未关闭等)
- C++中异常经常会导致资源泄漏的问题,比如在new和delete中抛出了异常,导致内存泄漏,在lock和unlock之间抛出了异常导致死锁,C++经常使用RAII来解决以上问题,RAll后面讲解。
5.异常规范
异常规范是 C++ 中用于声明函数是否会抛出异常以及抛出哪些异常类型的机制,但在不同标准版本中有不同的实现和语义。以下是关键点:
1. 异常规格说明的目的是为了让函数使用者知道该函数可能抛出的异常有哪些。 可以在函数的 后面接throw(类型),列出这个函数可能抛掷的所有异常类型。2. 函数的后面接throw(),表示函数不抛异常。3. 若无异常接口声明,则此函数可以抛掷任何类型的异常。
// 这里表示这个函数会抛出A/B/C/D中的某种类型的异常
void fun() throw(A,B,C,D);
// 这里表示这个函数只会抛出bad_alloc的异常
void* operator new (std::size_t size) throw (std::bad_alloc);
// 这里表示这个函数不会抛出异常
void* operator delete (std::size_t size, void* ptr) throw();// C++11 中新增的noexcept,表示不会抛异常
thread() noexcept;
thread (thread&& x) noexcept;
补充:C++11中新加了noexcept关键字,可以直接在函数名后面加上noexcept表示不会抛异常。
异常规范有什么用?在函数名后面加上可能抛出的异常类型可以大大提高调试的效率,为了养成好的编程习惯,建议加上!
6.自定义异常体系


上面是一个Exception定义的一个异常类,注意到有一个virtual的what函数,我们再来看看继承了这个基类的派生类:
看,这个派生类中对what函数进行了重写,那么调用的时候就已经满足了虚函数的重写,只需要使用基类的指针或者引用调用就可以实现多态,即不同的派生类对象传值产生不同的异常信息。

7.C++标准库的异常体系
C++库中也实现了多个派生类继承自基类exception,了解一下即可:
我们来尝试捕捉一下库中exception的异常信息:小试牛刀:~
void test2()
{vector<int> v;try{v.reserve(10000000000000);//v[9999999999910000000];}catch (const exception& e){cout << e.what() << endl;//常用的是bad_alloc out_of_range 两种异常}
}
结果是什么?
可以看到这是库中自带的异常信息,我们开辟一个巨大的空间,vector开辟失败并抛出了一个异常,可见必须掌握异常的捕捉,才可以更加熟练的使用STL~
8.异常的优缺点
优点:
分离错误处理与业务逻辑
异常机制将正常代码与错误处理解耦。开发者只需在可能出错的地方抛出异常,调用方通过try/catch
集中处理错误,避免了函数返回值中混杂大量错误检查代码,使代码更简洁、可读性更高。支持跨层级错误传递
当深层嵌套的函数发生错误时,异常能自动沿调用栈向上传递,直到被最近的catch
捕获。这避免了逐层手动传递错误码的繁琐(C语言的做法),尤其适合复杂调用链的场景。携带丰富错误信息
异常对象可自定义(如继承std::exception
),允许封装错误描述、错误码、上下文数据等。相较于简单的错误码,这为调试和日志记录提供了更详细的信息。在公司中,通常在exception中定义错误信息和错误id,这方便开发者去查看bug的具体错误。
缺点:
性能开销
异常处理机制(如栈展开、类型匹配)会引入额外开销。在频繁抛出异常或对性能敏感的场景(如实时系统),可能影响效率。比如在上述代码中,我们返回string,这就需要开辟空间。破坏代码执行流
异常会导致程序的执行流乱跳,并且非常的混乱,并且是运行时出错抛异常就会乱跳。这会导致我们跟踪调试时以及分析程序时,比较困难。
相关文章:
编译器视角下的 C++ 异常:探究 throw 与 catch 的编译原理
目录 0.写在前面 1.C异常概念 异常的定义: 异常处理的基本组成部分: 1. throw表达式 2. try块 3. catch块 2. 异常的使用 异常的抛出和匹配原则: 在函数调用链中异常栈展开匹配原则: 3.异常的重新抛出 4.异常安全 异…...
测试淘宝评论接口返回数据的详细说明
在电商数据分析、用户体验优化和竞品分析中,获取商品评论数据是一项重要的功能。淘宝开放平台提供了商品评论的 API 接口,允许开发者通过合法的方式获取商品的用户评论数据。本文将详细介绍如何测试淘宝评论接口的返回数据,包括接口调用步骤、…...
【微知】plantuml在泳道图中如何将几个步骤放入一个框中?(group “sub框1“; end !! “sub框1“)
背景 将几个步骤放在一起画个框,分区方便 命令 用法: group 和 end 关键字 用法: group "sub框1"User -> User: 模板渲染User -> User: 返回 HTMLend !! "sub框1" 这里!!是注释实操 修改前: 修改…...
深入解析 React 最新特性:革新、应用与最佳实践
深入解析 React 最新特性:革新、应用与最佳实践 1. 引言 React 作为前端开发的核心技术之一,近年来不断推出 新的 API 和优化机制,从 Concurrent Rendering(并发模式) 到 Server Components(服务器组件&a…...
C语言之数据结构:理解什么是数据结构和算法(启航)
引言 启航篇,理解什么是数据结构和算法 在 C 语言编程领域,数据结构和算法是两个核心且紧密相关的概念 一、数据结构 定义 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合(比如数组),它是组织和存储数…...
【21】单片机编程核心技巧:if语句逻辑与真假判断
【21】单片机编程核心技巧:if语句逻辑与真假判断 七律 条件分野 if语句判真假,括号条件定乾坤。 非零为真零为假,大括号内藏玄门。 省略虽简风险在,代码规范护本根。 单片逻辑由心控,条件分支自成文。 注释…...
hackme靶机通关攻略
第一步:确定靶机IP 第二步:使用御剑后台扫描工具扫描敏感文件 第三步:访问register.php注册登录,进入welcome.php页面 第四步:访问一个不存在的页面,确定网站使用的中间件是Apache(无用…...
网络安全演练有哪些形式
OPENVAS使用 1、确定指定IP是否能ping通 2、创建扫描目标 3、创建扫描任务(scan management →newtask) 4、开始任务start 5、查看扫描细节 6、查看扫描结果,包含漏洞详细信息,亦可到处PDF文件 7、导出扫描结果报告 8、为…...
PE,ELF,COFF
本文来自 (1)腾讯元宝 (2)程序员的自我修养 PE(Portable Executable)是一种文件格式,主要用于Windows操作系统中的可执行文件(如.exe、.dll、.sys等)。PE格式是Windows操作系统中标准的可执行文件格式,由…...
sql靶场-时间盲注(第九、十关)保姆级教程
目录 时间盲注(第九、十关) 1.判断 2.确认时间盲注 2.手工尝试时间盲注 数据库名长度 数据库名字符 表数 表名长度 表名字符 字段数 字段名长度 字段名字符 4.脚本时间盲注注入 5.第十关 时间盲注(第九、十关) 1.判…...
常见FUZZ姿势与工具实战:从未知目录到备份文件漏洞挖掘
本文仅供学习交流使用,严禁用于非法用途。未经授权,禁止对任何网站或系统进行未授权的测试或攻击。因使用本文所述技术造成的任何后果,由使用者自行承担。请严格遵守《网络安全法》及相关法律法规! 目录 本文仅供学习交流使用&am…...
【linux】解决 Linux 系统中 root 用户无法打开图形界面问题
【linux】解决 Linux 系统中 root 用户无法打开图形界面问题 问题描述: 在 Linux 系统中,当我们远程SSH尝试以 root 用户身份运行需要图形界面的应用程序时,可能会遇到以下错误信息: MoTTY X11 proxy: Unsupported authorisati…...
数据库系统概念全面解析
数据库系统可能看起来很抽象,但其实它们就像我们生活中的许多事物一样,有着清晰的结构和规则。让我们通过一些有趣的生活例子来理解这些概念。 一、数据库系统基础 想象一个图书馆: - 数据库管理系统(DBMS) 就像图书馆的管理员 - 数据库(DB…...
unity Rigidbody2D、Collider2D参数详解
Rigidbody2D属性: BodyType:类别Simulated:模拟,是否模拟真实物理效果。Use Auto Mass:使用自动质量,根据BoxCollider2D大小来设定Mass:质量。Linear Drag:影响位置移动的阻力系数An…...
es-索引详解
在 Elasticsearch 中,**索引(Index)**是核心概念之一,类似于关系型数据库中的“表”。索引用于存储、组织和检索文档(Document)。以下是关于 Elasticsearch 索引的详细解析: 1. 索引的基本概念 …...
SpringBoot3+Lombok如何配置logback输出日志到文件
Background/Requirement SpringBoot3Lombok如何配置logback输出日志到文件,因为我需要对这些日志进行输出,控制台输出和文件输出,文件输出是为了更好的作为AuditLog且支持滚动式备份,每天一个文件。 Technical Solution 1.确保你…...
城市客运安全员适合哪几类人报考
城市客运安全员适合以下几类人报考: 相关专业人员:交通工程、安全工程、交通运输管理等相关专业的人员,他们在学校系统学习过交通安全、运输管理、安全管理等方面的知识,具备扎实的理论基础,更容易理解和掌握城市客运…...
Elasticsearch 解析 updateTime 字段时格式错误
遇到的问题: {"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"failed to parse field [updateTime] of type [date] in document with id 57"}],"type":"mapper_parsing…...
Windows远程桌面黑屏怎么办?
在使用Windows远程桌面连接另一台电脑时,用户经常会遇到Windows远程桌面黑屏的问题。那么,该如何有效地解决Windows远程桌面黑屏的问题呢?遇到远程桌面连接黑屏的问题时,可以通过在本地组策略编辑器中禁用WDDM图形显示驱动来解决。…...
计算机视觉|超详细!Meta视觉大模型Segment Anything(SAM)源码解剖
一、引言 在计算机视觉领域,图像分割是一个核心且具有挑战性的任务,旨在将图像中的不同物体或区域进行划分和识别,广泛应用于自动驾驶、医学影像分析、安防监控等领域。Segment Anything Model(SAM)由 Meta AI 实验室…...
【不动产登记全解析】范围、内容与不予登记的情形
在现代经济社会中,不动产作为重要的资产形式,其权利的确立与流转离不开规范的登记制度。今天,我们就来深入探讨不动产登记的三大核心议题:登记的广泛范围、登记簿上的必备记载事项,以及在哪些情况下不动产登记将不会被…...
机器学习之距离度量方法
常见的距离度量方法及相关函数、图示如下: 1. 欧几里得距离(Euclidean Distance) 函数公式:对于两个 ( n ) 维向量 ( x = ( x 1 , x 2 , ⋯ ,...
2340单点修改、区间查询
2340单点修改、区间查询 ⭐️难度:中等 🌟考点:线段树 📖 📚 import java.util.Scanner;public class Main {static int N 100010;static int n;static int[] c new int[N];static int lowbit(int x){ // 求loub…...
Go语言 vs Java语言:核心差异与适用场景解析
在当今的软件开发领域,Go(Golang)和Java都是备受关注的后端开发语言。尽管二者都能构建高性能服务,但它们在设计哲学、语法特性和应用场景上存在显著差异。本文将从多个维度对比这两种语言,帮助开发者更好地理解它们的…...
18 | 实现简洁架构的 Handler 层
提示: 所有体系课见专栏:Go 项目开发极速入门实战课;欢迎加入 云原生 AI 实战 星球,12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力(聚焦于 Go、云原生、AI Infra);本节课最终…...
谷歌Gemma 3:开启AI新纪元的强大引擎
摘要 谷歌公司今日宣布推出最新版本的人工智能模型——Gemma 3。该模型基于Gemini AI技术,是继一年前两款“开放”Gemma AI模型后的进一步发展。Gemma 3以其卓越性能著称,能够在单个GPU上运行,成为迄今为止最强大的AI模型之一。这一技术升级标…...
【Java项目】基于JSP的电子商城系统
【Java项目】基于JSP的电子商城系统 技术简介:采用JSP技术、B/S结构、MYSQL数据库等实现。 系统简介:该电子商城系统包括用户、医生和管理员。其主要功能包括管理员:个人中心、用户管理、医生管理、药品信息管理、线上诊疗管理、医生信息管理…...
双 Token 无感刷新机制在前后端分离架构中实现
在前后端分离的架构中,双 Token 无感刷新是一种常见的身份验证机制,用于在 Access Token 过期时,通过 Refresh Token 自动获取新的 Access Token,从而避免用户频繁登录。 1. 双 Token 无感刷新的核心流程 1.1 核心流程 用户登录&…...
Linux中的基本指令(下)
目录 mv指令 more指令 less指令 head指令 tail 指令 继续理解文件 重定向和追加重定向操作 理解管道 find指令 whereis 指令 bc指令 uname ‒r指令 grep 指令 关机 扩展命令 zip/unzip 指令 tar指令 关于rzsz 系统间的文件互传 接上! mv指令 m…...
电子电气架构 --- 智能电动汽车概述
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 人生是一场骗局,最大的任务根本不是什么买车买房,也不是及时行乐,这就…...
Unity | 工具类:消息管理器-延迟分发
目录 一、消息管理器 二、获得新装备 三、UI面板创建 消息管理器除了简单的订阅(Subscribe)、取消订阅(Unsubscribe)操作以外,还需处理延迟分发(Dispatch)的情况。 (即时处理可参考:Unity | 工具类-利用事件系统进行业务串通-CSDN博客&…...
医院本地化DeepSeek R1对接混合数据库技术实战方案研讨
1. 引言 Deep SEEK R1是一个医疗智能化平台,通过本地化部署实现数据的安全性和可控性,同时提供高效的计算能力。随着医疗信息化的迅速发展,各种数据源的增加使得医院面临更多复杂的挑战,包括如何处理实时监测数据、如何进行大数据环境下的复杂查询以及如何整合多模态数据等…...
GPU加速的国密SM2算法实现
目录 GPU加速的国密SM2算法实现一、前言二、国密SM2算法概述2.1 国密SM2算法背景2.2 SM2的数学基础2.3 SM2数字签名流程三、GPU加速在SM2算法中的应用3.1 高性能运算需求3.2 GPU加速优势3.3 加速实现思路四、基于Python的SM2算法实现与GPU加速4.1 算法模块设计4.2 主要数学公式…...
《UE5_C++多人TPS完整教程》学习笔记35 ——《P36 武器类(Weapon Class)》
本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P36 武器类(Weapon Class)》 的学习笔记,该系列教学视频为计算机工程师、程序员、游戏开发者、作家(Engineer, Programmer, Game Developer, Author) Stephen …...
Linux——Shell运行原理以及Linux权限
目录 1. Shell的运行原理 2. Linux中的权限问题 2.1 Linux权限的概念 2.1.1 如何实现用户账号之间的切换 2.1.2 如何将普通用户添加到信任列表中 2.1.3 如何仅提升当前指令的权限 2.2 Linux权限管理 2.2.1 文件访问者的分类(人) 2.2.2 文件类型…...
SpringBoot注解驱动CRUD工具:spring-avue-plus
项目背景 作为一个后端小伙伴,最大的痛点就是写完的接口需要拥有一些可视化的页面去承载这些功能使用【如果是只给后端那么swagger也足够了,非后端有点呛】如果有专业前端去弄确实也快,但是小公司呀~~~ 学呗~妈呀,现在的前端也挺…...
Redis 数据持久化之AOF
AOF(Append Only File) 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换…...
API调试工具的无解困境:白名单、动态IP与平台设计问题
引言 你是否曾经在开发中遇到过这样的尴尬情形:你打开了平台的API调试工具,准备一番操作,结果却发现根本无法连接到平台?别急,问题出在调试工具本身。今天我们要吐槽的就是那些神奇的开放平台API调试工具,…...
git commit messege 模板设置 (规范化管理git)
配置方法 git config --global core.editor vim (设置 Git 的默认编辑器为 Vim)在用户根目录下(~),创建一个.git_commit_msg文件,然后把下面的内容拷贝到文件中并保存。 [version][模块][类型]{解决xxx问题…...
串口通信ASCII码转16进制及C#串口编程完整源码下载
在工业自动化、嵌入式系统及物联网以行业中,串口编程非常重要。 串口编程,重点在于串口数据通信和数据处理。 在C#中,System.IO.Ports命名空间提供了SerialPort类,用于实现串口通信。 串口程序的开发主要包括以下几点 1.引用命…...
第十一届蓝桥杯单片机国赛
什么?4T模拟赛和省赛做起来轻轻松松?不妨来挑战一下第十一届国赛,这一届的国赛居然没考超声波、串口通信!只要你正确地理解了题目的意思,规避出题人挖的坑,拿个国一轻轻松松。 附件:第十一届蓝桥…...
Ateme在云端构建可扩展视频流播平台
Akamai Connected Cloud帮助Ateme客户向全球观众分发最高质量视频内容。 “付费电视运营商和内容提供商现在可以在Akamai Connected Cloud上通过高质量视频吸引观众,并轻松扩展。”── Ateme首席战略官Rmi Beaudouin Ateme是全球领先的视频压缩和传输解决方案提…...
QT系列教程(20) Qt 项目视图便捷类
视频连接 https://www.bilibili.com/video/BV1XY41127t3/?vd_source8be9e83424c2ed2c9b2a3ed1d01385e9 Qt项目视图便捷类 Qt项目视图提供了一些便捷类,包括QListWidget, QTableWidget, QTreeWidget等。我们分别介绍这几个便捷类。 我们先创建一个Qt …...
【最后203篇系列】014 AI机器人-1
说明 终于开张了,我觉得AI机器人是一件真正正确,具有商业价值的事。 把AI机器人当成一笔生意,我如何做好这笔生意?一端是业务价值,另一端是技术支撑。如何构造高质量的内容和服务,如何确保技术的广度和深度…...
cfi网络安全 网络安全hcip
目录 RIP (路由信息协议) 算法 开销 版本 开销值的计算方式 RIPV1和RIPV2的区别 RIP的数据包 Request(请求)包 Reponse(应答)包 RIP的特征 周期更新 RIP的计时器 1,周期更新计时器 2,失效计时器 3,垃圾回收计时器 RIP的核心思…...
HTML 基础
一、HTML 基本结构 <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>页面标题</title> </head> <body><!-- 可见内容区域 --> </body> </html><!DOCTYPE html>:声明…...
数据结构与算法:归并排序
目录 归并排序的基本思想 归并排序的特性总结 代码 归并排序的非递归版 归并排序的基本思想 归并排序是建立在归并操作上的一种有效的排序算法。改算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列…...
Tweak Power:全方位电脑系统优化的高效工具
在日常使用电脑时,系统性能的下降、垃圾文件的堆积以及硬盘的老化等问题常常困扰着用户。为了提升电脑性能、优化系统运行,许多人会选择系统优化工具。然而,国内一些系统优化软件常常因为广告过多或功能冗杂而让人望而却步。此时,…...
stm32中分析UART中IDLE,RXNE,TC,TXE这些标志位的作用
下面将基于 STM32 标准库,结合之前提到的不同应用场景,给出使用 TXE、TC、IDLE 和 RXNE 标志位的代码示例及分析。 1. 连续数据发送(使用 TXE) 应用场景 向外部设备连续发送大量数据,如向显示屏发送显示数据、向传感…...
代码随想录算法训练营第十天,150.逆波兰表达式求值,239.滑动窗口最大值,347.前K个高频元素
今日内容:150.逆波兰表达式求值,239.滑动窗口最大值,347.前K个高频元素,栈与队列总结 心得:昨天休息了一天,栈与队列的题都比较典型,之前也是恶补过堆栈的知识,所以做起来相对kmp好一…...