编码规范C语言.docx
- 文档编号:5592527
- 上传时间:2022-12-28
- 格式:DOCX
- 页数:18
- 大小:22.56KB
编码规范C语言.docx
《编码规范C语言.docx》由会员分享,可在线阅读,更多相关《编码规范C语言.docx(18页珍藏版)》请在冰豆网上搜索。
编码规范C语言
编码规范(C语言)
1.引言
1.1简介
所有的程序开发手册都包含了各种规则。
一些习惯自由程序的人(例如C程序员)可能对这些规则很不适应,但是在多个开发人员共同协作的情况下,这些规则是必需的。
这不仅仅是为了开发效率,而且也为了测试和后期维护。
良好的编码习惯有助于标准化程序的结构和编码风格,使源代码对于自己和别人都易读和易懂。
在开发周期中越早使用恰当的编码规定,将会最大程度的提高项目的生产率。
良好的编码习惯除了代码格式,详细的注释外,还应该包括使用有助于提高程序效率的编码方式。
规范的开发有助于提高源码的可读性,可维护性,对于提高项目的整体效率更是不可缺少的(尤其是团队开发)。
1.2目的
本文是一套面向cprogrammer和cdeveloper进行开发所应遵循的开发规范。
按照此规范来开发C程序可带来以下益处:
代码的编写保持一致性;
提高代码的可读性和可维护性;
在团队开发一个项目的情况下,程序员之间可代码共享;
易于代码的回顾
2.命名规范
2.1文件命名规范
文件名必须由前缀和后缀组成,最好采用长文件命名格式;
文件名必须用英文字母表达,禁止使用中文;
对于几个单词组合表达的文件名,每个单词必须小写,单词之间用下划线“_”分割;
源文件后缀格式为.c,头文件后缀格式为:
.h。
例:
trade_rebuild.c,trade_rebuild.h
2.2变量命名规范
命名必须具有一定的实际意义,形式为xAbcFgh。
x由变量类型确定,Abc、Fgh表示连续意义字符串,如果连续意义字符串仅两个,可都大写,如OK。
表2-1变量类型缩写表
变量类型缩写
描述
例子
c
char
cGrade
b
BOOL
bEnabled
i
int
iLength
s
short
sLength
l
long
lOffset
p
指针
pAddr
f
float
fSpeedRate
d
double
dSpeedRate
st
struct
stParaInfo
un
union
unWeekDay
fp
文件描述符
fpTime
str
字符串
strVariable
局部变量中可采用如下几个通用变量:
nTemp,nResult,i,j(一般用于循环变量)。
变量应为名词或名词短语。
2.3常量命名和宏定义规范
常量和宏定义必须具有一定的实际意义;
常量和宏定义在#include和函数定义之间;
常量和宏定义必须全部以大写字母来撰写,中间可根据意义的连续性用下划线连接,每一条定义的右侧必须有一简单的注释,说明其作用。
例如:
#defineREPO_PRICE1000000/*回购价格*/
2.4函数命名规范
函数名用大写字母开头的单词组合而成,建议使用祈使动词或动词短语。
例如:
voidImportantPoint(void);
2.5结构体类型命名规范
结构体类型命名必须全部用大写字母,原则上前面以下划线开始;结构体变量命名必须用大小写字母组合。
例如:
typedefstruct{
charstrProductName[20];
charstrAuthor[20];
charstrReleaseDate[16];
charstrVersion[10];
longlMaxTables;
longlUsedTables;
}DBS_DATABASE;
DBS_DATABASEstDataBase;
2.6目录名命名规范
文件名必须由前缀和后缀组成,最好采用长文件命名格式。
文件名必须用英文字母表达,禁止使用中文。
对于几个单词组合表达的文件名,每个单词必须小写,单词之间用下划线“_”分割。
例如:
data_vender
3.注释
一般来说,注释的使用应按照以下原则:
注释应该能够帮助读者理解代码的功能和作用,应该有助于读者理解程序的流程;
注释要言简意赅;
错误的注释还不如不做注释;
重要的代码行或段落提示要加注释;
边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。
不再有用的注释要删除;
注释使用/**/。
以下将详细介绍注释的编写规范
3.1文件头部注释
文件开始注释内容包括:
公司名称、版权、作者名称、时间、模块用途、背景介绍、修订说明等,复杂的算法需要加上流程说明。
文件开头的注释模板:
/******************************************************************
**版权所有兴业银行
**文件名:
**版本:
X.X从0.1开始
**创建人:
中文名
**创建日期:
YYYY-MM-DD
**功能描述:
**修订记录:
**修订日期修订人修复的bug或者修订原因
******************************************************************/
3.2函数头注释
/*****************************************************************
**函数名:
**输入:
a,b,c
**a---
**b---
**c---
**输出:
x---
**x为1,表示...
**x为0,表示...
**功能描述:
**全局变量:
**调用模块:
**作者:
中文名
**日期:
YYYY-MM-DD
**版本:
X.X从0.1开始
**修订日期修订人修复的bug或者修订原因
****************************************************************/
3.3语句注释
对语句的注释必须放在其上方或右方相邻位置,不要放在下面;
在程序块的结束行右方最好加注释标记,以表明某程序块的结束;
过长的函数实现,最好将其语句按实现的功能分段加以概括性说明;
必须对不易理解的分支条件表达式加注释。
3.4常量、变量、宏的注释
在常量、变量(临时变量除外)和宏的声明前必须对其作适当注释,注释说明的要点是:
被保存值的含义(必须);
合法取值的范围(可选);
与其它数据,函数或模块的关系(可选)。
4.文件编写规范
4.1头文件构成
包含以下内容:
1)头文件头部注释;
2)防止重复包含的宏:
#ifndef_文件名_扩展名
#define_文件名_扩展名
3)包含文件部分(系统头文件、项目头文件、本地头文件)(可选);
4)宏定义部分(可选);
5)类型定义部分(可选);
6)结构体定义部分(可选);
7)函数或类的声明部分;
8)防止重复包含的宏:
#endif/*_文件名_扩展名*/。
4.2代码文件构成
包含以下内容:
1)源文件的头部注释;
2)包含文件部分(系统头文件、项目头文件、本地头文件)(可选);
3)宏定义部分(可选);
4)类型定义部分(可选);
5)结构体定义部分(可选);
6)函数定义部分。
注:
包含文件时禁止使用绝对路径。
对于代码文件内部使用的函数,应在代码文件的前面进行声明,并要指定static关键字。
例如:
staticvoid*ChoiceCommand(int);
5变量、常量使用规范
禁止对浮点型变量进行相等比较;
所有变量必须在使用前进行初始化;
最好不使用全局变量;
将全部变量的声明放在函数开始处;
最好用声明的常量代替代码中的经常出现的数字。
6函数编写规范
6.1函数的划分
良好的函数划分,必须能够自顶向下逐级抽象地展现设计思想,提高程序的易读性和自说明性;
函数必须是按功能划分的,每个函数必须只做一件事情(高内聚准则);
相关的一组函数之间的关联必须尽可能少(低耦合准则);
在不破坏高内聚准则和低耦合准则前提下,一个函数代码长度最好不超过100行。
6.2函数缩进
必须以4个空格键来表示一个缩进单位;
在不影响展示程序结构的前提下最好尽可能地减少缩进的层次;
使用如下缩进风格:
(以if为例)
if(expression)
{
statements//缩进四格
}
else
{
statements//缩进四格
}
6.3代码行内的空格
关键字之后要留空格。
象const、case等关键字之后至少要留一个空格,否则无法辨析关键字。
象if、for、while等关键字之后应留一个空格再跟左括号”(”,以突出关键字;
函数名之后不要留空格,紧跟左括号”(”,以与关键字区别;“,”之后要留空格,如Function(x,y,z)。
如果”;”不是一行的结束符号,其后要留空格,如for(initialization;condition;update);
赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如“=”、“+=”“>=”、“<=”、“+”、“*”、“%”、“&&”、“||”、“<<”,“^”等二元操作符的前后应当加空格;
一元操作符如“!
”、“~”、“++”、“--”、“&”(地址运算符)等前后不加空格;
象“[]”、“.”、“->”这类操作符前后不加空格;
对于表达式比较长的for语句和if语句,为了紧凑起见可以适当地去掉一些空格,如
for(i=0;i<10;i++)和if((a<=b)&&(c<=d))。
6.4长行拆分
代码行最大长度宜控制在70至80个字符以内。
代码行不要过长,否则眼睛看不过来,也不便于打印;
长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首(以便突出操作符)。
拆分出的新行要进行适当的缩进,使排版整齐,语句可读。
6.5简单语句
6.5.1赋值和表达式
每行只包含一条语句。
例如:
a=b+c;
count++;
6.5.2本地变量声明
本地变量的声明应在不同的行中。
例如:
inti=4;
6.5.3return语句
return语句后面的返回值不可以用括号包起来,除非是后面所跟为一个表达式。
例如:
returntrue;
return(a+b);
6.6复合语句
6.6.1括号的格式
复合语句是一个语句块被封装在{}中。
所有的复合语句建议采用如下的花括号形式:
{}中的语句应该单独作为一行。
例如:
if(i>0)
{
i++
}
在{}中的复合语句应该有层次;
如下的情况可以不使用花括号,如语句块中包含null语句,或者只有简单的一行。
6.6.2If语句
If(condition)
{
statements;
}
if(condition)
{
statements;
}
else
{
statements;
}
6.6.3for语句
for(initialization;condition;update)
{
statements;
}
6.6.4while语句
while(condition)
{
statements;
}
如使用无限循环,那么建议使用:
while(true)
{
statements;
}
6.6.5do-while语句
do
{
statements;
}while(condition);
6.6.6switch语句
switch(condition)
{
case1:
case2:
statements;
break;
default:
statements;
break;
}
6.7函数返回值规范
每个函数均有返回值,除非由接口定义的函数或者操作非常简单的函数。
对于有不同状态的返回值,建议用int型的返回值,0为成功。
对于出错类返回值,在同一层次的模块,用统一代码表示。
在函数的注释中要对函数的返回值加以说明,要说明各种不同类型的返回值以及它们的含义。
6.8其他
函数的输入参数和输出参数必须少于5个,当参数过多时,可以考虑将参数定义为一个结构体,并且将结构体指针作为参数;
对于超过3句以上的语句反复调用,最好封装为函数调用;
提供给外部使用的函数,禁止使用全局变量交换数据。
7异常和错误的处理
对程序中出现各种异常与错误,如除0错误、内存错误、数据库操作错误等都要捕获并记录日志。
对于异常和错误的抛出,采用函数返回值的形式返回,发生错误的函数或错误捕获函数要保证已将错误登记到日志中。
8定义系统目录结构
例(供参考):
src
|
--------系统目录名
|
--------build目录
|
--------conf目录
|
-------shell目录
|
-------src源码目录
|
-------main目录
|
------子模块1目录
……………..
|
------子模块n目录
|
----------public目录
|
----------util目录
9Makefile文件模板
1)Makefile请以模板为基础编写;
2)在Makefile中需统一指定setup目标行(参照模板),以方便系统的自动构建和发布;
3)在每次功能完成后或构建、发布前请执行setup目标,将目标文件(.o)发布到系统
的构建/发布目录。
#
#Module:
env
#Author:
SongFang
#Date:
2005.9.8
#
#-------------------------------------------------
#forRedHat9&Oracle9.2
#
#Oracleinclude&librarypath
ORAINCS=-I${ORACLE_HOME}/precomp/syshdr\
-I${ORACLE_HOME}/precomp/public\
-I${ORACLE_HOME}/rdbms/public\
-I${ORACLE_HOME}/plsql/public\
-I.\
-DLINUX-D_GNU_SOURCE-D_LARGEFILE64_SOURCE=1-D_LARGEFILE_SOURCE=1\
-DSLTS_ENABLE-DSLMXMX_ENABLE-D_REENTRANT-DNS_THREADS
ORALIBS=-L${ORACLE_HOME}/lib-L${ORACLE_HOME}/rdbms/lib
#Procincludepathsetting
PIPATH=include="${ORACLE_HOME}/precomp/public"\
include="${ORACLE_HOME}/precomp/syshdr"\
include="${ORACLE_HOME}/rdbms/public"\
include="${ORACLE_HOME}/plsql/public"\
sys_include="/usr/include"\
sys_include="/usr/include/linux"\
sys_include="/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/include"
#CCompilerinclude&librarypathsetting
CIPATH=
CLPATH=
CFLAGS=${CC_CFLAGS}${CIPATH}${CLPATH}
PFLAGS=${PIPATH}USERID=$(PFLAG_USERID)sqlcheck=SEMANTICSfips=NO\
code=KR_Cparse=FULL\
close_on_commit=YEScpool=YES
CC=${CC_COMPILER}${CFLAGS}
PC=proc${PFLAGS}
LB=ar-r
CP=cp
RM=rm-f
#-------------------------------------------------
.SUFFIXES:
.SUFFIXES:
.o.c
.SUFFIXES:
.o.pc
.SUFFIXES:
.obj.c
.SUFFIXES:
.obj.pc
.SUFFIXES:
.c.pc
.c.o:
$(CC)-o$(<:
.c=.o)-c$<
.pc.o:
$(PC)$<
$(CC)-c$(<:
.pc=.c)
$(RM)$(<:
.pc=.c)*.lis
.c.obj:
$(CC)-c$<
.pc.obj:
$(PC)$<
$(CC)-c$(<:
.pc=.c)
.pc.c:
$(PC)$<
#-------------------------------------------------
TARGET=env_build
AIM_PATH=$(DIST_AIM_PATH)
SHARE_OBJS=
NEW_OBJS=env.o
#-------------------------------------------------
all:
build
$(TARGET):
$(NEW_OBJS)
#$(CC)-o$@${SHARE_OBJS}$(NEW_OBJS)test.c
build:
$(TARGET)
clear:
build
@$(RM)$(NEW_OBJS)
setup:
build
@$(CP)$(NEW_OBJS)$(AIM_PATH)
clean:
@$(RM)$(TARGET)$(NEW_OBJS)
#-------------------------------------------------
10头文件模板
/******************************************************************
**版权所有YYYY,开发部门名称
**文件名:
command_controller.h
**版本:
0.1
**创建人:
XXX
**创建日期:
YYYY-MM-DD
**描述:
命令请求控制器的头文件
**修订记录:
**修订日期修订人修复的bug或者修订原因
**-----------------------------------------------------------------
******************************************************************/
/*
*$Header:
$
*$Revision:
$
*$Date:
$
*/
#ifndef_COMMAND_CONTROLLER_H
#define_COMMAND_CONTROLLER_H
#include
/*
*函数原型
*/
voidCommandController(int,structsockaddr*,int);/*命令请求控制器*/
#endif/*_COMMAND_CONTROLLER_H*/
11代码文件模板
/******************************************************************
**版权所有YYYY,开发部门名称
**文件名:
command_controller.c
**版本:
0.1
**创建人:
XXX
**创建日期:
YYYY-MM-DD
**描述:
命令请求控制器,完成命令报文转发处理
**修订记录:
**修订日期修订人修复的bug或者修订原因
**-----------------------------------------------------------------
******************************************************************/
/*
*$Header$
*$Revision$
*$Date$
*/
#include"command_controller.h"
/*
*返回命令报文对应的命令处理函数
*/
staticvoid*ChoiceCommand(int);
/*****************************************************************
**函数名:
CommandController
**输入:
iConnectedSocket,pClientAddr,iClientLen
**iConnectedSocket:
连接端口号
**pClientAddr:
客户端信息
**iClientLen:
pClientAddr的长度
**输出:
无
**功能描述:
命令请求控制器
**全局变量:
无
**调用模块:
命令监听程序
**创建人:
XXX
**创建日期:
YYYY-MM-DD
**版本:
0.1
**修订日期修订人修复的bug或者修订原因
****************************************************************/
void
CommandController(intiConnectedSocket,structsockaddr*pClientAddr,intiClientLen)
{
charstrBuf[32];
intiLen=0;
intiPocketId=0;
void(*commandProcess)(int)=NULL;
Log("[CommandController]receivedaconnectionfromclinet!
\n");
while
(1)
{
bzero(strBuf,sizeof(strBuf));
iLen=read(iConnectedSocket,strBuf,POCKET_ID_LENGTH);
if(iLen==POCKET_ID_LENGTH)
{
iPocketId=atoi(strBuf);
if((commandProcess=ChoiceCommand(iPocketId))!
=NULL)
{
(*commandProcess)(iConnectedSocket);
}
}
elseif(iLen>0)
{
Log("[CommandController]无效报文,忽略!
\n");
}
}
}
/*****************************************************************
**函数名:
ChoiceCommand
**输入:
iPocketId
**iPocketId:
报文ID
**输出:
命令报文处理函数指针
**功能描述:
返回命令报文对应的处理函数
**全局变量:
无
**调用模块:
命令请求控制器
**创建人:
XXX
**创建日期:
YYYY-MM-DD
**版本:
0.1
**修订日期修订人修复的bug或者修订原因
***************************************************************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编码 规范 语言