嵌入式C编码规范 V01.docx
- 文档编号:11007364
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:21
- 大小:23.90KB
嵌入式C编码规范 V01.docx
《嵌入式C编码规范 V01.docx》由会员分享,可在线阅读,更多相关《嵌入式C编码规范 V01.docx(21页珍藏版)》请在冰点文库上搜索。
嵌入式C编码规范V01
目录
1前言3
2编码规范正文3
2.1格式3
2.1.1空行的使用3
2.1.2空格的使用3
2.1.4缩进3
2.1.5长语句的书写格式3
2.1.6清晰划分控制语句的语句块4
2.1.7一行只写一条语句,一行只声明、定义一个变量4
2.1.8在表达式中使用括号4
2.1.9将操作符“*”、“&”和变量名写在一起5
2.2注释5
2.2.1对函数进行注释5
2.2.2对文件进行注释6
2.2.3给出确认性注释6
2.2.4其它应该考虑进行注释的地方6
2.2.5行末注释尽量对齐7
2.2.6块注释7
2.2.7注释量7
2.3命名7
2.3.1标识符命名要求7
2.3.2标识符长度要求8
2.3.3文件命名要求8
2.4语句9
2.4.1赋值操作符约束9
2.4.2赋值表达式中的规定9
2.4.3禁用goto语句,尽量少用break和continue10
2.4.4避免对浮点数值类型做精确比较10
2.4.5malloc和free10
2.4.6对switch语句中每个分支结尾的要求10
2.4.7指针的初始化、使用和释放10
2.5函数11
2.5.1明确函数功能,将重复使用的代码编写成函数11
2.5.2尽量保持函数只有唯一出口,为函数指定返回值11
2.5.3函数声明和定义的格式要求11
2.5.4在函数调用语句中不要使用赋值操作符11
2.5.5保护可重入函数中的全局变量12
2.6程序组织12
2.6.1头文件中只包含声明,不应包含定义12
2.6.2可被包含的文件及头文件的格式13
2.7公共变量13
2.7.1严格限制公共变量的使用13
2.7.2明确公共变量的定义13
2.7.3防止公共变量与局部变量重名13
2.8宏13
2.8.1避免使用不易理解的数字,用有意义的宏来替代13
2.8.2括号在宏中的使用14
2.9其它14
2.9.1将不再使用的代码删掉14
2.9.2死循环14
2.9.3简短语句使用宏或inline14
2.9.4不要使用难懂的技巧性很高的语句15
1前言
本文档分别对C程序的格式、注释、标识符命名、语句使用、函数、程序组织、公共变量等方面做出了要求。
规范分为两个级别——规则和建议。
规则级的规范要求开发人员必须要遵守,建议级的规范开发人员应尽量遵守。
2编码规范正文
2.1格式
2.1.1空行的使用
规范级别:
规则
规则描述:
●在头文件和实现文件中,各主要部分之间要用空行隔开。
所谓文件的主要部分包括:
序言性注释、防止被重复包含部分(只在头文件中)、#include部分、#define部分、类型声明和定义部分、实现部分等等。
●在一个函数中,完成不同功能的部分,要用空行隔开。
2.1.2空格的使用
规范级别:
规则
规则描述:
●在使用赋值运算符、逻辑运算符、位运算符、算术运算符等二元操作符时,在其两边各加一个空格。
例:
nCount=2;而不是 nCount=2;
● 函数的各参数间要用“,”和一个空格隔开。
例:
void GetDate(intx,inty);
而不是void GetDate(intx,inty)或void GetDate(intx,inty)。
●不要在引用操作符前后使用空格,引用操作符指“.”和“->”,以及“[]”。
例:
pFont->CreateFont();而不是 pFont->CreateFont()。
●不要在一元操作符和其操作对象之间使用空格,一元操作符包括“++”、“--”“!
”、“&”“*”等。
2.1.4缩进
规范级别:
规则
规则描述:
对程序语句要按其逻辑以4个空格为单位进行水平缩进,使同一逻辑层次上的代码在列上对齐。
不允许使用Tab进行缩进。
2.1.5长语句的书写格式
规范级别:
规则
规则描述:
较长的语句要分成多行书写。
长表达式要在低优先级操作符处分新行,操作符放在新行之首,划分出的新行要进行适当的缩进。
例:
nCount=fun1(n1,n2,n3)
+(nNumber1*GetDate(n4,n5,n6))*nNumber1;
2.1.6清晰划分控制语句的语句块
规范级别:
规则
规则描述:
控制语句(if,for,while,do...while)的语句部分一定要用‘{’和‘}’括起来(即使只有一条语句),并且‘{’和‘}’应处在同一列上。
例:
if(x==0)
{
x++;
}
else
{
while(x>min)
{
x--;
}
}
2.1.7一行只写一条语句,一行只声明、定义一个变量
规范级别:
规则
规则描述:
一行只写一条程序语句。
一次(一条声明、定义语句)只声明、定义一个变量。
例:
//不要这样写
intx,y;
x=x0;y=y0;
while(isOk(x)){x++;}
//应该这样写代码
intx;
inty;
x=x0;
y=y0;
while(isOk(x))
{
x++;
}
2.1.8在表达式中使用括号
规范级别:
建议
规则描述:
对于一个表达式,在一个二元、三元操作符操作的操作数的两边,应该放置“(”和“)”。
例:
//下面这行代码:
result=fact/100*number+rem;
//最好写成这样
result=((fact/100)*number)+rem;
2.1.9将操作符“*”、“&”和变量名写在一起
规范级别:
规则
规则描述:
在定义指针、引用变量时,将操作符“*”、“&”和类型写在一起。
举例:
//不要象下面这样写代码:
char* s;
//而应该写成这样
char *s;
2.2注释
下面是关于注释的基本原则:
1.注释内容要清晰明了,含义准确,防止出现二义性。
2.边写代码边注释,修改代码的同时修改相应的注释,保证代码与注释的一致性。
2.2.1对函数进行注释
规范级别:
规则
规则描述:
●函数的声明之前,要给出精练的注释(不必牵扯太多的内部细节),让使用者能够快速获得足够的信息使用函数。
格式不做具体要求。
●函数的定义之前,要给出足够的注释。
注释格式要求如下:
/******************************************************************************
**函数名:
【必选】
**说明:
【必选】
**
**输入:
【必选】
**输出:
【可选】
**返回:
【必选】
**异常:
【可选】
******************************************************************************/
|
要求在
第80列
2.2.2对文件进行注释
规范级别:
规则
规则描述:
在头文件、实现文件的首部,一定要有文件注释,用来介绍文件内容。
注释格式要求如下:
/******************************************************************************
**
**Copyright(c)2008-20010bySHENZHENCO-TRUSTAUTOMATIONTECH.
**
**文件名:
【必选】
**说明:
【必选】
**版本:
【可选】
**创建日期:
【必选】
**创建人:
【可选】
**修改信息:
【可选】
**修改人修改日期修改内容
**
******************************************************************************/
2.2.3给出确认性注释
规范级别:
建议
规则描述:
建议对每个空循环体给出确认性注释,对多个case语句共用一个出口的情况给出确认性注释。
举例:
while(g_bOpen==FALSE)
{
//空循环
}
switch(nNumber)
{
case1:
nCount++;
break;
case2:
case3:
nCount--;
break; //当nNumber等于2或3时,进行同样的处理
default:
break;
}
2.2.4其它应该考虑进行注释的地方
规范级别:
建议
规则描述:
● 变量的声明、定义。
通过注释,解释变量的意义、存取关系等;
● 数据结构的声明。
通过注释,解释数据结构的意义、用途等;
●分支。
通过注释,解释不同分支的意义;
●调用函数。
通过注释,解释调用该函数所要完成的功能;
●赋值。
通过注释,说明赋值的意义;
●程序块的结束处。
通过注释,标识程序块的结束。
●其它有必要加以注释的地方;
2.2.5行末注释尽量对齐
规范级别:
建议
规则描述:
同一个函数或模块中的行末注释应尽量对齐。
2.2.6块注释
规范级别:
建议
规则描述:
在函数实现中尽量不要使用块注释。
因为很多IDE不支持块注释的嵌套,所以在调试过程中不能使用块注释快速的注释掉无用的代码。
举例:
//下面的代码注释
inti=0;/*注释*/
//建议改成这样
inti=0;//注释
2.2.7注释量
规范级别:
规则
规则描述:
注释行的数量不得少于程序行数量的30%。
2.3命名
2.3.1标识符命名要求
规范级别:
规则
规则描述:
在程序中声明、定义的变量、常量、宏、类型、函数,在对其命名时应该遵守统一的命名规范。
具体要求如下:
∙●一般变量名应以小写字母打头,各英文描述单词的首字母分别大写,其他字母一律小写,建议查看《匈牙利变量命名法则》。
对于不同作用域的变量,其命名要求如下表所示:
变量种类
前缀要求
示例
全局变量
g_
g_Number
全局指针变量
g_p
g_pNumber
函数级变量(局部变量)
无要求
number
函数级指针变量(局部指针变量)
p
pNumber
项目组或程序员可在该要求上再进行细化,但要保证符合该要求。
●常量的名字要全部大写。
常量指:
const修饰的量。
如constintNUMBER=100;
枚举量。
如enum{ONE,TWO,THREE};
●所有用宏形式定义的名字,宏常量,名字要全部大写;宏名称中意义不同的单词(缩写)应该用下划线分隔。
例如:
#defineCC2500_CS_BITBit_3。
●函数名应以大写字母打头。
例如:
voidGetCount();
●如果函数属于某功能或设备时,需要在前面使用前缀(xxx_)。
例如:
voidCC2500_GetCount();
●名中含多于一个单词时,每个单词的第一个字母大写。
如:
nLastCount中要大写L和C;
●不要使用以下划线“_”打头的标识符。
如:
_bFind是不允许出现的变量;
●不要使用仅用大小写字母区分的名称。
如:
bFind和BFIND;
●尽量使用有意义的名字。
应做到见其名知其意。
如:
strError表示错误的字符串;
●函数名应准确描述函数的功能,使用动宾词组为执行某操作的函数命名。
如:
InitSys();//表示初始化系统
2.3.2标识符长度要求
规范级别:
规则
规则描述:
在程序中声明、定义的变量、常量、宏、类型、函数,它们的名字长度要在4至25个字符之内(下限不包括前缀,上限包括名字中所有的字符)。
对于某些已经被普遍认同的简单命名,可不受本规则的限制。
如for循环的循环记数变量,可使用i、j等简单字符命名。
2.3.3文件命名要求
规范级别:
建议
规则描述:
代码文件的名字要与文件中声明、功能意义基本保持一致,使功能与类文件名建立联系。
例如:
将CC2500操作函数的头文件和实现文件命名为cc2500.h和cc2500.c就是一种比较简单、恰当的方法。
还可以将系统名称作为前缀。
例如:
MTD_CC2500.h和MTD_CC2500.c
2.4语句
2.4.1赋值操作符约束
规范级别:
建议
规则描述:
●在一条程序语句中,只应包含一个赋值操作符。
赋值操作符包括:
=,+=,-=,*=,/=,%=,>>=,<<=,&=,|=,^=,++,--。
例:
//不要这样写
b=c=5;
a=(b*c)+d++;
//应该这样写
c=5;
b=c;
a=(b*c)+d;
d++;
●不要在控制语句if,while,for和switch的条件表达式中使用赋值操作符。
赋值操作符包括:
=,+=,-=,*=,/=,%=,>>=,<<=,&=,|=,^=,++,--。
例:
//不要象下面这样写代码:
if(x-=dx)
{
...
}
//应该这样写:
x-=dx;
if(x)
{
...
}
2.4.2赋值表达式中的规定
规范级别:
建议
规则描述:
在一个赋值表达式中:
●一个左值,在表达式中应该仅被赋值一次。
●对于多重赋值表达式,一个左值在表达式中仅应出现一次,不要重复出现。
例:
//不要象下面这样写代码:
i=t[i++];//一个左值,在表达式中应该仅被赋值一次
a=b=c+a;//对于多重赋值表达式,一个左值在表达式中仅应出现一次,不能重复出现。
i=t[i]=15;//对于多重赋值表达式,一个左值在表达式中仅应出现一次,不能重复出现。
2.4.3禁用goto语句,尽量少用break和continue
规范级别:
规则
规则描述:
程序中不要使用goto语句。
在控制语句(for,do,while)块中,尽量少用break和continue,在switch中的case语句块不受该规则限制。
2.4.4避免对浮点数值类型做精确比较
规范级别:
规则
规则描述:
不要对浮点类型的数据做等于、不等于这些精确的比较判断,要用范围比较代替精确比较。
由于存在舍入的问题,计算机内部不能精确的表示所有的十进制浮点数,用等于、不等于这种精确的比较方法就可能得出与预期相反的结果。
所以应该用大于、小于等范围比较的方法代替精确比较的方法。
2.4.5malloc和free
规范级别:
规则
规则描述:
在支持malloc和free的系统中,局部的malloc和free要成对出现。
2.4.6对switch语句中每个分支结尾的要求
规范级别:
规则
规则描述:
switch语句中的每一个case分支,都要以break作为分支的结尾(几个连续的空case语句允许共用一个)。
一定要有default分支来处理其它情况。
2.4.7指针的初始化、使用和释放
规范级别:
建议
规则描述:
在定义指针变量的同时,对其进行初始化。
如果定义时还不能为指针变量赋予有效值,则使其指向NULL或0。
在代码中用ptr->fld的形式代替(*ptr).fld的形式。
当指针变量所指的内存被释放后,应该赋予指针一个合理的值。
除非该指针变量本身将要消失这种情况下不必赋值,否则应赋予NULL。
对于函数传递进来的指针变量在使用之前,应该尽量先判断它是否是空指针。
2.5函数
2.5.1明确函数功能,将重复使用的代码编写成函数
规范级别:
规则
规则描述:
函数体代码长度不得超过100行(不包括注释)。
将重复使用的简单操作编写成函数。
2.5.2尽量保持函数只有唯一出口,为函数指定返回值
规范级别:
建议
规则描述:
应该尽量保证一个函数只有一个出口。
要为每一个函数指定它的返回值。
如果函数没有返回值,则要定义返回类型为void。
2.5.3函数声明和定义的格式要求
规范级别:
规则
规则描述:
在声明和定义函数时,在函数参数列表中为各参数指定类型和名称。
举例:
//不要象下面这样写代码:
f(int,char*); //函数声明
f(a,b) //函数定义
inta;
char*b
{
...
}
//应该这样写:
f(inta,char*b);//头文件.h
f(inta,char*b)//实现文件.c
{
...
}
2.5.4在函数调用语句中不要使用赋值操作符
规范级别:
建议
规则描述:
函数调用语句中,在函数的参数列表中不要使用赋值操作符。
赋值操作符包括=,+=,-=,*=,/=,%=,>>=,<<=,&=,|=,^=,++,--。
举例:
//不要象下面这样写代码:
voidfun1(inta);
voidfun2(intb)
{
fun1(++b); //注意这里!
}
2.5.5保护可重入函数中的全局变量
规范级别:
规则
规则描述:
编写可重入函数时,若操作全局变量,则应加以保护。
如果全局变量不加以保护,当多个线程调用此函数时,很可能使此变量变为不可知状态。
例如:
假设 Exam是int型全局变量,函数Squre_Exam返回Exam平方值,如下函数不具有可重入性。
Unsignedintexample(intpara)
{
unsignedinttemp;
Exam=para;
temp=Square_Exam();
returntemp;
}
此函数若被多个线程调用, Exam 可能成为未知的。
可改为如下方式:
Unsignedintexample(intpara)
{
unsignedinttemp;
[申请信号量操作]
Exam=para;
temp=Square_Exam();
[释放信号量操作]
returntemp;
}
2.6程序组织
2.6.1头文件中只包含声明,不应包含定义
规范级别:
规则
规则描述:
在头文件中只包含声明,不要包含全局变量和函数的定义,内联函数的情况除外。
在源文件中只应该包含对类的实现,不应该包含任何类的声明。
类声明应该统一放到头文件中去。
2.6.2可被包含的文件及头文件的格式
规范级别:
规则
规则描述:
只允许头文件被包含到其它的代码文件中去。
避免头文件的重复包含。
头文件的格式如下:
#ifndefIDENT_H
#defineIDENT_H
...
#endif/*IDENT_H*/
IDENT_H建议使用该文件的大写文件名。
2.7公共变量
2.7.1严格限制公共变量的使用
规范级别:
建议
规则描述:
在程序中要尽可能少的使用公共变量。
在决定使用一个公共变量时,要仔细考虑,权衡得失。
2.7.2明确公共变量的定义
规范级别:
规则
规则描述:
当你真的决定使用公共变量时,要仔细定义并明确公共变量的含义、作用、取值范围、与其它变量间的关系。
明确公共变量与操作此公共变量的函数之间的关系,如访问、修改和创建等。
2.7.3防止公共变量与局部变量重名
规范级别:
规则
规则描述:
防止公共变量与局部变量重名。
2.8宏
2.8.1避免使用不易理解的数字,用有意义的宏来替代
规范级别:
建议
规则描述:
使用宏定义代替程序中的变量,这样便于以后系统的移植和维护。
举例:
//原程序
for(i=0;i<100;i++)
{
//……
}
//建议修改成
#defineMAX_VALUE100//头文件
for(i=0;i { //…… } 2.8.2括号在宏中的使用 规范级别: 规则 规则描述: 对于宏的展开部分,在宏的参数出现的地方要加括号“()”。 保证宏替换的安全,同时提高代码的可读性。 举例: //不要这样写 #defineGET_NAME(obj,ind)obj->name[ind] //应该这样写 #defineGET_NAME(obj,ind)(obj)->name[ind] 2.9其它 2.9.1将不再使用的代码删掉 规范级别: 规则 规则描述: 将程序中不再用到的、注释掉的代码及时清除掉。 如果觉得这些代码你可能以后会用到,可以备份到其它地方,而不要留在正式的版本里。 2.9.2死循环 规范级别: 建议 规则描述: //不建议使用 for(;;); //建议使用 while (1); 2.9.3简短语句使用宏或inline 规范级别: 建议 规则描述: 因为函数调用是要消耗额外的时间,所以在程序存储空间足够的情况下,对于比较简单程序(一句),应该使用宏或者inline。 2.9.4不要使用难懂的技巧性很高的语句 规范级别: 建议 规则描述: 复杂的语句不一定具有高效率,但是肯定不利于系统维护。 因此应该使用简单明了的语句。 举例: //复杂,难懂,易出错 *stat_poi+++=1; //改为 *stat_poi+=1; stat_poi++;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式C编码规范 V01 嵌入式 编码 规范