在软件开发中,数据结构和函数是整个软件必不可少的部分,对它的命名规则可能对整个项目的管理起着至关重要的作用。如果有一个良好的命名习惯,对于项目的开发和维护是相当有利的。这里我仅仅根据自己的体会,简单的阐述一下自己的心德,希望能够给读者一些有益的启迪,当然,也希望能够给我一些中肯的建议。
在很多项目中,有些设计者喜欢定义一些自己的数据类型,比如:
typedef signed char int8; typedef unsigned char uint8; typedef signed short int16; typedef unsigned short uint16; typedef signed int int32; typedef unsigned int uint32 |
虽然说,这种定义能够使用户对于使用的类型及其大小有清晰的理解,但是我们势必将为在不同CPU中定义许多宏,以确保定义的准确性。请看下表:
|
8bit CPU |
32bit CPU |
64bit CPU |
Char |
1 byte |
1 byte |
1 byte |
short |
2bytes |
2bytes |
2bytes |
int |
2bytes |
4bytes |
4bytes |
Long |
4bytes |
4bytes |
8bytes |
void * |
4bytes |
4bytes |
8bytes |
从表中,我们不难看出,对于不同类型的CPU,我们的必须一一却别,难道不累吗?我们现在的ANSC C已经帮助我们定义了一套整型变量,它们是
int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t等 |
它们已经被定义在<stdint.h>标准头文件中,对于不同的硬件平台,它会帮助我们自动校正,我们何乐而不为呢J?!
如果使用合适的前缀字母,能够帮助我们理解变量的类型。我一般喜欢这样命名这些类型。
类(Class) |
使用大写的C开头,比如:CSocket, CTimer,等等 |
接口(Interface) |
使用大写的I开头,比如:ISocket, ITimer,等等 |
结构(Struct) |
使用大写的S开头,比如:SSocketAttr, STimerAttr,等等 |
联合(Union) |
使用大写的U开头,比如:USocketParam, UTimerParam,等等 |
枚举(Enum) |
使用大写的E开头,比如:EResult, ESocketMode,等等 |
函数指针 |
使用大写的F开头,比如:typedef void (*FNotify)( void *arg ); |
为函数命名是仁者见仁,智者见智,没有什么统一的规定。我这里仅仅是按照自己的喜好规定了一套命名的规则,请大家多提一些宝贵意见。请看下面的结构
[项目名] |
模块名 |
[子模块名…] |
_ |
动宾结构 |
项目名是可选的,对于各个项目中的通用模块应该没有项目名。
模块名必须使用,若一个模块中有若干子模块,那么子模块名必须是命名的一部分,否则子模块名可以忽略。
动宾结构是动词+名词的方式,主要是为了用户便以理解。
上面的讲述可能过于抽象,不妨举几个例子吧。
在项目中,一般都会有操作系统抽象层,这个层主要是为了便于在各种不同操作系统上程序有良好的移植性。
OsaMutex_Create(…),Osa是Operation System Abstraction的缩写,它在多个项目中是一个公用部分,所以我们不该加上任何项目名。Mutex是Osa的互斥子模块,所以必须加入到命名中。‘_’是分隔字符,没有什么特别意思。因为对于互斥的创建没有需要的宾语,所以应该省去,仅仅保留一个动词。在有些情况下,宾语是必要的,比如:
OsaMutex_GetName()。此外,对于函数第一个字母,必须以大写开头。
再比如,我们在WYQ项目中,有一个状态机模块,那么它的函数可以如此命名。
WyqStateMachine_Goto( … ).
内部函数一般而言就是以static修饰的函数,用于模块内部的具体实现。它的命名规则也很重要,为了便于与接口函数分开,我们采用如下的方法。
__ |
[项目名] |
模块名 |
[子模块名…] |
_ |
动宾结构 |
与接口函数命名规则相似,唯一不同在于在函数名最前面以两个下划线开头。比如:
__OsaMutex_Create(…)就是OsaMutex_Create的内部实现,整个实现函数看上去如下格式:
EResult OsaMutex_Create( … ) { EResult rs; if ( 参数无效 ) return WYQ_EINV; rs = __OsaMutex_Create( … ); if ( rs == WYQ_OK ) 增加Mutex实例进入资源管理器 return rs; } |
它的命名规则有些类似于接口函数,不过它要比接口函数的命名规则更加的简单。
[项目名] |
模块名 |
[子模块名…] |
. |
h |
我们还是以Mutex为例,它的头文件的命名规则应该是OsaMutex.h。对于某些特有项目的接口函数头文件定义,也只要加入对应项目名就完事了,比如:WyqStateMachine.h。
它类似外部接口函数头文件的定义,紧紧在命名前面加入__字符。
__ |
[项目名] |
模块名 |
[子模块名…] |
. |
h |
比如__OsaLinuxMutex.h, __WyqStateMachineCore.h。
上面的几个小点仅仅说明了命名规则中的一个部分,应该还有其他很多很细的地方。不过从个人角度来看,我不喜欢被太多的游戏规则所限定,毕竟这样做的代价可能是埋没了很多软件人才的独特个性,难道不是吗?