开发编码规范笔记

前言

(1)该博客仅用于个人笔记

格式转换

(1)查看是 LF 行尾还是CRLF 行尾。

# 单个文件,\n 表示 LF 行尾。\r\n 表示 CRLF 行尾。
hexdump -c <yourfile>
# 单个文件,'$' 表示 LF 行尾。'^M$' 表示 CRLF 行尾。
cat -e <yourfile>

(2)将文件转换为LF格式。

# 单个文件
dos2unix <yourfile>
# 批量操作
find <path> -type f -exec dos2unix {} \;

(3)将文件转换为CRLF格式。

# 单个文件
unix2dos <yourfile>
# 批量操作
find <path> -type f -exec unix2dos {} \;

C代码规范

断言

适用场景

(1)assert() 只能用于检测由于严重的内部逻辑错误或损坏而导致程序无法继续运行的不可恢复的错误。对于可恢复的错误,包括由于无效的外部输入而可能出现的错对于误,应返回错误值。
(2)对于返回值为esp_err_t类型的函数,应该使用ESP_ERROR_CHECK()而不是assert()

断言设置使能

(1)对于断言的设置,可以进入 menuconfig 搜索 CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL 进行配置:

  • Enabled : 启动断言功能。当断言失败时,会打印出断言的内容和行号。适用于开发阶段,因为它可以帮助开发者快速定位和修复代码中的错误。
  • Silent : 启动静默。断言失败时,不会打印出具体的断言信息和行号,而是直接中止程序。开发者需要通过中止地址来查找断言失败的位置。适用于在某些情况下需要节省代码大小的场景,同时仍然希望保留某种程度的断言检查
  • Disabled : 禁用断言。禁用断言后,任何断言检查都不会执行,从而提高程序的性能。

在这里插入图片描述

“变量设置但未使用”警告

(1)如果断言被失能,那么下面的 res 可能会出现“变量设置但未使用”警告。

int res = do_something();
assert(res == 0);

(2)为了避免这样的问题,我们可以让所有的返回值用同一个变量定义,然后加上关键字即可。

int res __attribute__((unused));res = do_something();
assert(res == 0);res = do_something_else();
assert(res != 0);

变量

前缀

(1)静态全局变量用 g_ 前缀,静态局部变量用 s_ 前缀。作用域仅限于当前文件的变量必须声明为静态变量 static

static uint8_t g_num; // 静态全局变量用 g_ 前缀
int main()
{static uint8_t s_num; // 静态局部变量用 s_ 前缀while (1);
}

使用

(2)变量注意重入问题。 尽量在一个固定函数中操作静态全局变量。使用 get_ set_ 等接口进行变量操作。

static SemaphoreHandle_t g_mutexhandle = NULL;  // 变量定义要赋初值,全局静态变量以 g_ 前缀
static uint8_t g_num = 0;                       // 变量定义要赋初值,全局静态变量以 g_ 前缀static void set_num(uint8_t value) // 使用 set_ 前缀接口操作变量
{// 获得信号量xSemaphoreTake(g_mutexhandle, portMAX_DELAY);g_num = value;// 释放信号量pthread_mutex_unlock(g_mutexhandle);
}static int get_num() // 使用 get_ 前缀接口操作变量
{uint8_t value;// 获得信号量xSemaphoreTake(g_mutexhandle, portMAX_DELAY);value = g_num;// 释放信号量pthread_mutex_unlock(g_mutexhandle);return value;
}int main() 
{static uint8_t s_count; // 静态局部变量用 s_ 前缀// 创造互斥量g_mutexhandle = xSemaphoreCreateMutex();while(1){set_num(10);s_count = get_num(); // 静态全局变量用 g_ 前缀vTaskDelay(pdMS_TO_TICKS(1000));}vSemaphoreDelete(g_mutexhandle);g_mutexhandle = NULL; // 句柄类型变量,在对象销毁后,应重新赋值为 NULL
}

变量名

(1)变量应尽量使用有意义的词语,或者已经达成共识的符号或变量缩写

在这里插入图片描述

函数

(1)如果一个函数存在重入和线程安全问题,需在注释中说明。

/*** @brief 打印函数,该函数存在线程安全问题* * @param __restrict 字符串* @param ...        可变参数* @return int */
int	printf (const char *__restrict, ...);

(2)函数名统一使用小写,同一组件保持同一前缀。

在这里插入图片描述

头文件

固定格式

(1)头文件固定如下格式。

