如何优雅地为程序中的变量和函数命名

如何优雅地为程序中的变量和函数命名,第1张

简言之,根据语意来选择词汇,别无它法……然而,有时我们会不知用什么词汇更合适。

当你想到某个抽象的东西,你更倾向于最先想到的词语,除非你故意不这样,这些词也会抢着出现,直到模糊或改变你的想法。

当你想到一个具体的对象,你觉得词穷,然后你想描述的已经看到了,然后你继续寻找更适合它的词。

哈哈,命名竟成了编程中最难的事~

Martin Fowler曾经在一篇文章中曾经引用过Phil Karlton的话:

There are only two hard things in Computer Science: cache invalidation

and naming things

他说这句话在很长的一段时间内都是他最喜欢的话。可见命名对于广大的程序员来说的确是个大问题。

对于我们中国人来说,问题可能出在两个方面:

– 自打学编程开始就没被教育过要重视命名。

这可以在谭浩强的《C语言入门》一书中可见一斑。《C语言入门》可以说是很多程序员在大学时学习的第一门编程语言使用的教材。而本书通篇都是各种

a,b,c,x,y,z 的命名方式。这种poor naming的方式被广大程序员纷纷效仿,导致如今在很多项目代码中随处可见。

– 命名需要一定的英文功底,而国内程序员的英文水平参差不齐。

很多程序员被教育后开始逐渐重视命名,但是受限于英文水平,不知道使用什么合适的英文词汇来命名。有的甚至直接把中文直译为英文的方式命名,或者直接用拼音来命名,反而得不偿失。

命名的重要性我想不需要过于强调。如今的软件开发早已不是求伯君那种单q匹马的时代。你写下的每一行代码都会在不久的以后被团队的其他人甚至你自己多次查看。如果是个开源项目,那么更会被全球各地的人查看源代码。所以代码的可读性就变得尤为重要。如果读者能够轻松读出你的代码的意图,那么就说明你的命名功底相当扎实。

比如在一个管理系统中,你使用这样的代码: a = b c

很容易让人摸不着头脑,虽然程序能够正常运作,但恐怕没人敢轻易修改这行他们不了解的代码。而如果修改成为这样: weeklypay =

hours_worked pay_rate; 那恐怕极少有人不懂这行代码的意图。

糟糕的命名也会导致大量无谓的注释,这是一个很容易跳进去的陷阱。下一段代码怕别人不明白你的意图,那么就加上注释。这貌似是一个很精妙的想法,实际上却南辕北辙。比如以下的注释:

int d; // elapsed time in days

貌似很容易让人读懂,但是问题还是很多。首先注释不能跟着所有的引用,在定义处了解了d的含义,继续往下看的话却很容易忘记;其次代码更新了,很可能会忘记修改注释,反而给把读者带入歧途。

与其用这样的注释,还不如直接重命名: int elapsedTimeInDays; 这样清晰易懂,还不用维护注释,何乐而不为?

那么如何着手来提高的自己的命名技巧那?

首先寻找一份公认的代码规范,并严格按照这样的标准执行。比如google开源了自己内部使用的语言编码规范,我们可以直接拿来使用。比如请看Google

Java的style guide,相当详实。除此之外还有C++等。这里收集了Google对各种语言的编码规范,非常具有参考价值。

标准的代码规范中的每一条都是有胜出的理由,值得我们遵从。但某些命名问题不一定只有一种最好的解决方式,这就需要团队自己建立起约定。比如对于Java单元测试类的命名方式,不同的团队可能不一样。比如有的团队喜欢以should开头,有的喜欢test开头,有的喜欢骆驼命名法,有些喜欢下划线命名法,每种方式有各自的利弊,没有一种能完全脱颖而出,所以需要团队自行制定。一旦确定使用某一种,那么一定要保持一致。

某些命名规范其实是可以进行自动化检查的,比如在Java应用的构建过程中可以引用checkStyle这款插件,对命名进行一些基本的检查,比如方法名、变量名是否遵循了一定模式等。这样在一定程度上可以强制大家遵守某些约定。自己以前曾经写过一篇文章,请参见这里。

最后要在团队中建立起code review的机制,通过code

review来相互监督纠正命名问题,并且这样更容易达成一致的命名约定,方便协作开发。code

