本帖最后由 66球 于 2015-6-5 17:05 编辑 如何养成良好的编程习惯
原作者:兄弟工程师07 (按键学院实战班导师) 编辑:66球。。
本文由按键学院提供技术支持
按键学院交流①群(1群已满):376122403
按键学院交流②群(2群):372671254
按键学院交流③群(3群):170084238
写出优秀的代码是一门艺术 要想如此,就必须在一开始就养成良好的编程习惯。 良好的编程习惯不仅有助于脚本初期的设计(如模块化),还可以 使你编写的代码更易于理解,从而使脚本的维护工作更轻松、更省力。 不好的编程习惯则会造成代码 bug,并且会使以后的维护工作困难重重。 那么,如何才能写出一手规范的、让人一看就觉得像是出自高手之手的脚本呢? |
最近承蒙06、07老师轮番上阵,为我们做脚本框架搭建、编写技巧的培训,感觉受益匪浅,无意间又发现07老师早期写的关于如何养成良好编程习惯的帖子,感觉真心很赞,特此拿来分享并按个人理解修改下,希望之前没看过的童鞋都可以一看,特别对初入按键的新手来讲,相信会学到不少东西、少走弯路的 |
[tr=rgb(154, 205, 50)]如何养成良好编程习惯
|
变量命名
- 对于变量命名,禁止取单个字符(如a 、b 、c... ),除了要有具体含义外,还能表明其变量类型、数据类型等,但i 、j 、k 作局部循环变量是允许的。
- 关于变量命名的规范性(大家学习一下“匈牙利命名规则”)
单行单条语句
- 尽量不要把多个短语句写在一行中,一行中只写一条语句。
勤做注释
- 源程序有效注释量必须在20 %以上,注释应与其描述的代码相近。
- 对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。
- 注释与所描述内容进行同样的缩排。
注意运算符优先级
- 注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。
避免使用难理解语句 合理嵌套循环语句
- 在多重循环中,应将最忙的循环放在最内层 (减少CPU切入循环层的次数)
避免子程序/函数代码过长
- 绝大多数子程序/函数的代码在1-20行之间,子程序/函数名称需要能看出它做什么,名字不怕长,就怕短。
- 一个方法只能完成一个任务。即使该任务非常小(很多方法很有可能是一句话,不要嫌麻烦)。
- 绝大多数方法的圈复杂度不能超过10,如果超过必须进行分解。
避免子程序间过多的嵌套调用 变量使用前先定义
- 按键精灵处理Q语言代码可能会非常宽容,但还是建议不要太过依赖它的解析能力,因此养成懒散的编码习惯,变量使用前先作定义,子程序或者函数内的变量就在其内完成定义。
总是检查数据
- 要检查你的输入框输入的所有数据,一方面是为了安全性,另一方面也是为了可用性。用户随时随地都会输入错误的数据。这不是因为他们蠢,而是因为他们很忙,并且思考的方式跟你不同。用VarType 函数来检测你的输入框的输入是否合法。
避免全局变量
- 全局变量跟环境变量非必要情况尽量少用。因为在一个脚本中包含的所有代码都在同一个域中运行。所以如果你的代码中声明了全局变量的话,后面的脚本代码中的同名变量和函数会修改该变量,子程序/函数中使用的变量只在子程序中定义。
[tr=rgb(154, 205, 50)]尽量避免使用goto语句
|
为什么这么讲呢?当然并不是说goto语句就没有优点,具体的可以看下紫猫大大的帖子——
关于GOTO语句的利与弊主要是频繁使用goto语句,特别是回跳的goto语句,会使程序结构混乱、难于理解,举个例子- //超混乱的代码结构
- Rem 弹琴
- n = 1
- Delay 500
- KeyPress "1", 1
- Delay 18000
- FindColor 750,490,839,505,"FFFFFF",intX,intY
- //以下是条件判断;如果返回的坐标大于0,那么就说明找到了。
- While intX < 0 And intY < 0
- n=n+1
- Goto 弹琴
- Wend
复制代码改成这样思路就清晰多了(当然下面的代码也可以用do···loop循环语句替代)
- While intX < 0 And intY < 0
- Delay 500
- KeyPress "1", 1
- Delay 18000
- FindColor 750,490,839,505,"FFFFFF",intX,intY
- Wend
复制代码[tr=rgb(154, 205, 50)]擅于优化循环
|
1、比如上面讲的在多重循环中,应将最忙的循环放在最内层 (减少CPU切入循环层的次数)
2、减少循环时的计算次数
比如循环遍历一个数组
下面这段代码会在每次进入循环的时候都计算一次维数的最大可用下标。
- Dim A
- A = Array(10,20,20,50,40)
- For i = 0 To UBound(A)
- TracePrint A(i)
- Next
复制代码改成这样写就只计算一次了
- Dim A,len
- A = Array(10, 20, 20, 50, 40)
- len=UBound(A)
- For i = 0 To len
- TracePrint A(i)
- Next
复制代码[tr=rgb(154, 205, 50)]减少代码冗余度 |
1、也就是在不影响脚本功能的情况下,尽量用简短的代码
比如同样是定义数组并给其赋值,后者明显比前者简短得多。
- Dim A
- A(0) = 10
- A(1) = 20
- A(2) = 20
- A(3) = 50
- A(4) = 40
复制代码一条语句就完成了数组赋值。
- Dim A
- A = Array(10, 20, 20, 50, 40)
复制代码2、对一些脚本中需要重复使用的代码,根据实际需求,尽量把它封装成带相关参数的函数或子程序(注意子程序没有返回值),需要的时候直接call一下就好了,个人认为如果有必要连鼠标点击代码都完全可以被封装
(参数可以是延时,偏移坐标X,偏移坐标Y)
[tr=rgb(154, 205, 50)]擅于改进并选择最优算法
|
很多脚本里往往都会植入算法,而算法的好坏往往决定了一个脚本运行起来是否够效率,咱们不妨也举个例子:
比如有一天天上突然掉下了一个装有500万RMB的密码箱在你面前,已知这个密码箱的密码是5位数,该箱子密码的中间一位是1,同时这个5位数的密码还是81和91的倍数,上帝告诉你如果你能设计一个算法启动后0.1秒内得到正确的密码,这个密码箱就属于你,否则箱子就飞走了,你能设计出来吗? |
A算法代码:
- 启动时间 = Plugin.GetSysInfo.GetTime()
- For a= 1 to 9
- For b = 0 To 9
- For c = 0 To 9
- For d = 0 To 9
- For e= 0 to 9
- 合成后的五位数 = a * 10000 + b * 1000 + c * 100 + d * 10 + e
- If 合成后的五位数 mod 81 = 0 and 合成后的五位数 mod 91 = 0 and mid(合成后的五位数, 3, 1) = 1 Then
- TracePrint 合成后的五位数
- End If
- Next
- Next
- Next
- Next
- Next
- 结束时间 = Plugin.GetSysInfo.GetTime()
- TracePrint (结束时间-启动时间)//10001毫秒
复制代码B算法代码:
- 启动时间 = Plugin.GetSysInfo.GetTime()
- For i = 10000 To 99999
- If i mod 81 = 0 and i mod 91 = 0 and mid(i, 3, 1) = 1 Then
- TracePrint i
- End if
- Next
- 结束时间 = Plugin.GetSysInfo.GetTime()
- TracePrint (结束时间 - 启动时间)//6565毫秒
复制代码C算法代码:
- 启动时间 = Plugin.GetSysInfo.GetTime()
- P=10000\7371+1
- For a=P*7371 To 99999 Step 7371//81、91的最小公倍数是7371
- If mid(a, 3, 1) = 1 Then
- TracePrint a
- End if
- Next
- 结束时间 = Plugin.GetSysInfo.GetTime()
- TracePrint (结束时间 - 启动时间)//15毫秒
复制代码大家可以对比下这几种算法,明显发现算法c相比其他俩种算法快了N多,所以设置一个科学的、合理的算法也是比较重要的
暂时先写到这里,有关于脚本代码编写规范性更好建议的同学欢迎直接跟帖提出~
其他相关连院刊
【院刊】-【201408期】编写代码时,注释写还是不写
【院刊】-【201410期】按键精灵之变量的作用域
【院刊】-【201411期】如何成为优秀的程序猿
点此查看院刊总目录
谢谢大家阅读,记得给小编送支花花 ! 顺手点个赞