【C命名规范】遵循良好的命名规范,提高代码的可读性、可维护性和可复用性

/********************************************************************
* @brief @param @return @author @date @version是代码书写的一种规范
* @brief :简介,简单介绍函数作用
* @param :介绍函数参数
* @return:函数返回类型说明
* @exception NSException 可能抛出的异常.
* @author zhangsan: 作者
* @date 2011-07-27 22:30:00 :时间
* @version 1.0 :版本
* @property :属性介绍
* *********************************************************************/

【变量的命名习惯】
变量名是自定义的,严格遵循 标识符 命名规则。

  • 见名知意
  • 大驼峰:即每个单词首字母都大写,例如:MyName
  • 小驼峰:即第二个(含)以后的单词首字母大写,例如:myName
  • 小写+下划线:例如:my_name

个人风格分享

1.变量

  • 全局变量:小驼峰(小驼峰+下划线),例如 myNamemy_Name

  • 局部变量: 全小写(小写+下划线),例如 indexmy_name

2.常量: 全大写字母、下划线分隔单词和描述性名称

#define MAX_BUFFER_SIZE 1024
#define PI_VALUE 3.14159
#define DEFAULT_TIMEOUT 30

3.标志变量

  • 全局:g_ + 小驼峰 + 下划线,例如 g_has_Err
  • 局部: g_ + 全小写 + 下划线 , 例如 g_has_err

4.函数名 大驼峰(大驼峰+下划线), 例如 GetValue, Get_Value()

动词+名词结构 ,例如 GetValue, Get_Value()

5.结构体 大驼峰(大驼峰 + 下划线),例如

// 定义结构体
typedef struct {int id;   // 结构体成员局部的用小写char name[50];int age;
} StudentInfo;
// Student_Info

6.枚举 : 枚举成员名使用全大写字母, 前缀标识枚举成员

typedef enum {STATUS_SUCCESS, // 前缀标识枚举成员STATUS_ERROR,  // 全大写字母STATUS_PENDING
} StatusCode;
// Status_Code;

总结就是凡是有带大写的都跟全局有关,凡是标志位够加g_,常量用全大写字母表示。


在C语言编程中,良好的命名规则有助于提高代码的可读性可维护性可扩展性。以下是一些值得学习和遵守的命名规则:

  1. 变量命名规则:

    • 使用小写字母,单词之间用下划线分隔,例如:student_age, total_sumindex
    • 变量名应具有描述性,反映其用途或含义。
  2. 常量命名规则:

    • 使用全大写字母,单词之间用下划线分隔,例如:MAX_BUFFER_SIZE, PI_VALUE
    • 常量名通常使用 #defineconst 关键字定义。
  3. 函数命名规则:

    • 使用动词或动词短语开头,后接名词,单词之间用下划线分隔,例如:calculate_sum, print_student_info
    • 函数名应清晰描述其功能或操作。
  4. 结构体和联合体命名规则:

    • 结构体和联合体类型名使用大写字母开头,每个单词的首字母大写,例如:StudentInfo, EmployeeRecord
    • 结构体变量名使用小写字母,单词之间用下划线分隔,例如:student_info, employee_record
  5. 枚举命名规则:

    • 枚举类型名使用大写字母开头,每个单词的首字母大写,例如:Color, Status
    • 枚举成员名使用全大写字母,单词之间用下划线分隔,例如:RED, GREEN, SUCCESS, FAILURE
  6. 文件名规则:

    • 文件名应简洁且具有描述性,通常使用小写字母,单词之间用下划线分隔,例如:main.c, student_info.h
  7. 缩写和简写:

    • 尽量避免使用不常见的缩写和简写,如果使用缩写,确保其含义清晰并在代码中有解释。
  8. 命名长度:

    • 命名长度应适中,过长的名字会影响可读性,过短的名字则可能不够描述性。一般推荐变量名长度在3-20个字符之间。
  9. 前缀和后缀:

    • 使用前缀或后缀区分不同作用域或用途的变量,例如:全局变量使用 g_ 前缀,静态变量使用 s_ 前缀,指针变量使用 _ptr 后缀。

通过遵守这些命名规则,可以使代码更具可读性和可维护性,减少出错的概率。