review可以采取非正式会议评审的方式。最简单的方式就是每天找个固定时间大家一起聚在一个显示器前review每个人的代码,现场提出问题,当事人记录下来会后更改。这种方式非常高效。另外有的团队在嵌入代码时可能会引入一些代码评审机制,比如pull

request, cherry pick等。这种review方式比较重量级,反馈周期也较长,好处是可以保证最终迁入的代码是没有问题的。

很多语言和框架为了更加可读,都把命名玩出花来了。比如JavaScript生态圈中重要的单元测试工具Jasmine把测试函数以it命名,这样可以与参数连接起来成为一种表意的自然语言:

如何优雅地为程序中的变量和函数命名?

- 不同的代码段采用不同的命名长度。通常来说,循环计数器(loop

counters)采用1位的单字符来命名,循环判断变量(condition/loop

variables)采用1个单词来命名,方法采用1-2个单词命名,类采用2-3个单词命名,全局变量采用3-4个单词命名。

- 对变量采用具体的命名(specific names)方式,”value”, “equals”,

“data”在任何情况下都不是一种有效的命名方式。

- 采用有意义的命名(meaningful names)。变量的名字必须准确反映它的含义和内容。

- 不要用 o_, obj_, m_ 等前缀命名。变量不需要前缀标签来表示自己是一个变量。

- 遵循公司的变量命名规则,在项目中坚持使用同一种变量命名方式。例如txtUserName, lblUserName,

cmbSchoolType等,否则会对可读性造成影响,而且会令查找/替换工具(find/replace tools)不可用。

- 遵循当前语言的变量命名规则,不要不统一(inconsistently)地使用大/小写字母。例如:userName, UserName,

USER_NAME, m_userName, username, …。

以Java为例:

类名使用驼峰命名法(Camel Case):VelocityResponseWriter

包名使用小写:comcompanyprojectui

变量使用首字母小写的驼峰命名法(Mixed Case):studentName

常量使用大写:MAX_PARAMETER_COUNT = 100

枚举类(enum class)采用驼峰命名法,枚举值(enum values)采用大写。

除了常量和枚举值以外,不要使用下划线’_’

- 在同一个类不同的场景(contexts)中不要复用变量名。例如在方法、初始化方法和类中。这样做可以提高可读性和可维护性。

- 不要对不同使用目的的变量使用同一个变量名,而是赋予它们不同的名字。这同样对保持可读性和可维护性很重要。

- 变量名不要使用非ASCII字符(non-ASCII chars)。这样做可能会在跨平台使用时产生问题。

-

不要使用过长的变量名(例如50个字符)。过长的变量名会导致代码丑陋(ugly)和难以阅读(hard-to-read),还可能因为字符限制在某些编译器上存在兼容性问题。

- 仅使用一种自然语言(natural language)来命名变量。例如,同时使用德语和英语来命名变量会导致(理解)不一致和降低可读性。

- 使用有意义的方法名。方法名必须准确表达该方法的行为,在多数情况下以动词(verb)开头。(例如:createPasswordHash)

- 遵循公司的方法命名规则,在项目中坚持使用同一种方法命名方式。例如 getTxtUserName(), getLblUserName(),

isStudentApproved(),否则会对可读性造成影响,而且会令查找/替换工具不可用。

- 遵循当前语言的变量命名规则,不要不统一地使用大/小写字母。例如:getUserName, GetUserName, getusername,

…。

以Java为例:

方法使用首字母小写的驼峰命名法:getStudentSchoolType

方法参数使用首字母小写的驼峰命名法:setSchoolName(String schoolName)

- 使用有意义的方法参数命名,这样做可以在没有文档的情况下尽量做到“自解释(documentate itself)”

总之,命名问题只是整个编码规范中的一小部分,但是起的作用举足轻重,它是判断一个程序员是否专业的必要标准。

