
编程的总则:编程首要是要考虑程序的可行性,然后是可读性、可移植性、健壮性以及可测试性。大多数程序员只是关注程序的可行性,而忽略了可读性,可移植性和健壮性,其实我个人认为,程序的可行性和健壮性与程序的可读性有很大的关系,能写出可读性很好的程序的程序员,他写的程序的可行性和健壮性必然不会差,也会有不错的可移植性。程序的可读性需要程序员有一个良好的编程风格。
好风格应该成为一种习惯。如果你在开始写代码时就关心风格问题,如果你花时间去审视和改进它,你将会逐渐养成一种好的编程习惯。一旦这种习惯变成自动的东西,你的潜意识就会帮你照料许多细节问题,甚至你在工作压力下写出的代码也会更好。
1、排版
a、代码缩进空格数为4个。若是可能,尽量用空格来代替Tab键,因为有些编译器不支持Tab键(我自己至今未见过,但确实有这个风险),这给程序的移植带来了问题。在keil中这个问题很容易解决,只需在在keil主界面的菜单栏点击Edit—Configuration…,弹出Configuration窗口,点击Editor标签,在其中C/C++ File:、ASM、Other Files栏下,选中Insert spaces for tab:复选框,Tab对应的框中填4,这样按tab键就相当于按下四个空格键。
BOOL BufClr(UINT8 * dest,UINT32 size)
{
if(NULL ==dest || NULL==size)
{
return FALSE;
}
}
b、较长的语句要分2行来书写,并用‘/’符号隔开。
uncrc=calcCRC16(Packet.p,unlen);
if((UINT8) uncrc != Packet.down_ser.mCrc[0] /
||(UINT8)(uncrc>>8)!= Packet.down_ser.mCrc[1])
{
BELL(ON);
}
c、 函数代码的参数过长,分多行来书写。
void UARTSendAndRecv(UINT8 *ucSendBuf,
UINT8 ucSendLength,
UINT8 *ucRecvBuf,
UINT8 ucRecvLength)
{
……
}
d、 if、do、while、switch、for、case、default等关键字,必须加上大括号{}。
if(bSendEnd)
{
BELL(ON);
}
else
{
BELL(OFF);
}
//--------------------------
for(i=0; i< ucRecvLength; i++)
{
ucRecvBuf[i]=i;
}
//--------------------------
switch(ucintStatus)
{
case USB_INT_EP2_OUT:
{
USBCiEP2Send(USBMainBuf,ucrecvLen);
USBCiEP1Send(USBMainBuf,ucrecvLen);
}
break;
case USB_INT_EP2_IN:
{
USBCiWriteSingleCmd (CMD_UNLOCK_USB);
}
break;
……
}
2、注释
a、 边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。不再有用的注释要删除。
注释应当准确、易懂,防止注释有二义性。错误的注释不但无益反而有害。
尽量避免在注释中使用缩写,特别是不常用缩写。
注释的位置应与被描述的代码相邻,可以放在代码的上方或右方,不可放在下方。
b、说明性文件必选在文件头着重说明,例如*.c、*.h文件
/***************************************************************************
* 定时器+计数器测频
*
* 文 件: frequency.c
* 作 者: 小瓶盖
* 说 明:定时器+计数机测频率
* 编写时间: 2010.3.17
* 版 本:1.0
* 修改日期: 无
*---------------------------------------------------------------------------
* 注: 本程序定义6个数码管,经过实测,在200HZ~50KHZ时结果较准确,误差小于0.4%,
* 50KHZ以上频率未进行测量.据资料表明,可以测量到120KHZ,本程序未证明.
*****************************************************************************/
#include
void func(void)
{
}
c、函数头应该进行注释,例如函数名称、输入参数、返回值、功能说明。
/**************将所有参数写入AT24C64,共4字节*********************
*说明:将表号和用户电量共四字节数据写入AT24C64中
*入口参数:
* 1.数据间接寻址地址-buf
* 2.写入到AT24C64的地址字-addh,addrl
* 3.写入字节数-count
*出口参数:1表示写成功,0表示写失败
***************************************************************/
bit write_byte(unsigned char * buf,
unsigned char addrh,
unsigned char addrl,
unsigned char count)
{
……
}
d、全局变量要注释其功能,若为关键的局部变量同样需要注释其功能。
volatile UINT8 __ucSysMsg=SYS_IDLE;
void SYSSetMsgPriority(void)
{
SYSMSG Msgt;//临时存储消息
UINT8 i;
}
e、复杂的宏定义同样要加上注释。
/* SYS_MSG_MAP 建立一个消息映射
宏参数NAME:消息映射表的名字
宏参数NUM_OF_MSG:消息映射的个数
*/
#define SYS_MSG_MAP(NAME,NUM_OF_MSG) do/
{/
DEFINE_MSG_NAME((NAME));/
UINT8 i;/
for(i=0;i< NUM_OF_MSG;i++)/
{/
ININ_CUR_MSG(i)/
}/
}while(0)
f、复杂的结构体同样要加上注释。
/* 奇偶校验结构体*/
typedef struct _ PKT_PARITY
{
UINT8 m_ucHead1; //首部1
UINT8 m_ucHead2; //首部2
UINT8 m_ucOptCode; //操作码
UINT8 m_ucDataLength; //数据长度
UINT8 m_szDataBuf[16];//数据
UINT8 m_ucParity; //奇偶校验值
}PKT_PARITY;
g、 相对独立的语句组注释。对这一组语句做特别说明,写在语句组上侧,和此语句组之间不留空行,与当前语句组的缩进一致。注意,说明语句组的注释一定要写在语句组上面,不能写在语句组下面。
文章来源: 博客园