全局变量的标志位变量命名时,应该遵循一些具体的规则,以确保代码的可读性和易维护性。以下是一些建议:

  1. 使用前缀标识全局变量:

    • g_ 前缀来标识全局变量。例如:g_flag_connected, g_flag_initialized
  2. 清晰描述变量含义:

    • 变量名应反映其用途或含义。使用描述性单词使其一目了然。例如:g_flag_error_occurred, g_flag_data_ready
  3. 使用布尔命名约定:

    • 对于布尔类型的标志位变量,使用 is, has, can 等前缀。例如:g_is_connected, g_has_error, g_can_read
  4. 统一命名风格:

    • 保持命名的一致性,确保团队中所有开发者遵循相同的命名规范。例如:所有标志位变量都以 g_flag_ 开头,然后描述具体含义。
  5. 避免使用缩写:

    • 除非是非常常见和容易理解的缩写,否则尽量避免使用缩写,以防止误解。例如:g_flag_buffer_overflow 而不是 g_flag_buf_ovf
  6. 示例命名:

    • g_flag_initialized - 表示系统或模块是否已初始化。
    • g_flag_error_occurred - 表示是否发生了错误。
    • g_flag_data_ready - 表示数据是否已经准备好。
    • g_is_connected - 表示是否已经连接。
    • g_has_data - 表示是否有数据可用。

通过遵守这些命名规则,可以使代码更具可读性和一致性,方便团队协作和代码维护。


在单片机开发中,良好的编程习惯和命名规则可以极大地提高代码的可读性、可维护性和可靠性。以下是一些值得学习和遵守的编程习惯和命名规则:

编程习惯

  1. 注释代码:

    • 在代码中添加必要的注释,解释代码的功能、逻辑和重要的变量或函数。确保注释清晰且有意义。
  2. 模块化编程:

    • 将代码划分为多个模块或文件,每个模块负责特定的功能。这样可以提高代码的可维护性和可复用性。
  3. 使用常量和宏定义:

    • 使用 #defineconst 定义常量,避免在代码中使用硬编码的数值。例如:#define MAX_BUFFER_SIZE 1024
  4. 初始化所有变量:

    • 在使用变量之前进行初始化,以防止未定义行为和潜在的错误。
  5. 防御性编程:

    • 编写健壮的代码,处理所有可能的错误情况和异常情况。使用断言(assert)来捕捉不应出现的条件。
  6. 合理使用中断:

    • 中断服务程序(ISR)应该尽量短小精悍,避免在ISR中执行耗时操作。将复杂的处理移到主程序中完成。
  7. 遵循代码规范:

    • 遵循团队或项目的编码规范,确保代码风格一致。常见的编码规范包括命名规则、缩进风格、括号位置等。

命名规则

  1. 变量命名:

    • 使用描述性名称,避免使用单个字符或无意义的名称。变量名应反映其用途或含义。
    • 使用小写字母,单词之间用下划线分隔。例如:sensor_value, motor_speed
  2. 常量命名:

    • 使用全大写字母,单词之间用下划线分隔。例如:MAX_BUFFER_SIZE, PI_VALUE
  3. 函数命名:

    • 使用动词或动词短语开头,后接名词,单词之间用下划线分隔。例如:init_motor, read_sensor_value
  4. 结构体和枚举命名:

    • 结构体和枚举类型名使用大写字母开头,每个单词的首字母大写,例如:SensorData, ErrorCode
    • 结构体变量名使用小写字母,单词之间用下划线分隔,例如:sensor_data, error_code
  5. 宏定义命名:

    • 使用全大写字母,单词之间用下划线分隔。例如:#define LED_PIN 13, #define TIMER_PERIOD 1000
  6. 文件命名:

    • 文件名应简洁且具有描述性,通常使用小写字母,单词之间用下划线分隔,例如:main.c, sensor_driver.h

代码示例

// 常量和宏定义
#define MAX_BUFFER_SIZE 1024
#define LED_PIN 13// 结构体定义
typedef struct {int sensor_value;float temperature;
} SensorData;// 函数声明
void init_motor(void);
int read_sensor_value(void);// 主函数
int main(void) {// 变量初始化SensorData sensor_data = {0, 0.0};int sensor_value = 0;// 初始化电机init_motor();// 读取传感器值sensor_value = read_sensor_value();// 处理传感器数据sensor_data.sensor_value = sensor_value;sensor_data.temperature = sensor_value * 0.1;return 0;
}// 函数定义
void init_motor(void) {// 初始化电机的代码
}int read_sensor_value(void) {// 读取传感器值的代码return 42;
}

