| HighScore Plus 脚本入门(一)-马尔文帕纳科
本文由马尔文帕纳科亚太应用中心技术经理朱晓东供稿
HighScore Plus脚本所使用的语言是Object Pascal,继承自相对古老的Pascal编程语言,支持结构化和面向对象编程。它的优点包括代码的易读性、快速编译,以及支持多个单元文件从而实现模块化编程。作为已经不再流行的编程语言,可能在图书馆里才能翻得到它的出版教程了,但网络上依然保留了不少资源。Neil Moffatt的Delphi Basic、Marco Cantù的Essential Pascal(中文)和Tao Yue的Learn Pascal tutorial(Wiki化后的中文版)都可以给初学者提供不少帮助。
HighScore Plus软件里甚至内置了一个集成开发环境(IDE,Integrated Development Environment ),可以由菜单Tools - Script Editor调出,麻雀虽小五脏俱全,可以直接编辑、编译和调试代码。软件帮助系统的第11部分中罗列了HighScore Plus软件开放的可调用的对象模型及它们的属性、函数和过程。软件安装目录下的HelpExternals子目录下也放了不少.PAS的示例代码文件,可用于参考和学习;Documentation子目录下的Scripting in HighScore Plus.pdf文件中也举了大量的例子来告诉你如何实现某些功能。
本文的编写也参考了上述的文件和网络资源。
图1 HighScore Plus中内置的脚本编辑器
01丨程序结构
如下图,Pascal程序的基本结构由三部分组成:
图2 Pascal程序基本结构
程序首部:
以关键字program开头,用以标识这是一个程序;其后便是由用户自己定义的程序名称ExampleProgram;最后以半角分号(;)作为这一部分的结束。
声明部分:
声明部分可以省略,但凡是在程序中用到所有变量、常量、数组及自定义的数据类型、过程与函数等都必须在声明部分预先定义,也就是说,不允许不声明就使用;声明部分中可以包含:
使用指令:以关键字uses开头,要在程序中引用的单元(相当于模块),以便在程序中使用在单元中定义好的过程、函数和类等等;一般System单元不用特地声明引用;如程序中不需要引用额外的单元,此部分可省略;
类型声明:以关键字type开头,基于已有数据类型构建自定义的数据类型,以在程序中使用;如没有自定义新数据类型的必要,此部分可省略;
常量声明:以关键字const开头,定义在程序中会使用到的常量;如无必要可省略;
变量声明:以关键字var开头,定义在程序中会使用到的变量;如果程序中用不到自定义的变量,此部分可以省略;
子过程、子函数定义;如无必要可省略;
程序主体:
程序主体由begin开始,end.(注意,不要遗漏这个点符)结束,两者中间则是执行语句。
Pascal程序代码不管哪一部分,语句末尾都必须有半角分号(;)以示这一语句的结束,但允许end前面的那一个语句省略分号;多个语句可以用一对begin和end;(注意,这里有半角分号)包含起来作为一个程序块,程序块多用于子过程、子函数等的定义以及流程语句;代码里最后一个end后的点符(.)代表整个程序的结束。
Pascal语言中,程序名称、常量名称、变量名称等这种自定义的名称统称为标识符。标识符必须以一个英文字母或者下划线(_)开始,后面可以是英文字母、数字或下划线,长度不限;但不能与Pascal语言已占用的有特殊含义的关键字/保留字(如program)相同。标识符以及关键字都不区分大小写,因此exampleprogram、ExampleProgram、EXAMPLEPROGRAM和eXaMpLePrOgRaM这几个名称都是相同的,但为了代码的可读性,建议遵循一定的命名书写规范,有意义地使用大小写。
在图2中可以看到,在脚本编辑器默认的代码高亮规则下,部分代码以绿色斜体显示,这些是不被编译也不被执行的注释。注释同样是代码的一部分,主要用来写一些说明,以让代码更容易理解,也可以用来在不删除的情况下屏蔽有问题的代码。Pascal语言支持三种注释方式:一对半角大括号({ })、一对带星号的半角小括号((* *))以及双斜线(//)。
图3 注释
在HighScore Plus的脚本编辑器中,当点开工具栏中第一个按钮并点击New Script项新建一个脚本时,在Script Name框中输入的脚本名称同时默认为程序名称;输完名称后,点击OK按钮,即会新建一个完整结构的空白的脚本。
图4 新建脚本
02丨数据类型及赋值、运算
Pascal语言中包含了以下基本数据类型:
整数类型:最基础的是integer类型,其数据范围一般情况下已足够使用,如果需要更大的整数范围,可以用longint类型甚至int64类型;
实数类型:也称浮点数型,最基础的是real类型,但不提倡用,建议用single单精度实型或double双精度实型,要更大范围得话,还可以用extended扩展实型;
字符类型:最基础的是char类型,即ASCII字符,一般用一对半角单引号将单个字符括起来,如‘a‘、‘@’等(注:半角单引号需多用一个单引号转义,即’’’’),也可以用井号加0~255以内的整数表示第几个ASCII字符,如#65即为‘A’;双字节的Unicode字符可以用widechar类型来支持;多个字符组成的字符串则可以用string类型;
布尔类型:最基础的是boolean类型,只有TRUE(真,值为1)和FALSE(假,值为0)两个值;
常量的赋值直接在声明部分中声明常量的同时完成,而且不必特别要求其数据类型,编译器会根据所赋的值自动选用合适的数据类型;赋值时,直接用等号(=)赋值;赋值后,在程序中可以用常量的标识符来使用其值,但无法修改其值。对于一个在程序中到处会用到,而且程序运行中保持不变的值,建议用常量来存储,然后在执行代码中使用这个常量的标识符,这样当要改这个值时,就不用到执行代码中到处查找这个值然后修改,而是可以轻松地直接在常量声明中修改一次就成。
图5 常量的声明与赋值
变量的值在程序运行的过程中可以更改,但使用前必须先声明好。在程序的声明部分中声明的变量称为全程变量,可以在整个程序(包括子过程、子函数中)中使用;在子过程、子函数中声明的变量,称为局部变量,只能在声明它的子过程或子函数中使用。变量一般在执行语句中用赋值符(带半角冒号的等号,即:=)赋值;全程变量也可以在声明的同时用等号(=)赋初值,但不建议这么做。在声明变量时,必须用半角冒号(:)要求变量的数据类型;不赋初值的情况下,一个语句可以声明同一类型的多个变量,这些变量的标识符须用半角逗号(,)分隔开。
图6 变量的声明与赋值
一般的工作可能前面所讲的那些数据类型已经足够使用了,但涉及到相对复杂的、要处理大量数据的工作时,通过定义很多个变量去实现很显然不太现实,此时对于同一类型的大量数据,就可以用数组来处理。
数组可以通过“array[下标范围] of 数据类型"来定义,其中下标值一般是整数类型。[下标范围]可以省略:定义时省略了[下标范围]的数组称为动态数组,使用前必须先用函数setlength设置其大小,设置后,动态数组的下标总是从零开始;定义时要求了下标范围的数组称为静态数组,下标范围可以按需要设置,以[下标下届..下标上届](用两个半角点符隔开,相当于从几到几的连续整数)的格式定义,下标值甚至可以是负数;如果要定义多维数组,可以通过套娃的方式定义,也可以在[ ]里定义多组下标范围。当声明了一个数组变量,则该数组变量中的各个元素就共用一个数组名(即该数组变量标识符),通过下标的不同以区别不同的元素,可以通过“数组名[下标]"来引用数组元素;对数组的操作归根到底就是对数组元素的操作,数组元素可以像同类型的普通变量那样操作。
图7 数组的声明与赋值
上图中第30行中的“[true, true, true, true, true, false, false]"是一个直接常量(直接以字面形式,而非标识符表示的常量,如前面附图中赋值语句等号右侧的那些数值或字符,2.7182818、10086、true、’A’ 等)数组,用一对半角方括号([ ])将各元素括在其中,元素之间用半角逗号(,)分隔。
变量在赋值时,赋值号的右侧除了用直接常量外,也可以是一个运算表达式,运算表达式中可以带有变量或常量。
数字的计算使用算术运算符,除了常规的四则运算:加(+)、减(-)、乘(*)、除(/)外,还有整除(div)和取模(除法取余数,mod);运算时,先乘除(整除和取模和乘除同一优先级)后加减,当然括号优先级最高(由内向外逐层降低),相同优先级则从左往右顺序计算;
图8 数字的算数运算
关系运算符(=、<>、>、<、>=、<=)则可以用来判断两个数之间的大小关系,其结果是布尔类型;关系运算符的优先级是zui低的;
图9 数字的大小比较
逻辑运算符则用来处理布尔类型的量,包含:not(非,只有一个运算对象,结果取运算对象的相反值)、and(且,只有两边都为真,结果才为真)、or(或,两边有一个真,则结果就为真)、xor(异或,两边不一样,则结果为真);not优先级最高,其次是and,与乘除同一级别, or和xor则与加减并列;
图10 布尔值的逻辑运算
对于字符(串),有连接运算符(加号,+)用来将两边的字符(串)连成一个字符串;关系运算符也可以用于字符串的比较,比较时,两个字符串从左往右按ASCII码值逐个比较,遇到不相等时,码值大的字符所在的字符串为大,因此小写字母>大写字母>数字。
图11 字符(串)的运算
除上述数据类型外,还有枚举、集合(图5中声明的常量Letters就是一个点亮大小写字母的52个字符的集合)、记录、指针、文件、类等等类型,本文中不再赘述,感兴趣的可以参考Essential Pascal、Delphi Basics、Learn Pascal tutorial等网络资源中的说明。