写程序没有既定的格式,当然一定要写得清晰啊。也就是要有良好的风格啊。一、程序内部文档应具备的规则 1、标识符应含有含义鲜明的文字。 含义鲜明的文字,能正确地提示程序对象所代表的实体。这对于帮助阅读者理解程序是非常重要的。如果用缩写的形式,那么缩写规则应该一致,并且应该给每个名字加注解。2、适当的注解 注解是程序员和程序读者通信的重要手段,正确的注解非常有助于对程序的理解。3、程序的视觉组织 程序的视觉组织可用阶梯式,结构化的程序风格对于我们实际编程也很有意义,可极大地改善代码的可读性。主要有代码注释和一致性缩进。 二、数据说明 数据结构的组织和复杂程序是在设计期间就已经确定了的,然而数据说明的风格却是在写程序时确定的。为了使数据更容易理解和维护,有一些比较简单的原则应该遵循。 1、数据说明的次序应该标准化。有次序就容易查阅。因此能够加速测试、调试和维护的过程。当多个变量名在一个语句中说明时,应按字母顺序排列这些变量。 2、数据结构复杂时,应加以说明其特点和实现方法。 三、语句构造 语句构造原则:每个语句应该简单而直接,不能为了提高效率而使程序变得过分复杂。下述规则的使用有助于语句简单明了。 1、不要为了节省空间把多行语句写在一行; 2、尽量避免复杂的条件测试; 3、尽量减少对“非”条件的测试; 4、避免大量使用循环嵌套和条件嵌套; 5、利用括号使逻辑表达式或算术表达式的运算次序清晰直观。 四、效率 效率三原则: 1、效率是性能的要求,需求分析时就应确定; 2、效率是靠设计提高的; 3、程序的效率和程序的简单程序是一致的。 运行时间 (1)写程序前先简化算术和逻辑表达式; (2)仔细研究嵌套的循环,以确定是否有语句从内层移到外层; (3)尽量避免使用多维数组; (4)尽量避免使用指针和复杂的表; (5)使用执行时间短的算术运算; (6)不要混合使用不同的数据类型; (7)尽量使用整数运算和布尔表达式 五、小结 其实风格是非常重要的,程序的外表是我们交流中不可缺少的东西。象我们常说的红颜命薄而归疚于外表太靓,也常听一些才子佳人的悲剧故事,提醒我们外表美而引出的一见钟情的浪漫不可取。可让人细想,才子佳人产生悲剧虽多,可也让人找到过心动和美好的感觉,做为一个人,活了一辈子,连那种感觉都未体验到,岂不比悲剧更加令人觉得可悲!编程亦然。

正确并形象地给函数、变量命名,不仅可以增加程序的可读性,也是程序员编程风格的一种反映。较好的命名习惯,可以有效的提高程序的可维护性。以下介绍几种常用的变量命名规则。

一、匈牙利命名法:广泛应用于MicrosoftWindows这类环境中。

这种命名技术是由一位能干的Microsoft程序员查尔斯·西蒙尼(CharlesSimonyi)提出的。匈牙利命名法通过在变量名前面加上相应的小写字母的符号标识作为前缀,标识出变量的作用域,类型等。这些符号可以多个同时使用,顺序是先m_(成员变量),再指针,再简单数据类型,再其他。例如:m_lpszStr,表示指向一个以0字符结尾的字符串的长指针成员变量。

匈牙利命名法关键是:标识符的名字以一个或者多个小写字母开头作为前缀;前缀之后的是首字母大写的一个单词或多个单词组合,该单词要指明变量的用途。

例如:bEnable,nLength,hWnd。

匈牙利命名法中常用的小写字母的前缀:

前缀类型描述

aArray数组

bBOOL布尔

byBYTE无符号字符

cchar字符

cbCountofbytes字节数

crColorreferencevalue颜色值

cx,cyCountofx,y(short)长度

dwDWORD双字(无符号长整形)

fFlags标志

fnFunction函数

g_Global全局的

hHANDLE句柄

iInteger(int)整数

lLong(long)长整数

lpLongpoint长指针

m_Datamemberofaclass类的数据成员

nShort(short)短整型

npNearpoint短指针

pPoint指针

sString字符串

szZeroterminatedstring以0结尾的字符串

tmTextmetric文本规则

uUnsignedint无符号整数

ulUnsignedlong(ULONG)无符号长整数

wWORD无符号短整数

x,yx,ycoordinates(short)坐标

vVoid空

有关项目的全局变量用g_开始,类成员变量用m_。

前缀类型例子

C类CDocument,CPrintInfo

m_成员变量m_pDoc,m_nCustomers