#ifndef FILE_NAME_H /* 名字要与 .c 文件对应 */
#define FILE_NAME_H#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus *//*********************************************               头文件内容写里面********************************************/#ifdef __cplusplus
}
#endif /* __cplusplus */#endif /* FILE_NAME_H */

类型定义

(1)类型都需要通过 typedef 定义并且命名

typedef enum{MODULE_FOO_ONE,MODULE_FOO_TWO,MODULE_FOO_THREE
} module_foo_t; /* typedef 之后名字后缀为 _t */typedef struct {esp_chip_model_t model;  uint32_t features;       uint16_t revision;      uint8_t cores;          
} esp_chip_info_t; /* typedef 之后名字后缀为 _t */

格式化代码

(1)如果重头写一个文件,可以使用 astyle 工具。

# 格式化代码
astyle example.c
# 使用乐鑫官方脚本
${esp-idf}/tools/format.sh <yourfile>

最终代码演示

C代码

/**********************************************************************************                                 版权声明*********************************************************************************/
/** SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD** SPDX-License-Identifier: Apache-2.0*//**********************************************************************************                                 头文件规范*********************************************************************************/
// #include < C 标准库头文件           >
// #include < POSIX 头文件及其常见扩展  >
// #include " IDF 头文件              "
// #include " 组件头文件,例如 FreeRTOS "
// #include " 私有头文件               "#define uint8_t unsigned char
#define NULL 0
#define portMAX_DELAY -1/**********************************************************************************                                变量定义规范*********************************************************************************/
static uint8_t g_num = 5, g_x = 0, g_y = 0; /* ","仅后面有空格,静态全局变量用 g_ 前缀  */
static uint8_t *g_z = NULL;
static SemaphoreHandle_t g_mutexhandle = NULL;      // 互斥量/**********************************************************************************                                 代码规范*********************************************************************************/
static void circulate_function()
{/* 函数定义的括号应该单独一行 */if (g_num) { /* 循环关键字后面加一个空格,函数内左括号与条件放在同一行 */printf("hello");}else if (g_x) {printf("world");}for (; g_x < g_num; g_x++) { /* 循环关键字后面加一个空格,函数内左括号与循环放在同一行 */printf("esp");}while (g_x){ /* 循环关键字后面加一个空格,函数内左括号与循环放在同一行 */printf("esp32");}switch (g_num) { /* 循环关键字后面加一个空格,函数内左括号与循环放在同一行 */ case 0:break;default:break;} 
}/* 尽量在一个固定函数中操作静态全局变量 */
static void set_num(uint8_t value) // 使用 set_ 前缀接口操作变量
{// 获得信号量xSemaphoreTake(g_mutexhandle, portMAX_DELAY);g_num = value;// 释放信号量pthread_mutex_unlock(g_mutexhandle);
}static int get_num() // 使用 get_ 前缀接口操作变量
{uint8_t value;// 获得信号量xSemaphoreTake(g_mutexhandle, portMAX_DELAY);value = g_num;// 释放信号量pthread_mutex_unlock(g_mutexhandle);return value;
}int main() /* 函数之间放置一个空行 */
{/* Tab 键为4个空格,而不是制表符进行缩进 *//* 如果不需要这行代码,直接删除,否则就解释禁用原因。 */// printf("hello world");static uint8_t s_count; // 静态局部变量用 s_ 前缀// 创造互斥量g_mutexhandle = xSemaphoreCreateMutex();while(1){set_num(10);s_count = get_num();  // 因为该变量不存在重入问题,因此不需要进行保护vTaskDelay(pdMS_TO_TICKS(1000));}vSemaphoreDelete(g_mutexhandle);g_mutexhandle = NULL; // 句柄类型变量,在对象销毁后,应重新赋值为 NULL// 获得信号量xSemaphoreTake(g_mutexhandle, portMAX_DELAY);/* 一元运算符不需要空格 */g_x = g_num++; g_y = g_num--; *g_z = &g_num; g_x = !g_num; g_x = ~g_x;g_y = *g_z;g_x = (uint8_t)g_x;/* 二元运算符需要空格 */g_num = g_x + g_y;g_num = g_x - g_y;g_num = g_x * g_y; /* 这个可以删除空格 */g_num = g_x*g_y; g_num = g_x / g_y; /* 这个可以删除空格 */g_num = g_x/g_y;g_num = g_x % g_y;g_num = (g_x == g_y);g_num = (g_x != g_y);      g_num = (g_x > g_y);       g_num = (g_x < g_y);       g_num = (g_x >= g_y);      g_num = (g_x <= g_y);      g_num = (g_x && g_y);  g_num = (g_x || g_y); g_num = g_x & g_y;  g_num = g_x | g_y;      g_num = g_x ^ g_y;      g_num = g_x << 1;     g_num = g_x >> 1;     g_x += 3;  g_x -= 2;  g_x *= 2;  g_x /= 4;  g_x %= 2;  g_y &= 3;   g_y |= 2;   g_y ^= 3;   g_y <<= 1;  g_y >>= 1;  // 释放信号量pthread_mutex_unlock(g_mutexhandle);
}

