C语言编程规范
C语言编程规范
代码命名规范
通用规范:
- 类型名用大写,变量名和常量名用小写
- 变量名前加变量类型,如u16count,ptext
- 所有宏定义、枚举项、结构体成员、联合体成员一定要加注释,并使用块注释
具体规范:
宏:
- 采用大写下划线,如果宏定义的是函数可以采用小写
- 为了更好地区分宏所属的模块,建议加模块前缀
枚举
- 枚举类型名使用大写,如若使用typedef定义枚举名,则枚举类型名后面加_E后缀
- 枚举成员名使用大写
- 枚举成员名最好添加模块前缀
结构体、联合体
- 类型名使用大写,如若使用typedef定义枚举名,则枚举类型名后面加_S后缀
- 成员变量名使用小写,且需要相应注释
全局变量:一律使用小写
- 仅文件内部使用:添加s_um_前缀
- 文件外部能访问:添加g_um_前缀
函数:一律使用小写下划线
- 仅供文件内部调用:可以不添加前缀
- 允许文件外部调用:添加um前缀
- 强调内部使用:添加__(双下划线)前缀
局部变量:一律使用小写下划线
基本类型:类型名使用大写
编译器版本间的兼容:有内联需求的,应使用
__inline
而非直接inline
语法和语义
变量定义后一定要初始化
删除未使用变量,去除编译时警告
函数无返回值则返回类型为void,函数无参数则参数类型为void,对有返回值的函数一定要处理返回值
声明统一放头文件或源文件最前面
debug版本中,函数传入的参数要使用assert进行检测,便于调试时排错
使用显示数据类型转换,避免编译器隐式转换
减少全局变量的使用
函数名和变量名不要同名,局部变量和全局变量不要同名
关于内存:
- 指针变量一定要初始化,无指向对象时先初始化为NULL,防止使用了野指针
- 动态分配内存要判断结果是否成功
- malloc和free要配套使用
- 释放内存后,要将指针指向NULL,防止野指针
常量
- 对外公开的放在头文件中,不公开的放在定义文件的头部
- 常量之间有密切联系时,应该在定义中显示出来,避免给出一些孤立的值
- C++中有两种定义常量的方式:
- const:有数据类型,编译器对其进行安全类型检查,可调试
- define:无数据类型,编译器不对其进行安全类型检查,不可调试
宏
- 使用宏定义表达式时,要使用完备的括号
- 宏定义有多条表达式,则表达式应该放在大括号中
- 使用宏时,不允许参数发生变化(自增自减)
const关键字
- 使用const修饰函数参数时,只能修饰输入参数
- C语言中,const修饰的是只读变量,C语言中定义常量的方法是宏define和枚举enum
变量:定义时一定要初始化,尽管全局变量和静态变量会有默认的初始值
避免使用bool参数,原因:
- bool参数值无意义,true/false的含义非常模糊,在调用时很难知道参数传达的意思
- bool参数值不利于扩充
关键字使用和语句使用规范
if语句
- 使用
if(NULL == p)
代替if(p == NULL)
,避免写少了等号 - 多个if语句判断时,将能预测到的最多情况放在第一个if语句中,从而提高效率
- 使用
for语句
不可在循环体内修改循环控制变量,防止for循环失去控制
建议for语句的循环控制变量的取值采用“半开半闭区间”写法,采用“半开半闭区间”写法能够减少错误,例如防止数组越界
在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数
如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面(不是很懂)
for (i=0; i<N; i++) { if (condition) DoSomething(); else DoOtherthing(); } //如果N非常大的话,应该采用右边的方法提高效率 if (condition) { for (i=0; i<N; i++) DoSomething(); } else { for (i=0; i<N; i++) DoOtherthing(); }
对于一次性的计算,不要放在for语句中
switch语句
- 每个case语句的结尾不要忘记加break
- 不要忘记缺省分支default,即使不需要也应添加
default:break;
- case后面的值只能是整形或字符型常量/常量表达式
- case语句排列顺序:
- 按字母或数字排序
- 正常情况放前面,异常情况放后面
- 按执行频率排列
- case语句中不能使用continue
goto语句:少用、慎用
inline关键字:内联,空间换时间
- 必须与函数定义体放在一起才能使函数内联
- 以下情况不宜使用inline
- 函数体代码较长
- 函数体内有循环
volatile关键字:修饰被不同线程访问和修改的变量,即修饰易变变量,保证每次读取时都重新读取
extern关键字:调用其他模块的变量或函数,要在本模块中用extern进行外部声明
void关键字
- 函数没有返回值或没有参数时,应声明为void类型
- 函数参数为任意指针类型时,声明为void *