书摘:C 嵌入式系统设计模式 04

2024-01-07 01:52

本文主要是介绍书摘:C 嵌入式系统设计模式 04,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本书的原著为:《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》,讲解的是嵌入式系统设计模式,是一本不可多得的好书。

本系列描述我对书中内容的理解。

  1. 实现类的最简单方法是使用文件作为封装边界:公共变量和函数声明在 .h 文件中,函数实现和私有变量在 .c 文件中。
  2. 一种更灵活的方法是使用文件中的结构体表示类。与结构体位于同一文件中的函数定义类的操作。为了确保函数能够访问正确的对象数据,我们需要传入一个 me 指针。
  3. 在结构体本身中嵌入函数指针,这可以实现子类的继承。

以上就是本书中用 C 语言模拟类的三种方法。这三种方法复杂度逐渐增加,不要因为第一种方法简单就认为它用处不大,不是这样的。实际上,这三种方法在 C 编程中都十分常用,尤其在编写模块化程序时,它们甚至与类无关,只是恰好可以模拟类的行为。

这三种方法都以文件作为封装边界,只是后两种没有明确指出。封装的目的在于降低整体复杂度。在编程界,封装是一种重要的思想。《UNIX 哲学》告诉我们:“要编制复杂软件而又不至于一败涂地的唯一方法就是降低其整体复杂度——用清晰的接口把若干简单的模块组合成一个复杂软件。如此一来,多数问题只会局限于某个局部,那么就还有希望对局部进行改动而不至牵动全身。”

第 1 种方法中将公共变量声明在 .h 文件,我自己并不认同这种方法,我推荐使用函数封装全局变量,对外只提供函数,这实际上对外隐藏了数据,因此封装性更好。此外,这样更灵活,有利于以后的扩展。这怎么理解呢?用函数封装一下后,函数能做的事情,比使用变量要多的多,你可以在函数中轻松的修改或扩展功能,而无需修改使用该函数(原来这里是变量)的所有代码

许久之前,我认为这样影响效率。直到我意识到,我手上的这颗 M3 芯片,1ms 可以执行110000 条单周期指令,或者换句话,1ms 可以执行 220KB 的代码。现代的单片机速度今非昔比了,效率固然重要,但可扩展性有些时候更重要。何况,对现代的编译器来说,用函数封装变量,真的会影响效率吗?还真不一定。

对于第一种方法,我并不赞同将公共变量声明在 .h 文件中。我主张使用函数来封装全局变量,仅对外提供函数接口。这样能更好地隐藏数据,从而提高封装性。此外,这种做法更灵活,有利于未来的扩展。这怎么理解呢?使用函数封装后,函数能做的事情,比变量要多的多。你可以在函数内部轻松地修改或扩展功能,而无需修改使用该函数的所有代码。

许久之前,我认为这样影响效率。直到我意识到,我手上的这颗 M3 芯片,1ms 可以执行110000 条单周期指令,或者换句话,1ms 可以执行 220KB 的代码。时至今日,单片机的速度今非昔比了!效率固然重要,但可扩展性有些时候更重要。何况,对现代的编译器来说,用函数封装变量,真的会影响效率吗?还真不一定。

在标准 C 编程中,复杂的算法仍然可以嵌入类中,但这些类通常是 单例(singletons),这意味着应用程序中只有一个类的 实例(instance)。例如,单例 Printer 类可能具有 currentPrinter 等变量和 print() 等操作,但应用程序只有一个实例。即使只有一个实例在运行,将类使用的数据与作用于该数据上的操作封装在一起仍然是有益的。在其他情况下,通常以数据为中心(与以算法或服务为中心相反)的类会有多个实例。

这段话描述了一些设计模式:单例和多实例。即使不采用面向对象的思想,了解这些知识也是非常重要的。在模块化设计中,我们经常会遇到单一实例模块(single-instance module)和多实例模块(multiple-instance module),它们在封装模块的数据方式上,有着本质的区别。

对于单一实例模块,其数据以静态形式存在于 .c 文件中,并通过 .h 文件中提供的接口来访问这些数据。由于使用了静态数据,这种方法适用于只需要处理一套数据的模块。这种方式简单,简单意味着可靠。

当一个模块要为不同的客户管理不同的数据时,要使用多实例模块。在多实例模块中,必须要初始化数据结构并把它传回给客户以保持其上下文。比如一个环形缓冲区模块。

在面向对象编程中,单例是一种设计模式,其中确保一个类只有一个实例,并提供一个全局访问点来访问该实例。假如 Printer 类是一个单例,这意味着在整个应用程序中,只有一个 Printer 类的实例存在。

类生来具有一些特殊的操作:构造函数和析构函数。

在面向对象编程中,构造函数析构函数 是两个非常重要的成员函数:

  1. 构造函数在创建对象时自动调用,主要作用是初始化对象的成员变量和其他资源。在本书中,构造函数命名为 Xxxx_Init()。此外,在本书中,创建对象的函数命名为 Xxxx_Create(),在这个函数中调用构造函数 Xxxx_Init()
  2. 析构函数在销毁对象时自动调用,主要作用是释放对象所占用的资源,例如内存、文件句柄等,还可以执行一些清理操作,例如关闭文件、断开网络连接等。在本书中,析构函数命名为 Xxxx_Cleanup() 。此外,在本书中,销毁对象的函数命名为 Xxxx_Destroy(),在这个函数中调用析构函数 Xxxx_Cleanup()






读后有收获,资助博主养娃 - 千金难买知识,但可以买好多奶粉 (〃‘▽’〃)
千金难买知识,但可以买好多奶粉

这篇关于书摘:C 嵌入式系统设计模式 04的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/578352

相关文章

Linux查询服务器系统版本号的多种方法

《Linux查询服务器系统版本号的多种方法》在Linux系统管理和维护工作中,了解当前操作系统的版本信息是最基础也是最重要的操作之一,系统版本不仅关系到软件兼容性、安全更新策略,还直接影响到故障排查和... 目录一、引言:系统版本查询的重要性二、基础命令解析:cat /etc/Centos-release详

更改linux系统的默认Python版本方式

《更改linux系统的默认Python版本方式》通过删除原Python软链接并创建指向python3.6的新链接,可切换系统默认Python版本,需注意版本冲突、环境混乱及维护问题,建议使用pyenv... 目录更改系统的默认python版本软链接软链接的特点创建软链接的命令使用场景注意事项总结更改系统的默

在Linux系统上连接GitHub的方法步骤(适用2025年)

《在Linux系统上连接GitHub的方法步骤(适用2025年)》在2025年,使用Linux系统连接GitHub的推荐方式是通过SSH(SecureShell)协议进行身份验证,这种方式不仅安全,还... 目录步骤一:检查并安装 Git步骤二:生成 SSH 密钥步骤三:将 SSH 公钥添加到 github

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs