自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(137)
  • 收藏
  • 关注

原创 基于TCP的Qt网络通信(QT网络上位机)

Qt网络通信原理:与文件操作类似。我们使用QTcpSocket这个类进行套接字通信的时候,不管我们是进行数据的读操作还是进行数据的写操作,操作的都不是网络中的数据而是本地的数据。假如通信的两端A和B,B给A发送数据,Qt框架会自动接收来自B的数据,Qt框架会给我们维护一块内存,A通过调用read方法读取的是这块内存里面的数据,也就是说这个内存数据是由Qt框架自动帮助我们接收过来的。同样调用write方法,也会先将数据写入到这块内存里,Qt框架检测到之后会帮助我们把这个数据发送到网络中。

2023-09-21 17:57:37 1594 1

原创 C++内存管理(3)——内存池

池化技术是一种降低频繁操作导致开销过大的方法,如内存池、线程池、进程池和对象池等。内存池(Memory Pool)是一种内存分配方式。通常我们习惯直接使用new、malloc等API申请内存,这样做的缺点在于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性能。

2023-09-07 00:41:07 637

原创 C++内存管理(2)new、delete详解

在C++中,内存管理是开发者的一项重要责任,也是容易出错的地方。开发者可能会遗忘释放已分配的内存,导致内存泄漏。重载new和delete可以帮助开发者更好地追踪和管理内存分配。通过在重载的new和delete操作符中插入日志或者调试语句,开发者可以监测和记录所有内存分配和释放的情况,从而检测内存泄漏。

2023-09-07 00:37:14 577

原创 C++智能指针之unique_ptr(保姆级教学)

独占式指针(专属所有权),同一时刻,只能有一个unique_ptr指向这个对象;当指针销毁,指向的对象也销毁;因此该指针不支持拷贝和赋值操作,也不存在引用计数。

2023-09-07 00:22:14 741

原创 C++智能指针之weak_ptr(保姆级教学)

weak_ptr:类模板,弱指针(弱引用计数)weak_ptr弱指针,不会控制影响对象的生命周期(不会改变对象的引用计数),shared_ptr释放指向对象时,是不会考虑weak_ptr是否指向该对象weak_ptr不是独立指针,不能单独操作所指向的资源(不配拥有对象),更不能指向一个新的空间;

2023-09-04 03:27:33 565

原创 C++智能指针之shared_ptr(保姆级教学)

共享式指针:多个指针可以同时指向同一个对象(共享所有权,协同工作),当最后一个指针被销毁或者指向其他对象时,这个对象会被释放;

2023-09-04 03:19:52 306

原创 C++内存管理介绍及智能指针

C++开发中大多问题都是由于内存泄漏导致,在C++11之前,和C语言一样只能通过人为来进行内存管理(new和delete),在C++11之后出现了智能指针new/delete必须成对出现,new[]/delete []必须成对出现人为的控制new/delete问题,无法杜绝内存泄漏。

2023-09-04 03:11:22 71

原创 内存管理之:内存空间分布和栈攻击(黑客常用攻击手段)

函数的定义通常存放在代码段中,而不是栈中。在程序运行时,代码段是用来存储程序的指令的内存区域,它通常是只读的。函数的定义在编译时就确定了,并且存放在代码段中,以便在程序执行过程中被调用和执行。栈则是用于存放局部变量、函数参数和临时数据等的内存区域,它在函数调用时动态分配和释放,具有先进后出的特性。

2023-09-04 03:05:24 372

原创 内存管理概述

为什么要学习内存管理?1. 高效性:内存管理能够帮助计算机更高效地利用内存。例如,当程序需要更多的内存时,操作系统会将它分配给程序,这样程序就可以存储更多的数据。如果内存没有被正确地管理,计算机可能会因为缺乏可用内存而变得非常慢。2. 安全性:内存管理也帮助防止了一些安全问题。例如,当一个程序尝试访问它没有权限访问的内存地址时,这可能会导致程序崩溃或者出现其他问题。良好的内存管理可以防止这种情况发生。3. 稳定性:学习内存管理也有助于了解如何防止和解决一些常见的程序错误,如缓冲区溢出、空指针引用等。

2023-09-04 02:55:57 242

原创 嵌入式开发学习必须要明白的一个问题!!!(嵌入式、单片机MCU开发为什么要学习RTOS)