这些编程习惯和命名规则可以帮助你编写更高质量、更易维护的代码,尤其是在团队协作和长期维护中显得尤为重要。


在编程中,断言(assert)是一种用于捕捉不应出现的条件的调试工具。断言可以在开发和调试过程中帮助检测程序中的逻辑错误和不一致性。当程序运行时,如果断言条件为假(false),程序会立即终止,并输出错误信息,方便开发者定位和修复问题。

使用断言的步骤

  1. 包含头文件:

    • 使用断言前,需要包含头文件 <assert.h>
  2. 使用 assert 宏:

    • 使用 assert 宏来检查条件。语法如下:
      #include <assert.h>void some_function(int value) {assert(value > 0); // 如果 value <= 0,程序将终止并输出错误信息
      }
      
  3. 编译时控制:

    • 断言在调试阶段非常有用,但在发布阶段可能不需要。可以通过定义 NDEBUG 来禁用断言。
      #define NDEBUG
      #include <assert.h>
      

示例代码

以下是一个使用断言的示例代码:

#include <assert.h>
#include <stdio.h>// 计算数组中元素的平均值
double calculate_average(int *array, int size) {// 断言数组指针不为空assert(array != NULL);// 断言数组大小大于0assert(size > 0);int sum = 0;for (int i = 0; i < size; i++) {sum += array[i];}return (double)sum / size;
}int main() {int values[] = {10, 20, 30, 40, 50};int size = sizeof(values) / sizeof(values[0]);// 调用函数前的断言assert(size > 0);double average = calculate_average(values, size);printf("Average: %.2f\n", average);return 0;
}

解释

  1. 包含头文件:

    • 代码中首先包含了 <assert.h> 头文件,这个头文件定义了 assert 宏。
  2. 使用 assert 宏:

    • calculate_average 函数中,使用了两个断言来确保输入的数组指针不为空且数组大小大于0。
    • main 函数中,使用了一个断言来确保数组大小大于0。
  3. 断言失败:

    • 如果 assert 条件为假,程序将终止并输出错误信息,包括断言失败的条件和源代码文件中的行号。

禁用断言

在发布阶段,可以通过定义 NDEBUG 来禁用断言。例如:

#define NDEBUG
#include <assert.h>

在定义 NDEBUG 后,所有 assert 语句将被预处理器移除,断言检查将不会在程序运行时执行。

总结

使用断言可以有效地捕捉程序中不应出现的条件,帮助开发者在调试阶段快速定位和修复逻辑错误。通过合理使用断言,可以提高代码的健壮性和可靠性。在发布阶段,可以通过定义 NDEBUG 来禁用断言,确保程序的性能和稳定性。


在项目中使用单片机的多个串口(如串口0、串口1、串口2)进行数据收发时,可以使用结构体来组织相关的变量,以便管理和操作这些串口。以下是一个示例,定义了一个结构体来表示三个串口的相关变量:

typedef struct {// 串口0相关变量volatile uint8_t uart0_rx_buffer[UART_RX_BUFFER_SIZE];volatile uint8_t uart0_tx_buffer[UART_TX_BUFFER_SIZE];volatile uint8_t uart0_rx_index;volatile uint8_t uart0_tx_index;volatile bool uart0_rx_complete;// 串口1相关变量volatile uint8_t uart1_rx_buffer[UART_RX_BUFFER_SIZE];volatile uint8_t uart1_tx_buffer[UART_TX_BUFFER_SIZE];volatile uint8_t uart1_rx_index;volatile uint8_t uart1_tx_index;volatile bool uart1_rx_complete;// 串口2相关变量volatile uint8_t uart2_rx_buffer[UART_RX_BUFFER_SIZE];volatile uint8_t uart2_tx_buffer[UART_TX_BUFFER_SIZE];volatile uint8_t uart2_rx_index;volatile uint8_t uart2_tx_index;volatile bool uart2_rx_complete;
} SerialPorts;// 定义一个实例化的结构体变量
SerialPorts serial_ports;

