当前位置: 首页 > news >正文

嵌入式应用开发之代码整洁之道

        前言:本系列教程旨在如何将自己的代码写的整洁,同时也希望小伙伴们懂如何把代码写脏,以备不时之需,同时本系列参考 正点原子 , C++代码整洁之道,编写可读的代码艺术。

#好的代码的特点

          好的代码应该都有着几条特性,可读性高(根据函数命名就知道这个函数是干啥的),简单(没有复杂的变量英文名,大量调用库中封装函数)。

        方便维护(别人在你的代码上加功能好加,好上手),好移植(头文件大量书写宏定义  移植只需要改宏定义引脚即可),函数功能单一精简(函数定义几百行,参数很多,永远 没有 十几行函数代码的好理解)。

        调用函数库统一,(没有二次封装函数,没有带位操作跟库函数混着用),没有带位操作,(程序中统一调用库函数)带位操作确实快,现对于库函数,但是不好上手,没有重新编写函数(如果放着现有的库函数不用,重新赋值寄存器,写新函数,还没有根据功能命名)

        上述的这些都是,好的代码的特点,接下来将从,每个类型的变量书写规范开始讲解。

#函数的命名

        函数的命名,应该把信息或者注释装进命名里面,同时每个单词使用下划线  "_" 进行连接,,让在读函数命名的同时,就知道你这个函数是什么作用,什么功能,大致看一下函数体,就行了。

void SPI_GPIO_Init(void);

        这个函数名,即使不看函数体,也知道这个函数用来将  SPI通信用到的GPIO 初始化,那么如何将代码命名进行规范化。

        翻译命名:将这个函数的功能,翻译成英文在命名里面加入英文的缩写,去表示。

        外设命名:如果用到对应的外设,可以在命名中加入所用到的外设。

        寄存器命名:这个函数里面用到了什么寄存器,什么参数也能写到函数名里面。

 #代码注释写给别人看也写给自己看

        代码注释不仅仅可以,用来解释这一行代码什么意思做了什么,最重要的是让读你代码的人知道你的写码思想,你此时在关联什么,你在想什么,你要用这些代码去干什么,完成什么,

        当自己编写代码的时候,肯定知道自己写这些代码是为了完成什么功能,去怎么应用在需求上,别人读代码,只有眼前每行代码的作用,注释在这个时候,可以是思维,可以是目的。可以是关联应用

#什么不需要注释

        注释在程序中,并不是越多越好的,大量的注释无关紧要的地方,会造成浪费时间,去阅读这些注释,占用屏幕空间,这些注释相对来说是没有价值的。

void Usart_GPIO_Init(void){GPIO_InitTypeDef GPIO_InitStructure;//声明结构体变量	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//开启时钟	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);//开启复用功能GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);GPIO_StructInit(&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin           = GPIO_Pin_9;//TX引脚GPIO_InitStructure.GPIO_Mode          = GPIO_Mode_AF;//IO口用作串口引脚要配置复用模式GPIO_InitStructure.GPIO_Speed         = GPIO_Speed_100MHz;//选择速度GPIO_InitStructure.GPIO_OType         = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_PuPd          = GPIO_PuPd_UP;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_StructInit(&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin           = GPIO_Pin_10;//RX引脚GPIO_InitStructure.GPIO_Mode          = GPIO_Mode_AF;//IO口用作串口引脚要配置复用模式GPIO_InitStructure.GPIO_Speed         = GPIO_Speed_100MHz;//选择速度GPIO_InitStructure.GPIO_OType         = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd          = GPIO_PuPd_UP;//推挽输出GPIO_Init(GPIOA,&GPIO_InitStructure);
}

        上述这些注释是没有价值的,为什么,因为没有提供额外的信息,这些作用能从函数里面读出来,就可以不用去加,写这么多注释是会影响效率的。

                                   总结:不要为代码本身能读出来的信息写注释

        同时不要为了写注释,而去注释,总有小伙伴认为,一定要写注释,为了写注释去写注释,从而忽略了写注释本身的作用,写注释是为了更好的理解工程,而不是写没有意义的注释,浪费读你注释的人的时间。

#什么需要注释

        注释本身就是一种信息,这种信息不是关于函数功能的信息,这些信息可以加入见解,可以使各种有关经验之谈,可以是别人不知道代码的瑕疵,缺陷,也可以是站在读你代码的人角度写注释,或者解释为什么选择A方案,而不是B方案。

