工欲善其事,必先利其器
我觉得一个优秀的程序员,首先应该有个好的编程风格,我承认,编码除了实现自己设计意图的过程外,也是一个“加密”的过程,这个加密过程远比使用MD5的加密效果还要好的。
看一个编程风格不好的代码,有如破解密码,破解密码我们有现成的工具,算法和字典,还算好。可是在面对“加密”过后的代码。如果想破译的话,那么只能使用最原始的方法和方式。用自己的脑子一点一点缕顺层次和逻辑关系了,如果是随便翻翻还可以,看其精华部分就可以了,如果是自己工作当中遇到这样的代码,又必须弄清,则实为不幸了。
如果你想加密的你的代码,那么找一个没有编程经历,且熟悉多国语言,特别是还不是很精通所掌握语言的人来帮你,效果一定非常好,并且是不可逆的软件加密工程,十天二十天后,不说别人,就是你自己也会发现,再看不懂自己写的代码了。
代码现在来说还是手工制成品,它的功效可以通过CMM,标准流程,评审,测试予以保证,但是其效率和美观就完全在乎于作者了,好在我一开始的时候读到了一篇关于代码风格的文章,对我影响较深,一直一来都按牢记着文章中的要点,我也是实在不愿意看到自己的作品杂乱,所以比较注意,再一我对算法非常感兴趣,所以看到言简意赅的算法总是爱不释手,这些代码虽然简练,透着作者的功底,另一方面却有着非常好的风格体现着他的逻辑。记得自己对下面这段精美代码代码曾欣赏不已。
char *strcpy(char *strDest, const char *strSrc);
{
assert((strDest!=NULL) && (strSrc !=NULL));
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘\0’ )
NULL ;
return address ;
}
今天我就读到了一个不算好的工程代码,逻辑烦杂,命名混乱,一定是多个坚持且有个性的人完成的,变量名称、消息类型、有各式各样的风格,有不够严格的匈牙利法,也有严格的××人专用法,大量的数组长度,消息长度没有通过宏定义,还有很多直接打印的语句,如_dbException( dbPrn,mtPrnNor_M,(PCHAR)"_mhdOnLoadReq sizeof(req) over 15000! " );直接写死了数值?!如果这个请求大小扩大后,作者是否还能找到这行代码,并把其中的16000改成扩大后的数值么?这个工程有70万多行,相信不是件易事。今天读到的只是这个工程中的一小部分,想想即使70多万行的工程都精美绝伦,虽然运行正确,但就因为有这么一小块的不规范代码,就致使其不可能移植,没有人愿意改造它或是敢去改造这个已经商用的工程,非常的可惜,让70万行的精华损失殆尽!所以代码风格的作用是非常重要的。代码是手工制品,但是大多工艺品都是手工制品,为何不让你的作品能卖个好价钱?
看到这些代码,觉得有必要总结出来,用于自己即将开始的一个软件产品特写了一些要点注意,还未整理完成。
=======================================================================================================
|Describe |tag |remark
|=========+===================+=============================================================================
|模块 |Mdl |不用modle,太长;
|表 |Tbl |不用Table,太长;
|字段/属性|field |不用attribut,因为引起歧异;不简写
|元组/记录|tuple |不用rec或record,因为引起歧异;不简写
|结构标签 |TB*_T |如:“typedef struct TBTDistrParam_T{”,定义结构一定要有标签,且和结构体同名,有利于si快速定位
|结构名 |TB*_T |如:“}TBTDistrParam_T”,使用_T后缀代表其为结构体
|结构指针 |_FAR* LP_TB*_Ttb*()|如:“ _FAR* LP_TBTDistrParam_T”,定义结构时必须定义该此类型指针,方便定义指针变量 LP_TBTDistrParam_T lpDest;
|状态 |Stat |不用Status,太长;
|系统函数 |tb_模块_名词动词 |首名词大写,如:“tb_SystemInit(),tb_env_SystemInit()”,不能使用“tb_system_init()”,太长
|普通函数 |tb_名词动词 |首名词大写,如:“tb_OutPrint()”,
|宏函数 |TB_* |大写,如“#define TB_ASSERT(e) ((e) ? (void)0 : tb_assert(#e, __FILE__, __LINE__))”
|文件名 |模块+含义 |文件名小写,如“db_init.c ,log_init.h"
关于风格,不得不提到的就是匈牙利发,匈牙利法是一个比较完善和严谨的命名方法,传闻微软也采用该方法,但是也有缺点,就是会导致名称过长,在用到转义的时候会歧异。鉴于这些,较好的做法是取其精华,在对指针,结构函数名称上使用匈牙利命名方法。其他时不刻意使用,特别是不能用该法限定自己的变量无法转义。
在文章尾部有一个自己写的系统中的例子供指点。供指点,谢谢!
/******************************************************************************
* Copyright (c) Chen Lei Individual 2004. All Rights Reserved.
*
* 文件名称:基础函数代码库
* 文件标识:basefun.c
* 摘 要:定义了经常用到的有用子函数的代码实现
* 当前版本:3.1 for HP
* 作 者:陈 雷
* 完成日期:2005-1-17 1:24
*
* 更改记录:MM/DD/YY
* chenlei 08/24/06 - 修改了getLower(),因为执行不对
* chenlei 07/26/06 - 增加setprecision(),changeprecision()
* chenlei 04/14/06 - 增加getDateDiff(),getCmdOutput()
* 。。。
******************************************************************************/
#ifdef __HP__
#include "hp_specific.h"
#endif
#ifdef __SUSE__
#include "suse_specific.h"
#endif
#ifdef __SORLARIS__
#include "solaris_specific.h"
#endif
#ifdef __AIX__
#include "aix_specific.h"
#endif
/******************************************************************************
* 函数名称 :StringToInt(const char* cpString, int* iValue)
* 摘 要 :将字符串变为数字
* 输入参数 :cpString:字符串
* 输出数值 :0 转换成功;-1 转换失败
* 备 注 :#cpString = "23";
iRet = StringToInt(cpString, iValue);
iRet = 0;
iValue = 23;
#cpString = "23w";
iRet = StringToInt(cpString, iValue);
iRet = -1;
iValue = 23;
******************************************************************************/
int StringToInt(const char* cpString, int* iValue)
{
int i;
for (i=0; i<SafeStrLen(cpString); i++)
{
if ((cpString[i] > '9') || (cpString[i] < '0'))
{
*iValue = atoi(cpString);
return -1;
}
}
*iValue = atoi(cpString);
return 0;
}
Flyxx 2006-11-25 23:10:13
http://flyxx.cnblogs.com