结构体成员说明:

  • uartX_rx_buffer: 串口X接收缓冲区,用于存储从串口X接收到的数据。
  • uartX_tx_buffer: 串口X发送缓冲区,用于存储待发送至串口X的数据。
  • uartX_rx_index: 串口X接收缓冲区的索引,指示下一个接收数据的位置。
  • uartX_tx_index: 串口X发送缓冲区的索引,指示下一个发送数据的位置。
  • uartX_rx_complete: 串口X接收完成标志,用于指示是否完成了一次数据接收。

注意事项:

  1. volatile 关键字

    • 在单片机编程中,通常使用 volatile 关键字来声明这些变量,以确保编译器不会对它们进行优化,保证每次访问都是直接从内存中读取或写入。
  2. 缓冲区大小定义

    • UART_RX_BUFFER_SIZEUART_TX_BUFFER_SIZE 是根据实际需求定义的宏或常量,表示串口接收和发送缓冲区的大小。
  3. 多个串口的区分

    • 结构体中通过命名方式区分不同的串口变量,如 uart0_...uart1_...uart2_...

通过这种方式,你可以方便地管理和操作多个串口的数据收发,使代码结构更清晰,易于维护和扩展。

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

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

相关文章

同一个excel表格,为什么在有的电脑上会显示#NAME?

一、哪些情况会产生#NAME?的报错 1.公式名称拼写错误 比如求和函数SUM&#xff0c;如果写成SUN就会提示#NAME&#xff1f;报错。 2.公式中的文本值未添加双引号 如下图&#xff1a; VLOOKUP(丙,A:B,2,0) 公式的计算结果会返回错误值#NAME?&#xff0c;这是因为公式中文本…

【PLC】三菱PLC如何和汇川伺服实现485通信

前言 一开始选用的是汇川SV660P脉冲型伺服&#xff0c;由于生产需求需要对伺服的个别参数进行读取和写入操作&#xff0c;但是SV660P并不支持这种情况&#xff0c;因此需要使用485通信来满足。PLC这边选用的是三菱FX5U。 开始 1、首先准备按照下图的引脚提示准备好一根带屏蔽…

全志H616交叉编译工具链的安装与使用

交叉编译的概念 1. 什么是交叉编译&#xff1f; 交叉编译是指在一个平台上生成可以在另一个平台上运行的可执行代码。例如&#xff0c;在Ubuntu Linux上编写代码&#xff0c;并编译生成可在Orange Pi Zero2上运行的可执行文件。这个过程是通过使用一个专门的交叉编译工具链来…

(七)glDrawArry绘制

几何数据&#xff1a;vao和vbo 材质程序&#xff1a;vs和fs(顶点着色器和片元着色器) 接下来只需要告诉GPU&#xff0c;使用几何数据和材质程序来进行绘制。 #include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostrea…

程序员接单服务话术

进入群聊开始服务时&#xff1a; 尊敬的客户您好&#xff0c;我程序员&#xff1a;xx 很荣幸为您服务 我擅长xx领域 接下来我们一起对接下详细需求&#xff0c;我将根据您的任务需求难度给您汇报开发所需时长及报价。预祝我们合作愉快。 报价后且客户接受时&#xff1a; 您好…

PostgreSQL的学习心得和知识总结(一百四十七)|深入理解PostgreSQL数据库之transaction chain的使用和实现

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

2024年文化传播与对外交流国际学术会议(ICCCFE 2024)

2024年文化传播与对外交流国际学术会议&#xff08;ICCCFE 2024&#xff09; 2024 International Conference on Cultural Communication and Foreign Exchange(ICCCFE 2024) 会议简介&#xff1a; 2024年文化传播与对外交流国际学术会议&#xff08;ICCCFE 2024&#xff09;定…

clion开发51 没有创建成功可能是Clion版本问题

安装插件 PlatformlO for CLion 进入这个网站下载get-platformio.py https://docs.platformio.org/en/latest/core/installation/methods/installer-script.html#local-download-macos-linux-windows 点击 Installation Methods 选择 Local Download (macOS/Linux/Windows) 点…

linux指令gzip