OS的作用是解决软件和底层硬件之间的耦合度,避免应用层软件直接操作底层硬件。学习单片机裸机开发的时候,学习80C51和学习89C51以及IAP15,我们写程序时要操作IO所要调用的接口都是不一样的,这样学习和使用起来所要掌握的接口就特别多,也就特别复杂,记起来也特别麻烦:在80C51中我们需要先设置IO为普通IO模式还是外设模式,上拉还是下拉,然后才能操作IO;在89C51中,我们可以直接操作IO;而在IAP15中,我们又需要先开启相应的锁存器,才能操作IO。

2023-08-31 10:46:15 198 1

原创 SQLite数据库C_C++接口(保姆级API应用 1.4W字)(全网最详细介绍,学完必掌握)

三种查询方式总结回调函数查询内存开销小,但查询效率相对较低;全缓冲查询的查询效率高,但是内存消耗大;字节缓冲查询兼具查询效率和低开销。(优先使用第三种查询方法)sqlite实现C语言自定义函数封装由于数据库提供的API接口过于复杂,使用的过程顺序也很繁琐,所以对于原生态的API在实际工作开发中,会进行一层封装,减少调用传参,减少调用次数,增加代码可读性,提高开发效率。可封装如下:包括创建数据库、建表、插入数据、查询数据、删除数据

2023-08-29 03:13:52 2185 1

原创 06.sqlite3学习——DQL(数据查询)(全)

一旦主连接计算完成,外连接(OUTER JOIN)将从一个或两个表中任何未连接的行合并进来,外连接的列使用 NULL 值,将它们附加到结果表中。查询会把 table1 中的每一行与 table2 中的每一行进行比较,找到所有满足连接谓词的行的匹配对。由于交叉连接(CROSS JOIN)有可能产生非常大的表,使用时必须谨慎,只在适当的时候使用它们。交叉连接的操作,它们都返回被连接的两个表所有数据行的笛卡尔积,返回到的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

2023-08-28 03:25:21 2674

原创 05.sqlite3学习——DML(数据管理:插入、更新、删除)

数据操纵(DML):用于增、删、改数据作用:负责对数据库对象运行数据访问工作的指令集,以INSERT、UPDATE、DELETE三种指令为核心。

2023-08-27 03:15:38 1540

原创 04.sqlite3学习——DDL(数据定义:创建和删除表)

数据定义(DDL):用于用户定义、删除和修改数据模式。但在sqlite3中不存在用户这一概念,所以sqlite的DDL包括创建表、修改表和删除表

2023-08-27 03:12:27 1235

原创 03.sqlite3学习——数据类型

SQLite 数据类型一般数据采用固定的静态数据类型, 而 SQLite 采用的是动态数据类型, 会根据存入值自动判断SQLite 具有以下五种基本数据类型:1、 integer: 带符号的整型(最多 64 位) 2、 real: 8 字节表示的浮点类型3、 text: 字符类型, 支持多种编码(如 UTF-8、 UTF-16), 大小无限制4、 blob: 任意类型的数据, 大小无限制。 BLOB(binary large object)二进制大对象, 使用二进制保存数据5、 null:空值

2023-08-26 02:52:34 1669 1

原创 02.sqlite3学习——嵌入式数据库的基本要求和SQLite3的安装

SQLite 是一个开源的、 内嵌式的关系型数据库, 第一个版本诞生于 2000 年 5 月, 目前最高版本为 SQLite3。SQLite 特性:1、 零配置 5、 灵活2、 可移植 6、 自由的授权3、 紧凑 7、 可靠4、 简单 8、 易用

2023-08-26 02:44:36 960

原创 01.sqlite3学习——数据库概述

数据库可以理解为操作系统和应用层软件之间的中间件,目的是用于优化数据的存储。1、保存数据的方式:文件(缺点:无格式保存) 数据库(有格式的)2、数据库是什么?数据库是一种特殊的文件(有格式、不能直接读取,通过DBMS软件,输入SQL语句进行数据库读取)用户不能直接读取数据库文件里的内容,必须通过输入SQL语句控制DBMS软件,从而操作数据库文件。所以对于用户来说,学习数据库最重要的就是学习SQL语言。3.数据库分类关系型数据库主流的有Oracle、SQL Server和MySQL。

2023-08-26 02:42:02 567

原创 C++多线程编程——线程同步(保姆级-1.4W字)

线程同步是一种编程技术,它用于在多线程环境中确保多个线程能够正确、安全地共享和访问共享资源。线程同步的主要目的是防止数据竞争和不一致性,以及避免多个线程同时对同一数据进行修改或访问导致的问题。

2023-08-25 17:11:54 933

原创 C++多线程编程——thread线程创建与使用(2W字保姆级介绍)

