C++ 面向对象_0
C++ 结构体--向面向对象的过渡
C++ 中的结构体是从 C 语言继承而来,允许程序员将相关的数据组合在一起形成一个抽象数据类型,同时拓展了面向对象的设计思想
声明(declaration)和定义(definition)
声明是向编译器引入一个标识符(如变量、函数、类、结构体等)的名称和类型,但不分配存储空间或提供完整实现。声明的主要目的是告诉编译器"这个东西存在",以便编译器在遇到该标识符的使用时能够知道它的类型和基本特性。在声明时,对于变量来讲并不提供分配内存的操作,对于函数来讲并不提供具体的实现,只...
总结 C++ 泛型算法_0
泛型算法
泛型算法是 C++ 标准库中的一个强大特性,它为程序员提供了处理各种数据类型的通用工具。
什么是泛型算法?
泛型算法可以理解为泛化各种类型的通用操作逻辑,是一组独立于特定数据类型和数据结构的算法,是操作各种数据类型的通用实现逻辑,可以操作不同类型的数据容器。这些算法被设计为可以处理各种数据类型,而不需要为每种类型编写专门的代码。C++ 标准模板库(STL)中的泛型算法主要在 <algorithm>、<numeric>和 <functional>头文件中定义。
泛型算法的核心特定是通过模板技术实现对...
总结 C++ 容器
关联容器
Set
set 是 C++ 标准模板库(STL)中的一种关联容器,定义在 <set> 头文件中。它是一个有序的集合,用于存储唯一元素,即不允许重复值。set 的底层实现通常基于红黑树(一种自平衡二叉搜索树),这使得它能够高效地支持插入、删除和查找操作,同时保持元素的有序性(默认按升序排列)。
set 的 key 是模板 T 对应的类型对象,value 是 set 中是否存在这个类型的对象,即 true 或者 false。
set 具有唯一性,每个对象在 set 中只出现一次,重复出现的对象会被自...
总结 C++ 动态内存管理_1
unique_ptr
unique_ptr 是 C++11 引入的一种智能指针(一种抽象数据类型),定义在 <memory> 头文件中。它是标准库提供的一种工具,用于管理动态分配的内存,确保该类型的对象维护的指针拥有内存的独占所有权(unique ownership)。换句话说,一个 unique_ptr 类型的对象维护的指针在整个程序的生命周期内只有一个,这不同于 shared_ptr 对象维护的指针可以是同一个,即被共享。当 unique_ptr 对象被销毁(例如离开作用域)时,它所管理的动态内存会自动...
错误
wifi一直连接不上咋回事
总结 C++ 动态内存管理_0
C++ 动态内存管理总结
为什么强烈不建议重载系统自身的 operator new 和 operator delete 行为
在 C++ 中,new 和 delete 是内存分配和释放的核心操作,默认由标准库提供行为实现。这些行为经过了高度优化,能够很好地与操作系统、编译器以及运行时环境协同工作,高度耦合。虽然允许开发者通过重载全局的 operator new 和 operator delete 来自定义内存管理行为,但这会带来很多问题。比如,破坏标准库的组件,性能问题,调试和维护难度,与第三方库的兼容性问...
总结 C++ 数组遍历
总结 C++ 数组遍历
C++ 中求数组元素个数的方式
1. 使用 sizeof 运算符
sizeof(array) / sizeof(array[0])
sizeof(array) 返回数组总的字节数。
sizeof(array[0]) 返回数组单个元素的字节数。
将总字节数除以单个元素的字节数,即可得到数组的元素个数。
int arr[5];
std::cout << sizeof(arr) / sizeof(arr[0]); // 输出 5
优点:简单、直接,适用于固定大小的数组。
缺...
理解 C++ 自动类型推导·:decltype
decltype
博主前面引入了 auto 的自动类型推导,decltype() 是 C++11 引入的另一个类型推导工具,用于获取表达式或变量的类型。它可以在编译期静态地分析表达式的类型并返回对应的类型定义,而不会实际执行表达式。
简单来说,decltype() 的作用是:评估一个表达式的类型并返回该类型。
2. 为什么需要 decltype()?
有时候类型过于复杂,例如标准库容器中的迭代器类型;decltype() 可以使代码更简洁。
在模板代码中,需要确定某些表达式的返回类型或变量的类型。
结合...
理解 C++ 自动类型推导:auto
C++ 中的自动类型推导:auto 全面总结
auto 是 C++11 引入的关键字,用于自动类型推导。它让编译器根据变量的初始化表达式来决定变量的类型,而不需要程序员显式指定类型。
为什么需要 auto?
引入 auto 关键字有几个重要原因:
简化复杂类型声明:在现代 C++ 中,类型名称可能非常冗长,特别是使用模板时。例如:
std::map<std::string, std::vector<int>>::iterator it = myMap.begin();
使用 auto 后:
auto ...
理解 C++ 常量和常量表达式
理解 C/C++ 常量与常量表达式
博主之前有篇文章讨论了 C/C++ 程序在被 gnu 链接器 ld 链接后的内存布局,内存通常被分为几个主要区域:
代码段(Text/Code Segment):存储程序的可执行指令。
数据段(Data Segment):
初始化数据段:存储已初始化的全局变量和静态变量。
未初始化数据段(BSS):存储未初始化的全局变量和静态变量。
堆(Heap):用于动态内存分配。
栈(Stack):用于存储栈帧。
以下面这段代码为例,在 main 函数内部定义一个局部常量:...
C/C++ 内存布局
C/C++ 程序的内存布局 (Memory Layout In C/C++)
上图展示了程序中内存布局(Memory Layout)的关键构成(Key Components),其中黄色部分称为动态内存区(Dynamic memory area),其中包括堆内存(Heap)和栈内存(Stake),下面三个不同颜色的部分我们各称为一个段(Segment),整个程序有自己的虚拟内存地址空间,由操作系统映射到实际的物理内存地址,从程序自身的角度看它认为自己在运行时是占用连续的一整块内存空间,至于物理内存如何存储运...
理解 C++ 引用的实现
理解 C++ 的引用实现
在 C++ 中,引用(reference)是一种特殊的机制,它允许你为一个已有的变量创建一个 “别名(alias)”。通过引用,你可以直接操作原始变量,而不是创建一个新的副本。引用本质上是一个变量的 “第二个名字”,它与原始变量绑定在一起,任何对引用的操作都会直接影响原始变量。
引用通过在变量声明时使用 & 符号来定义。定义引用时,必须立即初始化,并且它必须绑定到一个已存在的变量上。引用本身不是一个独立的实体,而是直接指向它所引用的变量。
语法示例:
int a = 10; ...
libmodbus 源码分析_1
unit-test-server.c
我们接着从源码的单元测试服务器(从机)libmodbus-3.1.10\tests\unit-test-server.c 的 main 函数开始分析源码执行流和所用的数据结构。推进学习百问网提供的全场景工业互联设备管理系统解决方案,其中有对 libmodbus 源码详细的视频课程讲解。
可以看到对于从机,初始化时的操作是类似的
use_backend = RTU; /* 设置传输模式为 RTU */
ip_or_devi...
libmodbus 源码分析_0
libmodbus源码分析
libmodbus 是一个免费的跨平台支持 RTU 和 TCP 的 Modbus 库,遵循 LGPL V2.1+ 协议。libmodbus 支持 Linux、Mac Os X、FreeBSD、QNX 和 Windows 等操作系统。libmodbus 可以向符合 Modbus 协议的设备发送和接收数据,并支持通过串口或者 TCP 网络进行连接。
如何下载、使用和移植libmodbus请参考百问网提供的全场景工业互联设备管理系统解决方案。
各文件作用如下:
win32: 定义在W...
Modbus 协议_1
6 功能码描述
本篇简要解读几个 MODBUS 应用协议规范 中的功能码和作用,更多详细内容参考协议手册。
百问网提供的全场景工业互联设备管理系统解决方案,其中有对 Modbus 详细的视频课程讲解和功能案例测试。
6.1 01 (0x01) 读取线圈 (Read Coils)
此功能码用于从远程设备读取 1 到 2000 个连续的线圈状态。请求 PDU(协议数据单元)指定起始地址,即第一个指定线圈的地址,以及线圈的数量。在 PDU 中,线圈从零开始寻址。因此,编号为 1 到 16 的线圈在 PDU 中的寻...
Modbus 协议_0
MODBUS 应用协议规范
本篇详解 Modbus 组织 提供的 MODBUS 应用协议规范-V1.1b3,感兴趣的朋友可以移步 Modbus 组织官网 详细了解。
推荐学习由百问网提供的全场景工业互联设备管理系统解决方案,其中有对 Modbus 详细的视频课程讲解和案例测试。
1. 引言
1.1 本文档的范围
MODBUS 是一种应用层消息协议,位于 OSI 模型的第七层[参考],提供在不同类型的总线或网络上连接的设备之间的客户端/服务器通信。
自 1979 年以来,MODBUS 已成为工业界的串行事实...
USB 设备编程_2
USB 设备类型之 CDC (Communication Device Class)
CDC 概述
CDC(Communication Device Class,通信设备类)是 USB 设备类规范中专门用于 USB 通信设备的一类。其主要目的是为各种需要通信功能的设备(如调制解调器、网络适配器、虚拟串口设备等)提供一个统一、标准化的接口,使得主机能够识别并正确地与这些设备进行数据交换和控制。CDC 类中不仅定义了数据传输的基本机制,还包括一些特定的控制和管理命令,确保设备能按照既定的协议工作。
根据 CDC...
USB 设备编程_1
描述符相关源码分析
本章分析百问网提供的全场景工业互联设备管理系统解决方案中有关 USB 设备编程,应用层中关于 USB 设备描述符相关源码进行分析。
ux_device_descriptors.h 源文件分析
重点分析头文件中,关于 USB 中各种设备描述符的定义。
USB 复合设备类型枚举
typedef enum
{
CLASS_TYPE_NONE = 0,
CLASS_TYPE_HID = 1,
CLASS_TYPE_CDC_ACM = 2,
CLASS_TYPE...
USB 设备编程_0
USB 设备编程
本篇将详细描述如何通过在嵌入式设备上(以百问网提供的全场景工业互联设备管理系统解决方案中所使用的 STM32H5 系列开发板为例)实现一个 USB 虚拟串口(Virtual COM Port,VCP),从而让嵌入式系统能够通过 USB 接口与计算机或其他主机设备进行串行通信。
本篇的目标是在大概理解 USB 体系结构和协议的基础上通过移植 USBX 并编写驱动程序来实现 虚拟串口 来进一步学习和理解 USB 在实际开发中的应用。
USBX 组件
推荐学习由百问网提供的全场景工业互联设备管理...
MAX13487E 半双工 RS-485/RS-422 收发器详解
MAX13487E 半双工 RS-485/RS-422 收发器详解
RS-485 是一种电气标准(物理层的通信协议)详解参阅RS-485标准详解
本篇以百问网提供的全场景工业互联设备管理系统解决方案所使用的 RS-485 收发器(MAX13487EESA+)为例详解实际的 RS-485 收发器使用案例。
RS-485 收发器
RS-485 收发器的主要功能是实现对 RS-485 总线的发送和接收操作,负责信号的转换和传输。
将数据从微控制器、计算机等设备的 TTL 电平(低电平和高电平)转换为 RS-485...