g_全局变量g_Servers

二、驼峰命名法:近年来越来越流行。

驼峰命名法,正如它的名称所表示的那样,指的是混合使用大小写字母来构成标识符的名字。其中第一个单词首字母小写,余下的单词首字母大写。

例如:

printEmployeePaychecks();

函数名中每一个逻辑断点都有一个大写字母来标记。

三、帕斯卡(Pascal)命名法:与驼峰命名法类似。

只不过驼峰命名法是第一个单词首字母小写,而帕斯卡命名法则是第一个单词首字母大写。因此这种命名法也有人称之为“大驼峰命名法”。

例如:

DisplayInfo();

UserName

都是采用了帕斯卡命名法。

在C#中,以帕斯卡命名法和骆驼命名法居多。

事实上,很多程序设计者在实际命名时会将驼峰命名法和帕斯卡结合使用,例如变量名采用驼峰命名法,而函数采用帕斯卡命名法。

四、下划线命名法。

下划线法是随着C语言的出现流行起来的,在UNIX/LIUNX这样的环境,以及GNU代码中使用非常普遍。

41函数的命名

函数名使用下划线分割小写字母的方式命名:

设备名_ *** 作名();

*** 作名一般采用:谓语(此时设备名作为宾语或者标明 *** 作所属的模块)或者谓语+宾语/表语(此时设备名作为主语或者标明 *** 作所属的模块)等形式,如:

tic_init();

adc_is_busy();

uart_tx_char();

中断函数的命名直接使用设备名_isr()的形式命名,如:

timer2_isr();

42变量的命名

变量的命名也采用下划线分割小写字母的方式命名。命名应当准确,不引起歧义,且长度适中。如:

intlength;

uint32test_offset;

单字符的名字也是常用的,如i,j,k等,它们通常可用作函数内的局部变量。tmp常用做临时变量名。

局部静态变量,应加s_词冠(表示static),如:

staticints_lastw;

全局变量(尤其是供外部访问的全局变量),应加g_词冠(表示global),如:

void(g_capture_hook)(void);

43常量及宏的命名

采用下划线分割大写字母的方式命名,一般应以设备名作为前缀,

防止模块间命名的重复。如:

#defineTIMER0_MODE_RELOAD2

#defineTIMER2_COUNT_RETRIEVE(val)((uint16)(65536-(val)))

当然,看作接口的宏可以按照函数的命名方法命名,例如:

#definetimer2_clear()(TF2=0)

#definetimer0_is_expired()(TF0)

据考察,没有一种命名规则可以让所有的程序员赞同,程序设计教科书一般都不指定命名规则。命名规则对软件产品而言并不是“成败悠关”的事,我们不要化太多精力试图发明世界上最好的命名规则,而应当制定一种令大多数项目成员满意的命名规则,并在项目中贯彻实施。

变量命名规则:

变量名必须是以字母、数字、下划线或$组成

变量名不能以数字开头

变量名不能是Java关键字

除了下划线、$之外,不包括任何其他特殊字符

变量名只能是字母(a-z

A-Z),数字(0-9),下划线(_)的组合,并且之间不能包含空格,数字不能放在变量名首位,并且不能使用系统关键字

这只个一个大流的命名规则,具体的根据你所使用的编辑语言不同也不是完全相同的

几种常见的程序命名规则

正确并形象地给函数、变量命名,不仅可以增加程序的可读性,也是程序员编程风格的一种反映。较好的命名习惯,可以有效的提高程序的可维护性。以下介绍几种常用的变量命名规则。

一、匈牙利命名法:广泛应用于Microsoft Windows这类环境中。

这种命名技术是由一位能干的 Microsoft 程序员查尔斯·西蒙尼(Charles Simonyi) 提出的。匈牙利命名法通过在变量名前面加上相应的小写字母的符号标识作为前缀,标识出变量的作用域,类型等。这些符号可以多个同时使用,顺序是先m_(成 员变 量),再指针,再简单数据类型,再其他。例如:m_lpszStr, 表示指向一个以0字符结尾的字符串的长指针成员变量。

匈牙利命名法关键是:标识符的名字以一个或者多个小写字母开头作为前缀;前缀之后的是首字母大写的一个单词或多个单词组合,该单词要指明变量的用途。

