嵌入式C学习笔记之编码规范
一、程序员的态度
1、不太愿意测试自己的代码
2、不太愿意检查团队成员的代码
二、专业程序员
1、与业余程序相比,专业程序员更注重自己的代码风格。
2、专业程序员才能写出人能读懂的代码。
3、专业程序员要保证自己的代码没有BUG。
三、编码规范
1、程序开发流程
0)需求分析
1)功能设计
2)编写代码
3)单元测试
4)功能测试
5)代码REVIEW
2、公司开发,一般会有公司的开发规范。
3、代码风格要有助于其他程序员易于理解。
四、宏观上高质量编码规范
1、版本和版权的声明
2、头文件结构
1)版本和版权的声明
2)预处理部分
3)函数或者结构体声明
3、头文件使用注意事项
1)为了防止头文件被重复引用,在代码中使用:
#ifndef、#ifdef、#define、#endif
2)引用标准头文件:
#include <标准头文件名.h>
3)引用非标准头文件:
#include "非标准头文件名.h"
4)头文件中只存放"声明",不存放"定义"
void pr();//这是声明
void pr(){//这是定义,实现
函数体
}
5)多个c文件合并生成.out/.exe可执行文件的过程
方法一
把定义部分.c文件单独编译成.o文件
gcc 1.c -c
再把包含main函数的源文件也单独编译成.o文件
gcc 2.c -c
最后把多个.o文件链接生成可执行文件.out
gcc 1.o 2.o
方法二
gcc *.c
6)不提倡使用全局变量,尽量不要在头文件中出现
extern int XXX;
4、源文件
1)定义文件开头处的版权和版本信息
2)对一些头文件的引用
3)程序功能的实现代码,包括数据声明和函数实现
5、大的项目会涉及到工程目录结构问题
1)通常会把头文件和定义文件分别保存于不同的目录:source,include,lib
2)根据需要,对某些信息进行隐藏
6、命名规范
1)在变量或者函数名前面加前缀
2)符合标识符命名规范
7、程序的版式要求
1)空行的合理使用会增加程序的可读性
2)一般每个函数定义结束之后加一个空行
3)代码行,一行代码只做一件事件
4)if、for、while、do语句独占一行,循环体都用大括号
5)尽可能在定义变量的同时初始化变量(就近原则)
6)代码行内空格问题:{
关键字之后要留空格,
函数名之后不要空格,紧跟左括号,以与关键字区别
二元运算符的前后一般应当加空格,一元运算符前后不加空格
[]、.、->这些运算符前后不加空格
逗号运算符之后加空格
}
7)代码对齐{
{}左右大括号应当独占一行并且位于同一行,同时与引用它们的语句左对齐
{}内代码在左大括号{右边缩进tab位。
}
8)注释
//XXXXX
/*XXX*/
.....
五、微观上高质量编码规范
1、程序健壮性
1)条件:在保证条件确定和不确定的情况下,程序都能正常运行。
2)复合表达式:
a = b = c = 0;简洁,提高编译效率
不要编写太复杂的复合表达式。
不要编写有多用途的复合表达式:d = (a = b + c) + r;不建议
不要把程序中复合表达式与数学的数学式子混淆
if(a > b && b > c){} 与 if (a > b > c){};
对 功能错
3)if语句
(1)逻辑值(真1,假0) 与 零值 比较 :flag = n % 2 或者 flag = a > b;
if(flag){}
if (!flag){}
(2)整型值与零值 比较 == 或 !=
(3)浮点值与零值 比较 ,不要使用 == 或 !=,使用 >= 或 <=
10.0/3*3 在程序中不一定得 10
(4)指针变量与零值 比较,使用== 或 != 与 NULL比较
4)使用const提高函数的健壮性
1)const定义只读变量 const int a = 100;
2)可以使用const来修饰函数的形参(也叫输入参数)
如果使用const修饰了一个指针,则指针指向的数据不能修改
void strCopy(char *destionStr,const char *sourceStr){}
3)使用const修饰函数的返回值,修饰返回的指针,则指针指向的数据不能修改
const char *getString(){}
调用此函数时:
char *str = getString();//编译报错
const char *str = getString();//正确
5)内存管理的规范
(1)如何是动态申请内存,使用malloc之后,一定要判断指针值是否为NULL,以避免没有申请到空间的情况。
(2)不要忘记给数组或者动态申请的内存空间赋值,以避免使用没有初始化内存的值。
(3)避免数组和指针的下标越界,多1或少1的情况。
(4)动态内存的申请和释放必须配对出现,防止内存泄漏。
(5)free之后的指针不要再使用,为了防止这种使用野指针的情况,free之后应立即让指针值为NULL
(6)当指针变量做为某一个函数的形参时,不要在函数内使用此指针动态申请空间。否则运行报错。
void getMemory(char *p,int n){
p = (char *)malloc(sizeof(char) * n);
}
void main(){
char *str = NULL;
getMemory(str,100);
strcpy(str,"hello world");//报错,原因是str地址依然是NULL
}
(7)不要使用return语句返回指向“栈内存”的指针,可以是static内存空间地址
2、程序的优化
1)使用常量的情况
2)循环语句
(1)在多重循环中,如有可能,将循环次数多的循环做为内循环,循环次数的少的循环做为外循环,以减少cpu跨越循环层的次数。
(2)当循环体中有条件,且循环次数较多,如有可能,将条件移动循环体外面。
(3)尽量做到不要在for循环体中修改循环变量,以防止循环失控。
for(XXXX ; XXX ;循环变量改变){
不要在此进行循环变量改变
}