第3章 ZPL基础语法:变量声明与数据类型、常量与枚举、运算符、表达式求值
好,咱们正式开始写代码了。这一章是ZPL的语法基础,说白了就是盖房子的砖头和水泥。你可能会觉得枯燥,但我跟你说,这些基础打不牢,后面写复杂脚本时你会哭的。我自己就吃过这个亏——刚开始学ZPL时,觉得变量声明太简单,结果写了个几百行的宏,最后发现变量类型搞混了,调试了整整一个下午。
3.1 变量声明与数据类型
ZPL是弱类型语言,这点跟Python有点像。你不需要像C语言那样提前声明变量类型,直接用就行。但别高兴太早,弱类型不代表没类型,只是解释器帮你自动判断了。
核心要点:ZPL中所有变量都是全局的,没有局部变量这个概念。嗯,这点跟很多语言不一样,你写函数时要注意。
3.1.1 基本数据类型
ZPL支持以下几种数据类型,我列个表给你看:
| 数据类型 | 说明 | 示例 |
|---|---|---|
| 数值型 | 整数或浮点数,ZPL不区分 | 3.14, -5, 1.2e-3 |
| 字符串型 | 用双引号括起来的文本 | "Hello", "曲率半径=50" |
| 布尔型 | 只有0和1,0为假,非0为真 | 0, 1 |
| 数组 | 用DECLARE声明的一维数组 | DECLARE arr, 10 |
你可能会问:为什么布尔型只有0和1?这就是ZPL的"土"地方。我在项目中遇到过,有人用2表示真,结果条件判断死活不对。记住:0是假,非0都是真,但最好只用1表示真。
3.1.2 变量命名规则
变量名其实挺自由的,但有几个坑你得避开:
- 变量名不能以数字开头(跟大多数语言一样)
- 不能使用ZPL关键字(比如IF、THEN、PRINT这些)
- 大小写敏感?不,ZPL不区分大小写。所以"abc"和"ABC"是同一个变量
- 变量名最长支持?我记得好像是80个字符,但没人会写那么长
我的习惯:变量名用有意义的英文单词组合,比如"lens_radius"、"field_height"。别用a、b、c这种,三个月后你自己都看不懂。
3.1.3 变量赋值
赋值用等号,简单粗暴:
radius = 50.0
thickness = 3.5
material = "BK7"
flag = 1
注意,字符串必须用双引号。单引号?不行,ZPL不认。我曾经因为这个被坑过一次,写了个字符串比较,怎么都不对,最后发现是引号用错了。
3.2 常量与枚举
常量就是固定不变的值。ZPL里没有专门的常量关键字,但有一些系统预定义的常量,你直接拿来用就行。
3.2.1 系统常量
ZPL里最常用的常量是光学系统相关的,比如:
PI:圆周率,3.14159265358979DEG:角度转弧度系数,PI/180RAD:弧度转角度系数,180/PITRUE:就是1FALSE:就是0
你想想看,如果每次都要自己写3.1415926,多麻烦。直接用PI就行了,精度还高。
3.2.2 枚举的替代方案
ZPL没有真正的枚举类型,但我们可以用常量来模拟。我在写镜头库管理脚本时,就经常这么干:
MODE_READ = 0
MODE_WRITE = 1
MODE_APPEND = 2
file_mode = MODE_READ
这样代码可读性就高多了。你看到MODE_READ就知道是读模式,比直接写0强百倍。
避坑指南:我曾经在项目中用数字0、1、2直接表示模式,结果后来要加个新模式,改得我头皮发麻。用常量名代替数字,这是血的教训。
3.3 运算符
运算符分三类:算术、关系、逻辑。咱们一个一个说。
3.3.1 算术运算符
这个你肯定熟悉:
| 运算符 | 说明 | 示例 |
|---|---|---|
| + | 加法 | a + b |
| - | 减法 | a - b |
| * | 乘法 | a * b |
| / | 除法 | a / b |
| ^ | 乘方 | a ^ 2 |
| MOD | 取余 | a MOD b |
注意,ZPL没有自增自减运算符(++、--),也没有复合赋值(+=、-=)。你得老老实实写:
i = i + 1
total = total * 2
嗯,确实有点原始,但习惯了就好。
3.3.2 关系运算符
关系运算符用来比较两个值,结果返回0或1:
| 运算符 | 说明 | 示例 |
|---|---|---|
| == | 等于 | a == b |
| != | 不等于 | a != b |
| > | 大于 | a > b |
| < | 小于 | a < b |
| >= | 大于等于 | a >= b |
| <= | 小于等于 | a <= b |
这里有个坑:ZPL里等于判断用两个等号,一个等号是赋值。我刚开始写时经常搞混,条件判断写成if(a=5),结果永远为真。你想想看,这bug多难找。
3.3.3 逻辑运算符
逻辑运算符用来组合多个条件:
| 运算符 | 说明 | 示例 |
|---|---|---|
| && | 逻辑与 | a && b |
| || | 逻辑或 | a || b |
| ! | 逻辑非 | !a |
注意,ZPL没有"短路求值"特性。什么意思?就是不管第一个条件成不成立,第二个条件都会执行。我在项目中遇到过,有人写了个条件,前面判断数组长度,后面访问数组元素,结果数组越界了。因为ZPL两个条件都执行了。
3.4 表达式求值
表达式就是变量、常量、运算符的组合。ZPL的求值顺序跟数学一样:先乘除后加减,括号优先。
3.4.1 运算符优先级
从高到低排列:
- 括号 ()
- 乘方 ^
- 乘除 * / MOD
- 加减 + -
- 关系运算符 == != > < >= <=
- 逻辑非 !
- 逻辑与 &&
- 逻辑或 ||
我个人建议:拿不准优先级时,加括号。别嫌麻烦,总比出bug强。
3.4.2 实际例子
咱们写个实际点的例子,计算透镜的有效焦距:
n = 1.5
r1 = 100
r2 = -50
t = 5
efl = 1 / ((n-1) * (1/r1 - 1/r2 + (n-1)*t/(n*r1*r2)))
PRINT "有效焦距 = ", efl
你看,这个表达式里既有算术运算,又有括号嵌套。ZPL会按照优先级一步步算,最后得到结果。
调试技巧:如果表达式结果不对,可以拆开算。比如先算1/r1,再算1/r2,看看中间结果对不对。我调试复杂公式时经常这么干。
3.4.3 字符串表达式
ZPL里字符串也能用加号拼接:
name1 = "BK7"
name2 = "SF11"
combined = name1 + " + " + name2
PRINT combined
输出结果是"BK7 + SF11"。这个在生成报告时特别有用,可以把变量值拼到字符串里。
3.5 本章小结
好了,这一章的内容就这些。变量声明、数据类型、常量、运算符、表达式求值,这些都是最基础的东西。你可能会觉得简单,但别小看它们。我见过太多人,基础没打好,写出来的脚本要么变量名乱起,要么表达式优先级搞错,调试起来痛苦得要命。
下一章咱们讲控制流——IF判断和FOR循环。到时候你就可以写真正有用的脚本了。记住,先把这章的基础练熟,写几个小例子试试。光看不练是学不会的。