例如:bEnable, nLength, hWnd。

匈牙利命名法中常用的小写字母的前缀:

前缀 类型 描述

a Array 数组

b BOOL 布尔

by BYTE 无符号字符

c char 字符

cb Count of bytes 字节数

cr Color reference value 颜色值

cx,cy Count of x,y(short) 长度

dw DWORD 双字(无符号长整形)

f Flags 标志

fn Function 函数

g_ Global 全局的

h HANDLE 句柄

i Integer(int) 整数

l Long(long) 长整数

lp Long point 长指针

m_ Data member of a class 类的数据成员

n Short(short) 短整型

np Near point 短指针

p Point 指针

s String 字符串

sz Zero terminated string 以0结尾的字符串

tm Text metric 文本规则

u Unsigned int 无符号整数

ul Unsigned long(ULONG) 无符号长整数

w WORD 无符号短整数

x,y x,y coordinates(short) 坐标

v Void 空

有关项目的全局变量用g_开始,类成员变量用m_。

前缀 类型 例子

C 类 CDocument, CPrintInfo

m_ 成员变量 m_pDoc, m_nCustomers

g_ 全局变量 g_Servers

二、驼峰命名法:近年来越来越流行。

驼峰命名法,正如它的名称所表示的那样,指的是混合使用大小写字母来构成标识符的名字。其中第一个单词首字母小写,余下的单词首字母大写。

例如:

printEmployeePaychecks();

函数名中每一个逻辑断点都有一个大写字母来标记。

三、帕斯卡(Pascal)命名法:与驼峰命名法类似。

只不过驼峰命名法是第一个单词首字母小写,而帕斯卡命名法则是第一个单词首字母大写。因此这种命名法也有人称之为“大驼峰命名法”。

例如:

DisplayInfo();

UserName

都是采用了帕斯卡命名法。

在C#中,以帕斯卡命名法和骆驼命名法居多。

事实上,很多程序设计者在实际命名时会将驼峰命名法和帕斯卡结合使用,例如变量名采用驼峰命名法,而函数采用帕斯卡命名法。

四、下划线命名法。

下划线法是随着C语言的出现流行起来的,在UNIX/LIUNX这样的环境,以及GNU代码中使用非常普遍。

41 函数的命名

函数名使用下划线分割小写字母的方式命名:

设备名_ *** 作名();

*** 作名一般采用:谓语(此时设备名作为宾语或者标明 *** 作所属的模块)或者谓语 宾语/表语(此时设备名作为主语或者标明 *** 作所属的模块) 等形式,如:

tic_init();

adc_is_busy();

uart_tx_char();

中断函数的命名直接使用 设备名_isr() 的形式命名,如:

timer2_isr();

42 变量的命名

变量的命名也采用下划线分割小写字母的方式命名。命名应当准确,不引起歧义,且长度适中。如:

int length;

uint32 test_offset;

单字符的名字也是常用的,如i, j, k等,它们通常可用作函数内的局部变量。tmp常用做临时变量名。

局部静态变量,应加s_词冠(表示static),如:

static int s_lastw;

全局变量(尤其是供外部访问的全局变量),应加g_词冠(表示global),如:

void ( g_capture_hook)(void);

43 常量及宏的命名

采用下划线分割大写字母的方式命名,一般应以设备名作为前缀,

防止模块间命名的重复。如:

#define TIMER0_MODE_RELOAD 2

#define TIMER2_COUNT_RETRIEVE(val) ((uint16)(65536 - (val)))

当然,看作接口的宏可以按照函数的命名方法命名,例如:

#define timer2_clear() (TF2 = 0)

#define timer0_is_expired() (TF0)

据考察,没有一种命名规则可以让所有的程序员赞同,程序设计教科书一般都不指定命名规则。命名规则对软件产品而言并不是“成败悠关”的事,我们不要化太多精力试图发明世界上最好的命名规则,而应当制定一种令大多数项目成员满意的命名规则,并在项目中贯彻实施。

以上就是关于如何优雅地为程序中的变量和函数命名全部的内容,包括:如何优雅地为程序中的变量和函数命名、【求助】数据结构的程序题都是怎么命名各种变量的、程序段号怎样命名的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/10101786.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存