第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.14159265358979
  • DEG:角度转弧度系数,PI/180
  • RAD:弧度转角度系数,180/PI
  • TRUE:就是1
  • FALSE:就是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 运算符优先级

从高到低排列:

  1. 括号 ()
  2. 乘方 ^
  3. 乘除 * / MOD
  4. 加减 + -
  5. 关系运算符 == != > < >= <=
  6. 逻辑非 !
  7. 逻辑与 &&
  8. 逻辑或 ||

我个人建议:拿不准优先级时,加括号。别嫌麻烦,总比出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循环。到时候你就可以写真正有用的脚本了。记住,先把这章的基础练熟,写几个小例子试试。光看不练是学不会的。