同步执行:同步,是所有的操作都做完,才返回给用户结果异步执行:异步,不用等所有操作都做完,就响应用户请求处理耗时操作(数据库大量写入或者查询、文件下载、复杂计算)同步操作:所有的操作都做完,才返回给用户,这样用户在线等待的时间太长,给用户一种卡死了的感觉异步操作:即先响应用户请求然后慢慢去执行耗时操作,用户体验较好。

2023-08-25 04:04:46 2074

原创 线程池的概念及实现原理

线程池是一种使用多个线程来执行任务的机制,其中线程的数量是固定的。而使用线程池可以预先创建一组线程,重复利用这些线程,从而减少线程的创建和销毁开销,提高程序的效率。线程池的实现原理,假设现在有一个服务器,当服务器运行起来的时候会创建一个线程池,我们规定线程池里面有100个线程。而使用线程池可以将任务分配给池中的线程,避免了频繁的线程创建和销毁,减少了线程间的通信开销,从而提高了多线程程序的效率。服务器在接收到客户端的响应,将需要做的事情都放在任务队列里,线程池中的线程就实时去处理任务队列中的任务。

2023-08-25 03:38:42 476

原创 线程池的实现v2.0(可伸缩线程池)

对之前V1.0版本的静态线程池进行修改,添加了一个名为management_thread的管理线程,该线程会根据任务队列的任务数量动态管理线程池中的线程数量。管理线程会在每次循环中根据一定的条件增加或减少线程数量,然后休眠一段时间后继续检查。对于静态线程池,我们额外引入一个管理线程专门来管理线程池。当线程池中的线程数量不足够匹配任务队列里的任务量,就增加线程;如果线程数量超出了任务队列的任务量,就减少线程。具体可伸缩的条件由我们自己来规定,比如说待处理的任务数>正在工作的线程数*2,就增加线程;

2023-08-22 23:24:10 170

原创 线程池的实现全过程v1.0版本(手把手创建,看完必掌握!!!)

实现线程池首先要确定线程池有哪些属性(1)线程池中线程的数量(2)线程池中已工作的线程数量(3)任务队列(4)任务队列的大小(5)任务队列的锁还需要确定线程池的三种条件情况(1)任务队列为空时:线程池里的线程需要阻塞等待(2)任务队列为满:不能再新增任务(3)任务队列不为空:线程池里的线程处理任务

2023-08-22 02:27:28 229

原创 线程和进程同步互斥你真的掌握了吗?(同步互斥机制保姆级讲解与应用)

互斥:同一时间,只能一个任务(进程或线程)执行,谁先运行不确定。同步:同一时间,只能一个任务(进程或线程)执行,有顺序的运行。同步 是特殊的 互斥。

2023-08-20 21:38:45 537

原创 C++ STL常用算法(详解)

作为一门面向对象的编程语言,使用 C++ 编写程序有一个缺点,即随着代码面向对象程度的提高,其执行效率反而会降低。例如,经实验证明几乎在所有情况下,直接操作一个 double 类型变量的执行效率,要比操作一个含 double 类型成员属性的类对象更高。对于大多数读者来说,以上所说是很容易想通的,因为它符合我们对高级编程语言的认知。但本节要介绍的内容,一定程序上会打破这个认知。

2023-08-18 09:56:36 440

原创 C++ STL迭代器适配器(详解)

本节讲解了 3 种插入迭代器,虽然它们都可以借助重载的赋值运算符,实现向目标容器的指定位置插入新元素,但在实际应用中,它们通常和 copy() 函数连用,即作为 copy() 函数的第 3 个参数。有关 copy() 函数的具体用法,由于不是本节重点,这里不再赘述,后续章节会做详细讲解。

2023-08-18 09:53:55 541

原创 C++ STL容器适配器(详解)

前面讲解 priority_queue 容器适配器时,还遗留一个问题,即当 头文件提供的排序方式(std::less 和 std::greater)不再适用时,如何自定义一个满足需求的排序规则。首先,无论 priority_queue 中存储的是基础数据类型(int、double 等),还是 string 类对象或者自定义的类对象,都可以使用函数对象的方式自定义排序规则。//函数对象类class cmppublic://重载 () 运算符int main()while (!

2023-08-18 09:52:37 223

原创 C++ STL无序关联式容器(详解)