头文件

#ifndef FILE_NAME_H /* 名字要与 .c 文件对应 */
#define FILE_NAME_H#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus *//* 枚举要通过 typedef 定义并且命名 */
typedef enum {MODULE_FOO_ONE,MODULE_FOO_TWO,MODULE_FOO_THREE
} module_foo_t; /* typedef 之后名字后缀为 _t *//*** @brief 该函数存在线程安全问题* * @param __restrict * @param ... * @return int */
int	printf (const char *__restrict, ...);#ifdef __cplusplus
}
#endif /* __cplusplus */#endif /* FILE_NAME_H */

参考

(1)Espressif IoT Development Framework Style Guide

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/45015.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

element-ui操作表格行内容如何获取当前行索引?

需求&#xff1a; 根据每个用户的提交次数、撤回次数&#xff0c;动态计算出实际次数&#xff0c;并且提交次数不能小于撤回次数 <template><div><el-table:data"tableData"style"width: 80%"border><el-table-columnprop"date&…

怎么提高音频的播放速度?可以提高音频播放速度的四种方法推荐

怎么提高音频的播放速度&#xff1f;提高音频的播放速度是一种有效的策略&#xff0c;可以显著节省时间和提升信息获取的效率。随着信息量不断增加和学习需求的多样化&#xff0c;快速播放音频已成为许多人在日常生活和工作中的常见做法。这种方法不仅可以用于提高学习效率&…

C语言 指针和数组——指针数组的应用:命令行参数

目录 命令行参数 演示命令行参数与main函数形参间的关系 命令行参数  什么是 命令行参数&#xff08; Command Line Arguments &#xff09;&#xff1f;  GUI 界面之前&#xff0c;计算机的操作界面都是字符式的命令行界面 &#xff08; DOS 、 UNIX 、 Linux &…

曹操的五色棋布阵 - 工厂方法模式

定场诗 “兵无常势&#xff0c;水无常形&#xff0c;能因敌变化而取胜者&#xff0c;谓之神。” 在三国的战场上&#xff0c;兵法如棋&#xff0c;布阵如画。曹操的五色棋布阵&#xff0c;不正是今日软件设计中工厂方法模式的绝妙写照吗&#xff1f;让我们从这个神奇的布阵之…

C++ 【 PCL 】点云添加随机均匀噪声及源代码

PCL向点云添加均匀随机噪声&#xff1a; #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/common/random.h>int main() {// 加载点云文件pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::Poi…

服务器数据恢复—同品牌不同系列服务器raid5阵列数据恢复方案分析

RAID5磁盘阵列数据恢复案例一&#xff1a; 服务器数据恢复环境&#xff1a; 一台某品牌LH6000系列服务器&#xff0c;通过NetRaid阵列卡将4块硬盘组建为一组RAID5磁盘阵列。操作系统都为Window server&#xff0c;数据库是SQLServer。 服务器故障&#xff1a; LH6000系列服务器…

Python实现傅里叶级数可视化工具

Python实现傅里叶级数可视化工具 flyfish 有matlab实现&#xff0c;我没matlab&#xff0c;我有Python&#xff0c;所以我用Python实现。 整个工具的实现代码放在最后,界面使用PyQt5开发 起源 傅里叶级数&#xff08;Fourier Series&#xff09;由法国数学家和物理学家让-巴…

Koa.js、Egg.js与Express.js:探析三大Node.js框架的异同

在Node.js的世界里&#xff0c;选择合适的框架对于构建高效、可维护的后端服务至关重要。Express.js、Koa.js 和 Egg.js 是三个备受欢迎的框架&#xff0c;它们各有特色&#xff0c;适用于不同的开发场景。本文旨在深入探讨这三个框架的区别&#xff0c;并通过代码示例帮助开发…

python3读取shp数据

目录 1 介绍 1 介绍 需要tmp.shp文件和tmp.dbf文件&#xff0c;需要安装geopandas第三方库&#xff0c;python3代码如下&#xff0c; import geopandas as gpdshp_file_path "tmp.shp" shp_data gpd.read_file(shp_file_path) for index, row in shp_data.iterro…

异步任务中传递用户信息的一种优雅写法

