我最近在写stm32单片机的程序在写的过程中发现自己编写函数名、类型名、宏定义的时候自己编写的代码总是有点别扭主要原因就是宏定义、函数名、全局变量名、类型名、局部变量名、枚举值等这些元素的命名上有问题我查阅了uboot、linux内核源码、以及我以前同事编写的代码积累了这些元素在命名方面的一些共性现在记录下来。1宏定义的宏名尽量用三个大写单词以内下划线方式实现。#define KEXEC_ARM_ATAGS_OFFSET 0x1000 #define KEXEC_ARM_ZIMAGE_OFFSET 0x80002枚举类型定义中的枚举值尽量用三个大写单词加下划线方式实现。3枚举类型名尽量用三个小写单词加下划线方式实现uboot和linux内核源码中习惯用小写例如enum km_type { KM_BOUNCE_READ, KM_SKB_SUNRPC_DATA, KM_SKB_DATA_SOFTIRQ, KM_USER0, KM_USER1, KM_BIO_SRC_IRQ, KM_BIO_DST_IRQ, KM_PTE0, KM_PTE1, KM_IRQ0, KM_IRQ1, KM_SOFTIRQ0, KM_SOFTIRQ1, KM_L1_CACHE, KM_L2_CACHE, KM_KDB, KM_TYPE_NR };4结构体、共用体类型名和成员变量名尽量用三个小写单词加下划线方式实现内部成员变量也尽量用三个小写单词加下划线方式实现。struct root_device { struct device dev; struct module *owner; };5函数名尽量用三个小写单词加下划线方式实现如下所示。static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct device_attribute *dev_attr to_dev_attr(attr); struct device *dev to_dev(kobj); ssize_t ret -EIO; if (dev_attr-show) ret dev_attr-show(dev, dev_attr, buf); if (ret (ssize_t)PAGE_SIZE) { print_symbol(dev_attr_show: %s returned bad count\n, (unsigned long)dev_attr-show); } return ret; }6全局变量名尽力用三个小写单词加下划线方式实现如下所示。static const struct sysfs_ops dev_sysfs_ops { .show dev_attr_show, .store dev_attr_store, };7函数内部定义的参数或者临时栈变量尽量使用三个小写单词加下划线方式实现。这里容易犯的一个错误是参数名或者临时栈变量名中包含了函数名中已经有的单词导致参数名或者临时栈变量名特别长之所以会犯这样的错误是因为“编写程序的时候错误下意识以为临时栈变量的作用域也为全局因此保证起参数或者临时栈变量名字的时候不能重名”这其实是错误的。我们都知道函数内部的参数或者临时栈变量的作用域只局限在函数内部因此就算名字重复了也是没有任何影响的也可以这样理解函数名是唯一的前缀就算函数内部参数和变量名字重复了整体看来也能做到命名不重复。为了缩短参数或者临时栈变量名的长度采用比较有效的办法就是在参数名或者临时栈变量名中将函数名中已经表明的英文单词给省略掉。8if条件判断中的反逻辑和正逻辑方式三编写的函数也就是返回值为某个错误状态码在父函数中经过传参和函数调用后直接或间接利用返回值参与逻辑运算最常见的就是作为if条件判断的表达式。表达式往往采用反逻辑与OK、SUCCESS等值做比较也就是使用不等于!OK、SUCCESS等数值这样做的好处就是采用防御思维编程卫语句可以降低代码嵌套级数。另外值得说明的是错误状态码中往往只有唯一的一个成功值SUCCESSOK值其他错误状态可能有多个因此与这个唯一的成功值SUCCESS、OK值参与反逻辑或者正逻辑运算而不是与其他错误状态码进行比较逻辑运算是比较简洁的方式。当然返回值使用正逻辑与唯一的OK或者SUCCESS值进行比较也是有的就是没有以防御卫语句编写方式编写还与个人编写代码习惯有关。9if-else二分法。在编程中经常使用二分法。也就只有2种情况真假、成功失败YES/NO等二分法编写代码是最简单的因为情况越多需要处理的情况代码也越多如果发生嵌套情况越多写代码难度越大。而且条件判断使用最多的就是if()触发判断和if-else二分法条件判断。这也与我以前以前文章中论述错误状态码只需要两种状态OK/ERROR、SUCCESS/FAILE、YES/NO而不需要细分错误状态码保持一致。(10) 什么是应用层程序。所谓应用层程序就是模块与模块之间的资源相关调用完成业务逻辑功能。这里的模块资源包括全局变量API函数公共宏定义、公共数据类型定义。在应用层往往发生模块A的函数调用模块B、C、D等模块的资源其实就是驱动层的资源完成应用层资源建立也就是创建私有/公共数据类型、私有/公共全局变量、私有/公共API函数私有/公共宏定义等。从宏观上看应用层程序编写与驱动层程序编写创建模块的各个资源本质上没有区别但是应用层程序的内容与业务逻辑相关并且会交叉调用驱动层的相关资源这也是应用层比驱动层负载的地方。11函数的复用性将相似代码段定义成一个函数关键是不同变量定义成参数可以减少代码行数节省代码段大小。最近我在写stm32项目程序的业务应用层程序其中使用了一个阶梯判断语句switch-case-break-default语句用于判断接收命令行命令ID的具体分析其中有几个命令ID的处理是非常相似的只有很少一部分语句不同。当我进行程序优化的时候感觉完全可以将这些命令ID的相似处理包含写成一个含参函数参数对应处理不同部分。这样函数在被调用时传递不同参数对应上述代码中不同部分剩余部分相同。返回值选为void也就是不参与父函数任何运算。static void app_USB5Vx_set(USB5V_PWR_X x) { if (cmd_rxbuf[4] 0x00) USB5Vx_power_set(x, USB5V_PWR_OFF); else USB5Vx_power_set(x, USB5V_PWR_ON); } case CMD_USB5V_1: /**0x55 0xAA 0x03 CMD_USB5V_1 0xXX[4] 0x00 0x0A */ // 第一路5V供电配置 app_USB5Vx_set(USB5V_PWR1); // 回传命令 cmd_send(cmd_rxbuf, cmd_rxlen); break; case CMD_USB5V_2: /**0x55 0xAA 0x03 CMD_USB5V_2 0xXX 0x00 0x0A */ // 第二路5V供电配置 app_USB5Vx_set(USB5V_PWR2); // 回传命令 cmd_send(cmd_rxbuf, cmd_rxlen); break; case CMD_USB5V_3: /**0x55 0xAA 0x03 CMD_USB5V_3 0xXX 0x00 0x0A */ // 第三路5V供电配置 app_USB5Vx_set(USB5V_PWR3); // 回传命令 cmd_send(cmd_rxbuf, cmd_rxlen); break;例如上述代码中几个命令ID的处理就是函数体的内容不同之处主要是函数体内函数USB5Vx_power_set()的第一个参数不同因此将这个不同的变量定义成参数变量返回值为void这样定义成一个函数函数调用的时候分别传递不同参数但是都调用同一段代码这样可以节省代码段的大小也体现了函数的复用性。后面如果发现有新共性继续补充。
企业数字化 ERP 产品动态
相关推荐
华旭金卡身份证阅读器JS调用实战:绕过ActiveX兼容断层 简介:本资源是一套面向Web开发者与前端工程师的华旭金卡身份证阅读器JS集成实战方案,解决在网页端快速接入国产二代证读卡设备的核心难题,适用于政务系统、银行开户、实名认证等需现场身份核验的业务场景。压缩包共31个文件,含6个… · 2026/9/25 18:14:16
仿网易云年度听歌报告:纯前端源码包与滚动动画实战 简介:这是一套可直接运行的网页版年度音乐报告前端模板,面向具备基础HTML/CSS/JS能力、希望快速搭建数据可视化报告页的开发者与设计爱好者,解决从零复刻网易云年度听歌报告交互与视觉风格的成本问题。资源包共25个文件,约825KB&a… · 2026/9/25 18:14:16
Substrate底层抽象思维:从区块链框架到通用基础设施的工程实践 1. 从“substrate”这个词说起:它到底指什么第一次看到“substrate”这个词,很多人会愣一下。它在不同圈子里指向完全不同的东西:做区块链的人第一反应是 Parity 那套区块链框架,做材料的人想到的是衬底、基材,做生物实… · 2026/9/25 18:14:10
RAG工程优化实战:Chunking、混合检索与Rerank核心策略 1. 为什么 RAG 工程优化绕不开 Chunking、混合检索和 RerankRAG 这个词现在已经被说烂了,但真正在生产环境里跑过知识库问答的人都知道,把文档塞进向量库、检索出 Top-K 丢给大模型,这套最朴素的流程在实际业务里几乎不可用。问题出在哪&… · 2026/9/25 19:41:13
Backtrader 学习笔记:从会写 Python 到能做可信回测(八) Backtrader 策略实战:从一个想法到一份完整回测
学完基础概念后,最好的练习不是继续背 API,而是完整做一个小策略。
今天用“双均线交叉”演示一遍:
提出规则
→ 写代码
→ 加入成本
→ 分析结果
→ 检查问题一、先把策略说成人话… · 2026/9/25 19:41:06
幂等设计(Idempotence) 幂等设计(Idempotence)详解
TL;DR(30 秒速览)
幂等定义:执行一次和执行多次,对状态效果相同。为什么需要:发送端无法区分请求丢还是响应丢,只能重试。Ymodem 两处幂等点:… · 2026/9/25 19:41:06
桌面仪表盘全栈实战:Go 后端 + SSE 卡片状态看板 桌面仪表盘这个东西,我前后折腾过四五轮,从最早拿现成的监控面板凑合,到后来自己写脚本往终端里刷,再到干脆动手做一个完整的全栈项目。每一次都解决了一部分问题,又冒出来新的别扭。直到把 Status Deck 这个项目立起来… · 2026/9/25 19:41:00
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37