赞
踩
华为 (特殊规范已经省略,如:全局变量应增加“g_”前缀。)
每一个.c文件都应有一个同名.h文件,用于对外公开接口
禁止头文件循环依赖(现在循环依赖编译不会通过)
.c/.h文件禁止包含用不到的头文件
减少编译时间
头文件应当自包含,头文件可独立编译
编写#include保护符(#define保护)
#ifndef __STM32F10x_IT_H
#define __STM32F10x_IT_H
...
#endif /* __STM32F10x_IT_H */
由于操作失误,导致2-3章原始笔记丢失,使用简单笔记作为补充
原因:文章已经发布之后,不会自动保存正在编辑的内容,过程中断网,导致原始笔记丢失。
背景:函数设计的精髓:编写整洁函数,同时把代码有效组织起来。
标识符的命名要清晰、明了,有明确含义。
缩写少,可读性高
除了常见的通用缩写以外,不使用单词缩写,不得使用汉语拼音 。
汉语拼音
一些常见可以缩写的例子:
argument 可缩写为 arg
buffer 可缩写为 buff
clock 可缩写为 clk
command 可缩写为 cmd
compare 可缩写为 cmp
configuration 可缩写为 cfg
device 可缩写为 dev
error 可缩写为 err
hexadecimal 可缩写为 hex
increment 可缩写为 inc、
initialize 可缩写为 init
maximum 可缩写为 max
message 可缩写为 msg
minimum 可缩写为 min
parameter 可缩写为 para
previous 可缩写为 prev
register 可缩写为 reg
semaphore 可缩写为 sem
statistic 可缩写为 stat
synchronize 可缩写为 sync
temp 可缩写为 tmp
用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。
add/remove begin/end create/destroy
insert/delete first/last get/release
increment/decrement put/get add/delete
lock/unlock open/close min/max
old/new start/stop next/previous
source/target show/hide send/receive
source/destination copy/paste up/down
尽量避免名字中出现数字编号,除非逻辑上的确需要编号。
标识符前不应添加模块、项目、产品、部门的名称作为前缀。
平台/驱动等适配代码的标识符命名风格保持和平台/驱动一致。
重构/修改部分代码时,应保持和原有代码的命名风格一致。
对于数值或者字符串等等常量的定义,建议采用全大写字母,单词之间加下划线„_‟的方式命
名(枚举同样建议使用此方式定义)。
#define PI_ROUNDED 3.14
除了头文件或编译开关等特殊标识定义,宏定义不能使用下划线„_‟开头和结尾。
构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的全局变量,防止多个不同模块或函数都可以修改、创建同一全局变量的现象。
使用面向接口编程思想,通过API访问数据,提供接口函数设置,获取。
在首次使用前初始化变量,初始化的地方离使用的地方越近越好。
不要使用无意义的初始化:speedup_factor = 0;
明确全局变量的初始化顺序,避免跨模块的初始化依赖。 要考虑到该全局变量在什么时候初始化,使用全局变量和初始化全局变量,两者之间的时序关系,谁先谁后。
尽量减少没有必要的数据类型默认转换与强制转换。
用宏定义表达式时,要使用完备的括号。
宏只是简单的代码替换,不会像函数一样计算参数先后
将宏所定义的多条表达式放在大括号中。
暂时用不到,看不太懂
使用宏时,不允许参数发生变化。
示例:如下用法可能导致错误。
#define SQUARE(a) ((a) * (a))
int a = 5;
int b;
b = SQUARE(a++); // 结果:a = 7,即执行了两次增。
个人觉得上述代码应该写成函数(例子罢了,正常人不会这样写)
不允许直接使用魔鬼数字。
魔鬼数字的定义:在代码中没有具体含义的数字、字符串。
解决:用常量定义魔鬼数字。
除非必要,应尽可能使用函数代替宏。
正如上述代码所说
常量建议用const代替宏
出错跟踪的时候可见源头而不是一个数字,但是很多嵌入式开发中,宏定义利大于弊。
程序流程语句不要在宏定义中使用,如:return,goto,break,continue。
代码质量保证优先。
正确,简洁,可维护,可靠,可测试,性能,可移植,个人表达
注意容易混淆的操作符。
易混淆如:= 和 == ;!(逻辑操作)和~(位操作);
易用错如:
/操作,两边是整形,结果也是整形,向下取整。
%取余操作只能用整数
自加自减操作符的前置和后置
了解内存分配方式,不同编译系统变量分配规则。
不仅关注接口,也要关注实现。
禁止内存操作越界。
- 数组考虑最大情况,避免空间不足。
- 避免使用危险函数sprintf /vsprintf/strcpy/strcat/gets操作字符串,使用相对安全的函数snprintf/strncpy/strncat/fgets代替。
- 使用memcpy/memset时一定要确保长度不要越界。
- 考虑字符串结尾是’\0’,确保字符串是以’\0’结束。
- 指针加减考虑指针类型长度。
- 数组下标检查。
- 使用sizeof/strlen检查长度,避免手工检查。
禁止内存泄漏。
禁止引用已经释放的内存空间。
编程时,要防止差1错误。
比如"<=“和”<"的使用
有if最后要有else,有switch要有default。
函数分配内存,要在退出之前释放。
规则5
不要goto
注意表达式的上溢下溢
unsigned char size;
...
while(size-- >= 0) //将出现下溢
{
...
}
//当size等于0,继续减不会小于0,而是0xFF,死循环
在保证软件系统的正确性、简洁、可维护性、可靠性及可测性的前提下,提高代码效率。
将大概率出现的分支放在前面,虽然可以提高效率,但是大多数时候,不要把注意力集中在如何使代码更快上,应首先关注让代码尽可能地清晰易读和更可靠。
通过对数据结构、程序算法的优化来提高效率。
简单来说,赋值操作最好分开写。
注意告警清除,修改代码清除告警
用户输入检查。(函数入参检查)
- 用户输入作为数值的,做数值范围检查
- 用户输入作为数值的,做数值范围检查
- 用户输入是字符串的,检查字符串长度
- 用户输入作为格式化字符串的,检查关键字“%”
- 用户输入作为业务数据,对关键字进行检查、转义
字符串以NULL即’\0’结尾,避免使用一些危险函数。
//正确写法:截断字符串,保证字符串以NULL结束。
char a[16];
strncpy(a, "0123456789abcdef", sizeof(a) - 1 );
a[sizeof(a) - 1] = '\0';
明确字符串长度再写入数组,分配内存
避免整型变量溢出
避免带符号整型和无符号整型的符号错误。
避免截断错误,大整型到小的转换
格式化输出参数匹配 %d,int,懂?
不要将用户输入直接输出
printf(input);//可能会出错
printf(“%s”, input);//正确
避免使用strlen()计算二进制数据的长度。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。