前面在讲解 unordered_map、unordered_multimap、unordered_set 以及 unordered_multiset 这 4 种无序关联式容器(哈希容器)时,遗留过一个共性问题,即如何给无序容器自定义一个哈希函数和比较规则?注意,虽然每种无序容器都指定了默认的 hash 哈希函数和 equal_to 比较规则,但它们仅适用于存储基本类型(比如 int、double、float、string 等)数据的无序容器。

2023-08-18 09:49:31 1156

原创 C++ STL关联式容器(详解)

前面在讲解如何创建 map、multimap、set 以及 multiset 容器时,遗留了一个问题,即如何自定义关联式容器中的排序规则?实际上,为关联式容器自定义排序规则的方法,已经在 《STL priority_queue自定义排序方法》一节中做了详细的讲解。换句话说,为 Priority_queue 容器适配器自定义排序规则的方法,同样适用于所有关联式容器。总的来说,为关联式容器自定义排序规则,有以下 2 种方法。在掌握此方法之前,读者必须对函数对象有基本的了解,可阅读《C++函数对象》一节。

2023-08-18 09:47:26 145

原创 C++ STL序列式容器(详解)

尽管不同容器对应着不同类别的迭代器,但这些迭代器有着较为统一的定义方式,具体分为 4 种,如表 1 所示。迭代器定义方式具体格式正向迭代器容器类名::iterator 迭代器名;常量正向迭代器容器类名::const_iterator 迭代器名;反向迭代器容器类名::reverse_iterator 迭代器名;常量反向迭代器容器类名::const_reverse_iterator 迭代器名;

2023-08-18 09:44:41 596

原创 相对于多进程,你真的知道为什么要使用多线程吗(C/C++多线程编程)

1、线程与进程的区别要能在面试时侃侃而谈至少五分钟。二者的区别详细可以参考以下博客,这是我觉得写得非常好的一篇博客:线程与进程,你真得理解了吗2、本文除了介绍线程与进程的区别,还包括了C语言中POSIX线程库的使用以及对线程的同步与互斥的复习,最后还引入了线程池的概念,之后将从C语言的多线程过度到C++线程池的实现。

2023-08-18 01:58:19 203

原创 RTT(RT-Thread)IIC设备

I2C(Inter Integrated Circuit)总线是 PHILIPS 公司开发的一种半双工、双向二线制同步串行总线。而我们之前的串口设备属于全双工通信,一般使用异步功能。双向数据线 SDA双向时钟线 SCL。

2023-08-17 10:56:26 481

原创 RTT(RT-Thread)ADC设备(RTT保姆级介绍)

ADC(Analog-to-Digital Converter) 指模数转换器。是指将连续变化的模拟信号转换为离散的数字信号的器件。

2023-08-17 10:53:13 821 1

原创 ADC电压采集(基于STM32hal库)(保姆级应用)

首先是比较基础实 用的单通道采集,实现开发板上电位器电压的采集,并通过串口打印至 PC 端串口调试助手。单 通道采集适用 AD 转换完成中断,在中断服务函数中读取数据,不使用 DMA 传输,在多通道采 集时才使用 DMA 传输。

2023-08-17 10:48:22 6958 17

原创 ADC电压采集(基于STM32hal库)(详细介绍)

以STM32F407ZGT6为例它拥有3个分辨率为12bit,最大转换速率为2.4M,有24个通道,三个ADC交替采集同一个通道可以达到的最大转换速率为7.2M。其中SPS指的是转换速率,表示1S内完成模拟量转换为数字量的次数,所以单次转换时间为1/24000000我们STM32所有ADC的外设都是逐次比较型或者也叫逐渐逼近型。ADC转换器就速度划分有三种,一种为积分型ADC,它的转换时间是毫秒级,属于低速ADC;逐次比较型ADC的转换时间是微秒级;

2023-08-17 10:40:44 4285

原创 RTT(RT-Thread)串口设备(RTT保姆级教程)

本章主要介绍串口设备在RT-Thread操作系统中应用层如何使用。关于串口设备的使用,我们只需要在应用层找到串口设备,然后去初始化,初始化完成以后就可以读写串口设备了。操作的方法在应用层,驱动是不需要我们去完成的,驱动已经在操作系统中提供了。

2023-08-14 16:10:00 3636 1

原创 RTT(RT-Thread)IO设备模型(RTT保姆级教程)

RT-Thread 提供了一套简单的 I/O 设备模型框架,如下图所示,它位于硬件和应用程序之间,共分成三层,从上到下分别是 I/O 设备管理层、设备驱动框架层、设备驱动层。简单设备的注册不经过设备驱动框架层,直接将设备注册到I/O设备管理器中。