gzip 是 Linux 系统中广泛使用的一个文件压缩和解压缩程序。它使用 Lempel-Ziv 编码&#xff08;LZ77&#xff09;和 Huffman 编码的组合来压缩文件&#xff0c;减少磁盘使用空间和网络传输时间。以下是对 gzip 命令的一些基本使用说明和示例&#xff0c;这些示例旨在帮助你了解…

小阿轩yx-案例:MySQL主从复制与读写分离

小阿轩yx-案例&#xff1a;MySQL主从复制与读写分离 案例分析 概述 实际生产环境中 如果对数据库读和写都在同一个数据库服务器中操作&#xff0c;无论在安全性、高可用性还是高并发等各个方面都完全不能满足实际需求一般都是通过主从复制&#xff08;Master-Slave&#xf…

MSPG3507——蓝牙接收数据显示在OLED,滴答定时器延时500MS

#include "ti_msp_dl_config.h" #include "OLED.h" #include "stdio.h"volatile unsigned int delay_times 0;//搭配滴答定时器实现的精确ms延时 void delay_ms(unsigned int ms) {delay_times ms;while( delay_times ! 0 ); } int a0; …

4.自动生成class和device

第三章里面&#xff0c;我们使用mknod创建设备节点&#xff0c;常规操作是在驱动init的时候就创建好&#xff0c;使用class_create和device_create创建。 #include "asm/uaccess.h" #include "linux/scatterlist.h" #include "linux/types.h" #…

【公平锁 和 非公平锁】

公平锁 和 非公平锁 公平锁:类似食堂打饭&#xff0c;按照申请锁的顺序来获取锁类似厕所蹲坑先来后到 公平锁就是很公平 在并发环境下每个线程在获取锁的同时会先查看此锁维护的等待队列&#xff0c;如果为空&#xff0c;或者当前线程是等待就占有锁&#xff0c;否则就加入到…

20人团队如何免费使用 Atlassian 云产品?

企业赚钱越来越难&#xff0c;尤其是初创团队或小型团队更倾向于使用免费工具支持业务。团队规模影响协作复杂度&#xff0c;Atlassian 考虑到小团队的需求&#xff0c;提供了多种选择。比如&#xff0c;Jira 和 Confluence 的云版本有免费版&#xff0c;包含基本的项目管理功能…

ISP IC/FPGA设计-第一部分-SC130GS摄像头分析(0)

1.介绍 SC130GS是一款国产的Global shutter CMOS图像传感器&#xff0c;最高支持1280Hx1024V240fps的传输速率&#xff1b;SC130GS有黑白和彩色款&#xff0c;作为ISP开发选择彩色的&#xff0c;有效像素窗口为1288Hx1032V&#xff0c;支持复杂的片上操作&#xff0c;选择他理…

Toshiba东芝TB6612FNG电机驱动IC:释放性能与多功能性

在嵌入式系统和机器人技术领域&#xff0c;电机控制是一个关键方面&#xff0c;对项目的性能和可靠性有着显著影响。东芝的TB6612FNG电机驱动IC作为一个稳健且多功能的解决方案&#xff0c;在驱动双直流电机方面脱颖而出&#xff0c;提供了高性能、可靠性和易用性。本文将深入探…

23种设计模式之装饰者模式

深入理解装饰者模式 一、装饰者模式简介1.1 定义1.2 模式类型1.3 主要作用1.4 优点1.5 缺点 二、模式动机三、模式结构四、 装饰者模式的实现4.1 组件接口4.2 具体组件4.3 装饰者抽象类4.4 具体装饰者4.5 使用装饰者模式4.6 输出结果&#xff1a; 五、 应用场景5.1 图形用户界面…

排序(堆排序、快速排序、归并排序)-->深度剖析(二)

前言 前面介绍了冒泡排序、选择排序、插入排序、希尔排序&#xff0c;作为排序中经常用到了算法&#xff0c;还有堆排序、快速排序、归并排序 堆排序&#xff08;HeaSort&#xff09; 堆排序的概念 堆排序是一种有效的排序算法&#xff0c;它利用了完全二叉树的特性。在C语言…

复分析——第9章——椭圆函数导论(E.M. Stein R. Shakarchi)

第 9 章 椭圆函数导论 (An Introduction to Elliptic Functions) The form that Jacobi had given to the theory of elliptic functions was far from perfection; its flaws are obvious. At the base we find three fundamental functions sn, cn and dn. These functio…