3. KRL数据类型与变量
KRL 是强类型语言,每个变量在声明时必须确定数据类型,类型决定了它能保存什么值、占用多少内存、能参与哪些运算。工程中常见的错误——比如把 REAL 直接赋给 INT 导致编译报错、数组下标越界、结构体成员名拼错——根源往往不是逻辑问题,而是类型系统没吃透。本节围绕六类基本类型和两种复合类型,说明它们在真实程序中的声明方式与使用边界。
基本类型:INT、REAL、BOOL、CHAR
INT 是 32 位有符号整数,取值范围约 ±21 亿,工程中主要用于计数器、循环变量、数组下标、I/O 编号、枚举底层值。声明形式为 DECL INT nCount,赋值 nCount = 5。注意 KRL 的整数除法会截断:7/2 得到 3 而不是 3.5,涉及比例计算时必须先转 REAL。
REAL 是 32 位浮点数,用于位置坐标、速度、时间、角度等连续量。声明 DECL REAL fSpeed,赋值 fSpeed = 1.25。REAL 与 INT 之间不会隐式转换,DECL INT a; DECL REAL b; a = b 会报类型错误,必须写成 a = b 前先做取整处理,例如 a = b 在 KRL 中不允许,需借助 a = b 的显式转换函数或先 b = a 反向赋值。实际工程中更常见的做法是保持量纲一致,避免混用。
BOOL 只有 TRUE 和 FALSE 两个值,用于条件判断、使能标志、夹爪开合状态。声明 DECL BOOL bGripClosed,可写 bGripClosed = TRUE。BOOL 不能参与算术运算,bFlag + 1 是非法表达式。
CHAR 是单字符类型,占 1 字节,用于拼接提示信息或解析字符串。声明 DECL CHAR cLetter,赋值 cLetter = "A"。KRL 没有独立的 STRING 基本类型,字符串通常用 CHAR 数组表达,例如 DECL CHAR sMsg[20],此时它是数组而非基本类型。
ENUM:让状态可读
ENUM 是枚举类型,把一组有意义的命名常量绑定到整数值上,提升程序可读性并限制取值范围。声明格式为:
DEFINE STATE_T GRIP_OPEN = 0, GRIP_CLOSED = 1, GRIP_FAULT = 2
DECL STATE_T eGripState
之后可直接写 eGripState = GRIP_CLOSED,比 eGripState = 1 更清晰。ENUM 的底层仍是整数,因此可以比较、可以用于 CASE 分支,但不能直接赋任意整数,必须用枚举成员名。工程中常把设备状态、工位号、报警等级定义为 ENUM,减少魔法数字。
数组:同类型批量数据
数组用于保存同类型的多个值,声明时指定长度:DECL REAL fPos[6] 表示 6 个 REAL 元素,下标从 1 开始,合法范围是 1~6。访问 fPos[1] 到 fPos[6],越界会触发运行时错误。二维数组写作 DECL INT nMatrix[3,4],共 12 个元素。
数组常用于保存轨迹点、I/O 映射表、配方参数。例如把 6 个关节角存入 DECL REAL fJoint[6],再用循环遍历:
DECL INT i
FOR i = 1 TO 6
fJoint[i] = 0.0
ENDFOR
注意数组不能整体赋值,fJoint = fJoint2 非法,必须逐元素复制。初始化时可用循环或逐项赋值,KRL 不提供数组字面量初始化语法。
结构体:把相关变量打包
结构体(STRUC)把不同类型的数据组合成一个整体,适合描述一个工件的完整信息。声明格式:
DEFINE STRUC WORKPIECE_T
CHAR cName[16]
INT nType
REAL fLength
REAL fWidth
BOOL bInspected
ENDSTRUC
DECL WORKPIECE_T stPart
访问成员用点号:stPart.nType = 3、stPart.fLength = 120.5、stPart.bInspected = FALSE。结构体可以嵌套,也可以作为数组元素,例如 DECL WORKPIECE_T stBuffer[10] 表示 10 个工件记录,用 stBuffer[2].fWidth 访问第 2 个工件的宽度。结构体同样不能整体赋值,需逐成员操作,或借助 KRL 的 COPY 类机制(视控制器版本而定)。
声明位置与作用域
KRL 变量可声明在程序文件顶部的 DEF 区(全局,整个模块可见),也可声明在子程序内部(局部,仅该子程序可见)。全局变量用 DECL,局部变量同样用 DECL,但作用域不同。工程中应尽量缩小作用域:只在一个子程序里用的循环变量就声明在子程序内,避免全局污染和意外修改。
下面这张图把六类基本类型与两种复合类型的声明、典型用途和关键约束放在同一张关系图中,便于对照记忆。
工程中的选择原则
面对一个具体需求,先问“这个量是连续还是离散”。连续量(位置、速度、温度)用 REAL;离散计数、编号、下标用 INT;只有两种状态的用 BOOL;需要可读状态名的用 ENUM;一组同类型数据用数组;一组不同类型但描述同一对象的用结构体。例如一个码垛程序:垛位坐标用 REAL fPalletPos[3],层数用 INT nLayer,夹爪状态用 BOOL bGripClosed,工件信息用 WORKPIECE_T stBox,设备模式用 ENUM MODE_T。类型选对了,程序结构自然清晰,后续维护和排错也更容易。
1 TO 6 而数组长度只有 5;若结构体成员访问报错,核对成员名拼写与大小写,KRL 对标识符大小写敏感。