2023-08-14 02:03:40 728

原创 C++文件类(整理自C语言中文网-全)

文件刚打开时,文件读指针指向文件的开头(如果以 ios::app 方式打开,则指向文件末尾),用 read() 方法读取 n 个字节,读指针指向的位置就向后移动 n 个字节。注意,和 put() 方法一样,操作系统在接收到 get() 方法的请求后,哪怕只读取一个字符,也会一次性从文件中将很多数据(通常至少是 512 个字节,因为硬盘的一个扇区是 512 B)读到一块内存空间中(可称为文件流输入缓冲区),这样当读取下一个字符时,就不需要再访问硬盘中的文件,直接从该缓冲区中读取即可。

2023-08-12 02:27:05 901

原创 RTT(RT-Thread)线程间同步(保姆级)

线程通过获取信号量来获得信号量资源实例,当信号量值大于零时,线程将获得信号量,并且相应的信号量值会减 1,如果信号量的值等于零,那么说明当前信号量资源实例不可用,申请该信号量的线程将根据time参数的情况选择直接返回、或挂起等待一段时间、或永久等待,直到其他线程或中断释放该信号量。此时线程2可以获取到信号量2,开始执行,执行完之后信号量2自动减1,然后释放信号量1,信号量1加1,然后线程1又开始执行了。那么不管是线程1还是线程2,谁先执行临界区,都会先获取信号量,然后信号量value减1,变成0;

2023-08-12 02:23:12 568 4

原创 C++封装思想之二:友元机制和运算符重载(1W字详解)

友元的作用:类的非成员函数可以直接访问类的非公有成员变量,省去函数的调用和访回过程。从而提高了程序的运行效率(即减少了类型和安全性检查及调用的时间开销)运算符重载的作用可以提高程序的可读性体现了C++的可扩充性运算符重载仅仅只是语法上的方便,它是另一种函数调用的方式运算符重载,本质上是函数重载

2023-08-04 17:15:05 655

原创 C++封装思想之一:封装(1.8W字详解)

通过类的封装,实现对外提供接口,屏蔽数据,对内开放数据,保证代码的独立性(内聚性),提高代码的维护性C++的封装:class 封装的本质,在于将数据和行为,绑定在一起然后通过对象来完成操作。性能优化更方便性能:地址跳转访问(内部:更复杂的访问机制)我们在编写栈类的时候,使用自定义的init函数来实现栈的初始化,但是我们在人为操作的时候可能会忘记初始化。因此C++引入了构造函数。构造函数的定义及特点注意如果编写了自定义有参构造函数,会自动屏蔽默认构造函数,导致默认构造函数无法调用。可以将有参构造函数的参数设置

2023-08-04 01:31:33 843

蓝桥杯全模块代码+部分国赛省赛程序

蓝桥杯全模块代码+部分国赛省赛程序

2023-06-29

2023年蓝桥杯单片机资源数据包(最新)+赛点数据包修改注意事项

2023年蓝桥杯单片机资源数据包(最新)+赛点数据包修改注意事项

2023-06-29

单片机课设:基于IAP15F2K61S2的数字测量仪表设计(程序+课程设计报告+演示视频)

单片机课设:基于IAP15F2K61S2的数字测量仪表设计(程序+课程设计报告+演示视频),提供给正在参加蓝桥杯同时需要做单片机课设的同学。本工程是根据蓝桥杯单片机第十届国赛题进行进一步更改的,在原有的基础上增加了DS1302时钟显示模块。共包括十一个模块:DS1302时钟、DS18B20温度传感器、AT24C02存储器、PCF8491模数转换、NE555脉冲讯号输出、八位八段数码管、独立按键、继电器、蜂鸣器、LED灯

2023-06-29

SmartRF04EB+CC2530 ZigBee Dongle

SmartRF04EB+CC2530 ZigBee Dongle

2023-06-29

C语言歌词解析项目,建议Linux操作系统下运行

C语言歌词解析项目,在Linux Ubuntu开发环境编写运行 功能包括:lrc格式歌词的文件读取、解析、链表创建等,同时在屏幕上将解析出的歌词进行实时显示 主要使用了文件IO、链表和多进程,主要涉及到了双向链表的使用,对正在学习数据结构的同学很有参考价值。 涉及的C语言知识点有:基本数据类型、运算符及控制语句、数组 、结构体、链表、函数、指针、文件、内存等等,比较重要的是字符串操作函数如字符串切割函数strtok、字符串解/组包函数sscanf/sprintf函数。

2023-06-25

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除