#ifndef  _pid_h_
#define  _pid_h_
#include <stdio.h>
#include "board.h"
//编写PID应在云台中调用
#define Kp  5.0
#define Ki  5.0
#define Kd  5.0
//这里参数设定有问题,云台抖动
typedef struct 
{float Velcity_Kp;float Velcity_Ki;float Velcity_Kd;float Error;float Last_Error;float integral;float derivate;int Control_Velocity;
}PID;
void PID_Init(PID*pid, float Velcity_Kp ,float Velcity_Ki,float Velcity_Kd);
float PID_Calculate (PID*pid,float Current_Velocity ,float TargetVelocity);
#endif

        上述这些出函数本身带来的信息,是值得去注释的,这些是对于读你代码的人是有用的,是有价值的信息

#代码缩进问题

        使用TAB进行缩进的时候,这个键的值可能是4位或者是8位,有的小伙伴上面缩进4跟下面8个,随便缩进,反正不会报错,看着确实难受,如果使用文本方式打开,驱动文件,可以发现是跟在KEIL5中阅读的缩进大小是不一样的。

        如果代码被不同的编译器打开,缩进效果,也是不一样的,但是如果使用 空格键 代替缩进在大多数编译平台看到的区别都是不大的。

        这里在KEIL5中是4位缩进,下面使用VSCODE打开相同的源文件

        可以看到这里就变成了8位缩进,只是因为使用的编译器不同,导致效果就不一样了,同时附带着汉字乱码(改编码格式)。

        总结:如果代码经常移植,建议缩进使用空格代替。

                                欢迎指正,希望对你有所帮助!!!

相关文章:

嵌入式应用开发之代码整洁之道

前言&#xff1a;本系列教程旨在如何将自己的代码写的整洁&#xff0c;同时也希望小伙伴们懂如何把代码写脏&#xff0c;以备不时之需&#xff0c;同时本系列参考 正点原子 &#xff0c; C代码整洁之道&#xff0c;编写可读的代码艺术。 #好的代码的特点 好的代码应该都有着几…...

iwconfig iwpriv学习之路

iwconfig和iwpriv是两个常用的wifi调试工具&#xff0c;最近需要使用这两个工具完成某款wifi芯片的定频测试&#xff0c;俗话说好记性不如烂笔头&#xff0c;于是再此记录下iwconfig和iwpriv的使用方式。 -----再牛逼的梦想&#xff0c;也抵不住傻逼般的坚持&#xff01; ----2…...

【Docker-compose】搭建php 环境

文章目录 Docker-compose容器编排1. 是什么2. 能干嘛3. 去哪下4. Compose 核心概念5. 实战 &#xff1a;linux 配置dns 服务器&#xff0c;搭建lemp环境&#xff08;Nginx MySQL (MariaDB) PHP &#xff09;要求6. 配置dns解析配置 lemp Docker-compose容器编排 1. 是什么 …...

【记录】LaTex|LaTex 代码片段 Listings 添加带圆圈数字标号的箭头(又名 LaTex Tikz 库画箭头的简要介绍)

文章目录 前言注意事项1 Tikz 的调用方法&#xff1a;newcommand2 标号圆圈数字的添加方式&#xff1a;\large{\textcircled{\small{1}}}\normalsize3 快速掌握 Tikz 箭头写法&#xff1a;插入点相对位移标号node3.1 第一张图&#xff1a;插入点相对位移3.2 第二张图&#xff1…...

《框架封装 · Redis 事件监听》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…...

小白学webgl合集-Three.js加载器