目录 前言基础写法测试示例 升级写法测试示例 前言 在异步任务中&#xff0c;我们通常会遇到子任务获取当前用户的场景。我们可能会采取ThreadLocal来存储主线程传递的用户信息。然后在业务开始时set&#xff0c;业务结束时remove&#xff0c;来保证不会出现OOM的场景。 基础…

MySQL中的约束

目录 1. 主键约束&#xff08;PRIMARY KEY&#xff09;2. 唯一约束&#xff08;UNIQUE&#xff09;3. 外键约束&#xff08;FOREIGN KEY&#xff09;4. 非空约束&#xff08;NOT NULL&#xff09;5. 默认约束&#xff08;DEFAULT&#xff09;6. 检查约束&#xff08;CHECK&…

数据库容灾 | MySQL MGR与阿里云PolarDB-X Paxos的深度对比

开源生态 众所周知&#xff0c;MySQL主备库&#xff08;两节点&#xff09;一般通过异步复制、半同步复制&#xff08;Semi-Sync&#xff09;来实现数据高可用&#xff0c;但主备架构在机房网络故障、主机hang住等异常场景下&#xff0c;HA切换后大概率就会出现数据不一致的问…

论文学习_B2SFinder: Detecting Open-Source Software Reuse in COTS Software

1. 引言 研究背景:随着结构设计模式的广泛采用以及缩短上市时间的迫切需要,越来越多的商业现成(COTS)软件产品正在开源软件(OSS)项目之上开发。如此快速的应用程序开发会导致一些不良问题,包括许可证违规和安全问题。在这些问题中,OSS 重用漏洞是最严重的问题之一。 …

Vue打包文件dist放在SpringBoot项目下运行(正确实现全过程)(下)

在上一篇中&#xff0c;实现了Vue打包文件dist放在SpringBoot项目下运行。 Vue打包文件dist放在SpringBoot项目下运行&#xff08;正确实现全过程&#xff09;&#xff08;上&#xff09; 问题 路由刷新会产生404的问题。 原因 vue开发的应用&#xff0c;采用的是SPA单页…

JAVA 提速方法——类数据共享 CDS

类数据共享 CDS&#xff08;Class-Data Sharing&#xff09; 类数据共享 是一项 JVM 功能&#xff0c;减少 Java 应用的启动时间和内存占用。CDS 作用是让** class 被预处理到归档文件**&#xff0c;Java 程序启动直接带上归档文件&#xff0c;这样 JVM 可直接将归档文件映射到…

【Linux网络】网络基础

本篇博客整理了 Linux 网络编程的前置知识&#xff0c;例如网络的发展、协议和协议栈分层、网络通信原理、网络地址等&#xff0c;为后续进入 Linux 网络编程作铺垫。 目录 一、网络发展 二、网络协议 1&#xff09;协议的作用 2&#xff09;协议栈 3&#xff09;协议分层…

大吉大利杯_RE

A-Maze-In 一道比较新颖的 maze 题吧&#xff0c; 地图长度是 256 32 * 8 &#xff1f; 不知道了 0.0 难崩&#xff0c;看了一下 wp 说map长度什么的都有&#xff0c;应该就是 16 * 16的 看了一圈&#xff0c;感觉还是要把 DFS&#xff0c;BFS 算法学一下&#xff0c;直接跑…

中国内陆水体氮沉降数据集(1990s-2010s)

全球大气氮沉降急剧增加对内陆水生态系统产生不良影响。中国是全球三大氮沉降热点地区之一&#xff0c;为了充分了解氮沉降对中国内陆水体的影响&#xff0c;制定合理的水污染治理方案&#xff0c;我们需要清楚的量化内陆水体的氮沉降通量。为此&#xff0c;我们利用LMDZ-OR-IN…

[AI 大模型] 百度 文心一言

文章目录 [AI 大模型] 百度 文心一言简介模型架构发展新技术和优势API 代码示例 [AI 大模型] 百度 文心一言 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0DwAIh0T-1720667576892)(https://i-blog.csdnimg.cn/direct/283919e5d78b4951ba1ade5dcfc…

java-mysql5.7 相关安装和配置

在 Java 中使用 MySQL 5.7 进行开发之前&#xff0c;首先需要安装和配置 MySQL 数据库。以下是详细的步骤&#xff0c;涵盖了 MySQL 5.7 的下载、安装、基本配置以及如何在 Java 中使用 JDBC 连接 MySQL 数据库。 ### 一、安装 MySQL 5.7 #### 1. 下载 MySQL 5.7 前往 MySQL …