变量命名的3种常用方法(匈牙利、驼峰、帕斯卡)
变量命名的3种常用方法(匈牙利、驼峰、帕斯卡)
目录
2.3.1、HN命名法并不能帮助编译器进行类型检查也不加快开发速度
1、概述
随着计算机技术的不断发展,计算机计算能力的提升催生了大量大型软件的出现,大型软件的代码量动辄成千上万行,甚至数十万行。随着代码量的指数级增长,以前未曾注意的“小”问题也明显被放大。比如代码中的变量命名,这属于我们印象中的“小”问题,对于代码量小的程序来说,将变量命名为a、b、aa、string1、string2等类型,并不会影响程序的编写及阅读,如果是代码量大的程序,如果通篇都是字母、*1、*2等类型的变量名称,不仅在编写代码时容易出错,而且极不利于程序的阅读,那程序的后期维护就更难上加难了!所以如何有效地解决这些“小”问题也成了亟需研究的内容。
本文主要研究的是在代码编写时的变量、函数命名法。目前存在的主流命名法主要有匈牙利命名法、骆驼命名法、帕斯卡命名法。下面就对这三种命名法进行详细的介绍,并结合三种命名法的特点提出适合自己的命名规则。
2、匈牙利命名法
2.1、简介
匈牙利命名法(Hungarian Notation),是由1972年至1981年在施乐公司工作的程序员查尔斯.西蒙尼(Charles.Simony),此人后来成为微软的总设计师,因其祖籍是匈牙利,故有此名。
匈牙利命名法在国内之所以这么有名是因为当时微软对其推崇备至。在上世纪90年代,MFC的出现影响了一代代程序员,而MFC中各种类的命名是以匈牙利命名法命名的,再加上当时微软出了不错的书《Windows程序设计》推波助澜,而同时呢,国内UNIX编程风格氛围不强,这种命名法几乎成了国内变量命名法的标准。这就导致在现在的某些书籍或者项目中推荐使用匈牙利命名法
2.2、规则
匈牙利命名法的基本规则是:变量名=属性+类型+对象描述,其中每一个对象的名称都要求有明确含义,可以是对象名字全程或者一部分,同是要基于容易记忆理解的原则。
变量名中各部分的使用规范:
1) 属性部分
变量名的属性主要是表明该变量的属性,比如变量的作用范围(全局\局部)、成员变量、或者静态变量等。相关的表示如下:
全局变量 | g_ |
常量 | c_ |
类的成员变量 | m_ |
静态变量 | s_ |
2) 类型部分
类型值得是变量的类型,如整型、浮点型、字符串等。部分表示如下:
数组 | a | 长整型 | l |
指针 | p | 布尔型 | b |
函数 | fn | 浮点型 | f |
无效 | v | 双字节 | dw |
句柄 | h | 字符串 | sz |
短整型 | n | 双精度浮点型 | d |
计数 | cnt | 字符 | ch |
整型 | i | 字节 | by |
字节 | w | 无符号 | u |
3) 描述部分
描述部分通常用来表示该变量描述的意义,即该变量所表示的含义,部分标识如下:
最大 | Max | 最小 | Min |
初始化 | Init | 临时变量 | Temp |
源对象 | Src | 目的对象 | Dest |
4) 例子
变量定义的这些描述符号可以多个同时使用,顺序一般是m_,再指针,再简单数据类型,再其它。
hwnd: h类型描述,表示句柄;wnd是变量的对象描述,表示窗口,所以hwnd表示窗口句柄。
pfnEatApple: pfn是类型描述,表示指向函数的指针;EatApple是变量对象描述,所以pfnEatApple表示指向EatApple函数的函数指针变量。
m_lpszStr: m_表示是成员变量;l表示长整型;p表示指针;sz表示的是字符串;Str是对象描述;所以m_lpszStr的含义就是表示指向一个字符串的长指针成员变量。
由此可见,匈牙利命名法通过在变量名前面加上相应的小写字母的符号标识作为前缀,标识出变量的作用域;前缀之后的是首字母大写的一个单词或单词组合,主要指明变量的用途
2.3、匈牙利命名法存在的问题
匈牙利命名法是最有名但也是最有争议的一种命名方法。随着软件代码量的增加以及集成开发环境功能越来越强大,匈牙利命名法存在的问题也越来越突出。
2.3.1、HN命名法并不能帮助编译器进行类型检查也不加快开发速度
匈牙利命名法与其他命名法相比最主要的特点就是在变量名中指定了该变量的类型,在编译器功能还不是很强大的年代,这种命名法确实有它独到的优势。
但是随着编译器功能越来越强大,在编写代码时,如果需要的话是可以显示变量类型的,而且最主要也是把匈牙利命名法推下神坛的就是现代的集成开发环境都具有自动标记不匹配的类型的功能。
匈牙利命名法在编译器做类型检查时是多余的。特别是对于C++这样的强类型语言,一个提供类型检查的语言在确定一个变量与其类型一致时,比人眼仅仅检查变量的用法与变量名一致要强大得多
2.3.2、HN命名法保持前缀不利于代码重构
在代码的重构中,如果一个变量的类型改变了,那么对于该变量而言需要把所有的该变量名修改,因为该变量是把变量类型与变量名捆绑在一起 ,这样极不利于代码的移植。
一个众所周知的例子就是WPARAM类型,以及在许多Windows系统函数声明中使用的wParam参数。它原本是一个16位的类型(w描述的是Word类型),但在后来的操作系统中被改成了32位或64位,但仍保留原来的名字
2.3.3、HN命名法保持类型前缀会造成一定的冗余成本
HN命名法中,变量将类型从单一地点(变量声明处)复制到了多个地点(变量使用处),这会造成一定的冗余成本,其一就是前面提到的维护代码一致性的难题;其二就是占用了额外的空间与时间;空间是指为了保留这些含有变量类型的变量需要占用额外的代码行数,因为这种命名法不可避免的会造成变量名长度的增加;时间是指,在阅读代码时每当看到变量总是先去解析变量的类型,然后才会解析变量所代表的含义,这种“拐个弯”的想法总会造成在阅读代码时时间上的增加。比如定义了一个变量m_lpszName,我们首先回去解析m_lpsz所代表的含义,然后才知道原来这个变量代表的是名字。
在比如常见的字符串复制函数strcpy(pstrSource, pstrDest); 程序员需要从变量名中剔除pstr之类的前缀才能找到Source、Dest,才能理解变量的含义。相比strcpy(Source, Dest); 由于strcpy函数本身它已经规定了参数的类型,对于程序员来说只要一看到这个函数就会知道这两个参数的类型,所以,大部分情况下是没有必要按照HN命名法为变量命名的,也能避免一些不必要的冗余
3、骆驼命名法
3.1、简介
骆驼式命名法(CamelCase),又称驼峰命名法。正如名称CamelCase所表示的形式,是指混合使用大小写字母来构成变量和函数的名字。
驼峰命名法就是以单个单词或多个单词组成变量或者函数的唯一标识符时,第一个单词以小写字母开始,第二个单词以及后面的每一个单词的首字母大写,例如myFirstName、myLastName,这样的变量名看上去就像骆驼峰一样此起披伏,故此得名。
需要注意的是这些单词组成的标识符必须具有一定的意义,比如说:int studentNum; 通过变量名就能直观的看出变量所代表的意义,就学生数量,而程序员也可以根据变量名的意义大致猜测出变量类型,就向studentNum变量,既然是指学生数量,那肯定是整型数据了。
驼峰法有分小驼峰法、大驼峰法;
小驼峰法大多是用来标识变量,是驼峰法的常规用法,即第一个字母小写,其他单词首字母大写,例如:
int myStudentCount;
大驼峰法又称帕斯卡命名法,是把变量名称的第一个字母也大写。主要用于类名、函数名、属性、命名空间等,例如:
class DataBaseUser;
void GetUserName();
4、帕斯卡命名法
帕斯卡(Pascal)命名法又称大驼峰法,用法见上文
5、如何选用命名法
匈牙利命名法、驼峰命名法、帕斯卡命名法皆是针对代码编写时为了提高编码质量和效率而提出的一种变量命名规范,这三种命名规范既有优点也有缺点,不能只使用着一种命名规范,要根据相关情况综合使用这三种命名规范,主要目的还是为了是变量名便于记忆识别。下面就根据我的相关经验与认识谈谈我自己的命名规范
1) 变量的命名使用小驼峰法;函数、类型名等非常规变量采用大驼峰法;
2) 匈牙利命名法中关于变量属性的用法是可取的;在实际编写代码时回不可避免的用到全局变量,而在阅读时,往往无法识别出全局变量,总是用上下文查找的方法,这样很不方便,参考HN命名法中关于变量属性的使用,觉得在变量命名中引入属性的概念是很有帮助的。
全局变量 | g_ |
常量 | c_ |
类的成员变量 | m_ |
静态变量 | s_ |
3) HN命名法中关于指针的用法。在定义变量时加上p_的前缀;
4) 中间变量加上Temp后缀;如airTemp
5) 对于作用范围很小的变量,比如for循环中的渐变变量,可以使用极简形式的变量如i、j等 ;
6) 对于C++STL中类型的变量,比如map、list等,在声明变量时加上对应类型的后缀,如Map、Vector、List。如airMessageMap
7) 对于线程函数,加上Thread后缀;如ServerThread()
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)