THREE.TextureLoader: 用途: 加载单个图像文件并将其作为纹理应用到材质上。示例: const loader new THREE.DataTextureLoader(); loader.load(path/to/data.bin, function (texture) {const material new THREE.MeshBasicMaterial({ map: texture });const geometry new TH…...

【算法】字符串的排列

难度&#xff1a;中等 给你两个字符串 s1 和 s2 &#xff0c;写一个函数来判断 s2 是否包含 s1 的排列。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 换句话说&#xff0c;s1 的排列之一是 s2 的 子串 。 示例 1&#xff1a; 输入&#xff1a;…...

5-3.损失函数

文章最前&#xff1a; 我是Octopus&#xff0c;这个名字来源于我的中文名–章鱼&#xff1b;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github &#xff1b;这博客是记录我学习的点点滴滴&#xff0c;如果您对 Python、Java、AI、算法有兴趣&#xff0c;可以关注我的…...

SCSA第四天

ASPF FTP --- 文件传输协议 Tftp --- 简单文件传输协议 FTP协议相较于Tftp协议 ---- 1&#xff0c;需要进行认证 2&#xff0c;拥有一套完整的命令集 用户认证 防火墙管理员认证 ---- 校验登录者身份合法性 用户认证 --- 上网行为管理中的一环 上网用户认证 --- 三层认证…...

品牌策划必读:9本改变游戏规则的营销经典

作为深耕品牌十余年的策划人&#xff0c;这些年自学啃下的书不计其数。 这里特意挑选了几本知名度不高但是却非常有用的“遗珠”优质品牌策划书籍分享出来。 如果你是一位初步了解品牌的人&#xff0c;这些书籍既包含了品牌理论基础&#xff0c;也有实用的实践指导。 这些书…...

泛型

背景 优点 类型绝对安全避免强制类型转换 泛型类 定义 使用 举例 泛型类 // 泛型类 T就是类型参数 public class Generic<T>{// key这个成员变量的类型为T,T的类型由外部指定private T t;public void set(T t){this.t t;}public T get(){return t;} }使用 // 创建一个泛…...

react动态渲染列表与函数式组件

1.如何使用jsx语法动态渲染列表呢&#xff0c;下边我用一个例子来切实总结一下 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scal…...

小程序内容管理系统设计

设计一个小程序内容管理系统&#xff08;CMS&#xff09;时&#xff0c;需要考虑以下几个关键方面来确保其功能完善、用户友好且高效&#xff1a; 1. 需求分析 目标用户&#xff1a;明确你的目标用户群体&#xff0c;比如企业、媒体、个人博主等&#xff0c;这将决定系统的功…...

HDFS 块重构和RedundancyMonitor详解

文章目录 1. 前言2 故障块的重构(Reconstruct)2.1 故障块的状态定义和各个状态的统计信息2.2 故障文件块的查找收集2.5.2.1 misReplica的检测2.5.2.2 延迟队列(postponedMisreplicatedBlocks)的构造和实现postponedMisreplicatedBlocks中Block的添加postponedMisreplicatedBloc…...

Power BI DAX常用函数使用场景和代码示例

Power BI函数表达式对于没有接触过的朋友可能会有些迷茫&#xff0c;花一点时间了解一下原理在学习一些常用的DAX函数&#xff0c;就可以解决工作中绝大部分问题&#xff0c;函数使用都是共同的。 以下是一些最常用的DAX函数&#xff0c;如聚合&#xff0c;计数&#xff0c;日期…...

机器学习与深度学习:区别与联系(含工作站硬件推荐)

一、机器学习与深度学习区别 机器学习&#xff08;ML&#xff1a;Machine Learning&#xff09;与深度学习&#xff08;DL&#xff1a;Deep Learning&#xff09;是人工智能&#xff08;AI&#xff09;领域内两个重要但不同的技术。它们在定义、数据依赖性以及硬件依赖性等方面…...

大模型/NLP/算法面试题总结5——Transformer和Rnn的区别

Transformer 和 RNN&#xff08;循环神经网络&#xff09;是两种常见的深度学习模型&#xff0c;广泛用于自然语言处理&#xff08;NLP&#xff09;任务。 它们在结构、训练方式以及处理数据的能力等方面有显著的区别。以下是它们的主要区别&#xff1a; 架构 RNN&#xff0…...

【RHCE】转发服务器实验

1.在本地主机上操作 2.在客户端操作设置主机的IP地址为dns 3.测试,客户机是否能ping通...

AI提示词:打造爆款标题生成器

打开GPT输入以下内容&#xff1a; # Role 爆款标题生成器## Profile - author: 姜小尘 - version: 02 - LLM: Kimi - language: 中文 - description: 利用心理学和市场趋势&#xff0c;生成吸引眼球的自媒体文章标题。## Background 一个吸引人的标题是提升文章点击率和传播力…...

skywalking-1-服务端安装

skywalking很优秀。 安装服务端 skywalking的服务端主要是aop服务&#xff0c;为了方便查看使用还需要安装ui。另外采集的数据我们肯定要存起来&#xff0c;这个数据库就直接用官方的banyandb。也就是aop、ui、banyandb都使用官方包。 我们的目的是快速使用和体验&#xff0c…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...