首页 > 基础教程 > SCL基础教程 > 文章内容

SCL PLC 编程教程第七篇 数组、结构体、字符串的处理方法:为什么 SCL 更适合做复杂数据处理

时间: 2026-04-28 13:42浏览量:69次


很多工程师第一次正式接触数组、结构体、字符串时,心里都会有一点别扭。
因为在以前以梯形图为主的编程习惯里,大家更熟悉的是:

一个按钮
一个输出
一个中间位
一个定时器
一个设定值
一个故障位

也就是说,很多时候我们处理的是“单个变量”。

但一旦项目复杂起来,你会很快发现,工程实际根本不是一直在处理单个变量。
你经常会遇到这些情况:

20 路报警
16 路输入状态
8 路温度采样
一整套配方参数
一整组电机状态
一批工件信息
一组扫码字符
一串通信报文内容

这时候,如果你还一直按“一个变量一个变量地散着写”,程序会越来越难看、越来越难维护。

而数组、结构体、字符串,正是帮助你把这些“零散数据”组织起来的工具。

所以这一篇,你不要把它理解成三个孤立的知识点。
更准确地说,它们共同解决的是一个问题:

当 PLC 程序面对一组数据、一类数据、或者文本数据时,怎样把它们组织得更清楚。

一、先记住这一句最重要的话:单个变量是点,数组和结构体是在组织“数据的形状”

这句话可能一开始稍微抽象一点,但非常值得你理解。

比如以前你可能只写:

Temp1
Temp2
Temp3
Temp4

看起来也能表示四个温度值。
但这种方式的问题是,它只是四个散点。

如果你改成数组:

Temp[1]
Temp[2]
Temp[3]
Temp[4]

那它们立刻就从“四个分散变量”变成了一组有顺序的数据。

再比如你以前可能有:

Motor1_RunCmd
Motor1_RunFB
Motor1_Fault
Motor1_Overload
Motor1_SpeedSP

这也能写。
但如果你用结构体去组织,意思就完全不一样了:

这个数据不再只是几条散乱的变量,而是“1 号电机的完整信息集合”。

也就是说:

数组解决的是“同类数据成组”的问题
结构体解决的是“同一对象的多项属性组织在一起”的问题
字符串解决的是“文本数据怎么表示和处理”的问题

这三者一旦真正理解,你的程序结构感会明显提升。

二、为什么 PLC 项目越来越需要这些数据组织方式

很多人一开始会觉得:

“我做现场控制,真的需要数组和结构体吗?”

答案是:
项目越简单,越感觉不明显;项目越复杂,越离不开。

因为设备一复杂,控制就不再只是几个点位开关了。你会越来越频繁地碰到这些需求:

1. 批量处理一组同类对象

例如:

所有报警位统一复位
所有温度点统一超限判断
所有输入点统一做状态扫描
所有产品槽位统一检查占用情况

这时候数组就非常自然。

2. 组织一个对象的完整信息

例如一个气缸,不只是“有个输出位”,它还可能有:

伸出命令
缩回命令
伸出到位
缩回到位
动作超时
故障状态
自动允许
手动允许

这些信息如果散着写,后面非常容易乱。
而结构体可以把它们聚合成“一个对象的一组属性”。

3. 处理文本类数据

例如:

扫码器读到的条码
产品型号名称
报警描述
配方名称
通信字符串

这时候字符串就会变得很重要。

所以你可以这样理解:

数组、结构体、字符串,不是为了让程序显得高级,而是为了让复杂数据不至于散掉。

第一部分:数组
三、数组到底是什么

数组最简单的理解就是:

把一组同类型的数据,按顺序放在一起,并用下标来访问。

这句话里有两个关键词:

第一,同类型

也就是说,这一组里的元素通常类型一致。
比如都是 BOOL,或者都是 INT,或者都是 REAL。

第二,有编号顺序

也就是说,你不是靠不同变量名区分它们,而是靠“第几个”来区分。

例如:

Alarm[1]
Alarm[2]
Alarm[3]

这就表示一组报警位。

如果换成以前那种散写方式,可能就是:

Alarm1
Alarm2
Alarm3

表面看差不多,
但一旦你要循环处理、批量复位、统一比较,数组的优势就会越来越明显。

四、数组最适合处理什么场景
1. 一批规则相同的数据

例如:

16 路输入状态
8 路模拟量
20 路报警位
12 个工位占用状态

只要这些数据的处理规则相似,数组通常都很合适。

2. 需要配合循环批量处理的场景

前一篇我们讲过 FOR 循环。
数组和 FOR 几乎是天然搭档。

例如:

FOR i := 1 TO 16 DO
    IF SensorOK[i] = FALSE THEN
        FaultExist := TRUE;
    END_IF;
END_FOR;

这种逻辑如果不用数组,会写得非常散。

3. 顺序明确、编号明确的对象集合

例如:

第 1 到第 10 个工位
第 1 到第 8 路温度
第 1 到第 32 个报警点

这些都非常适合数组。

五、数组和“很多个类似变量”最大的区别是什么

这点一定要讲透。

例如你有 8 路温度,你可以这样写:

Temp1
Temp2
Temp3
Temp4
Temp5
Temp6
Temp7
Temp8

这样当然也能做。
但问题在于,这 8 个变量在程序眼里,其实彼此没什么结构关系。
你自己知道它们是“一组温度”,但程序只是看到 8 个独立名字。

而如果你写成:

Temp[1]
Temp[2]
Temp[3]
...
Temp[8]

那它们就正式成为一组可遍历、可统一处理的数据。

差别就在这里:

很多个类似变量,只是“看起来像一组”;
数组,是“真正被程序当成一组”。

这也是为什么数组一旦用起来,程序会更像“规则处理”,而不是“零散堆逻辑”。

六、数组最常见的工程用途
1. 批量报警处理

例如:

一键清除所有报警位
遍历查找第一个故障报警
统计当前有几个报警正在激活
2. 多通道模拟量处理

例如:

对 8 路温度统一限幅
对 4 路压力统一滤波
对多路液位统一超限判断
3. 工位状态管理

例如:

12 个工位是否有料
12 个工位产品编号
12 个工位加工完成状态
4. 配方参数组

例如:

一组产品参数
一组延时设定
一组速度设定
一组压力设定
5. 历史数据缓存

例如:

最近 10 次采样值
最近 20 次称重结果
最近 50 条报警编号

这些场景一旦出现,数组的优势就会非常明显。

七、使用数组时最重要的习惯:边界意识

数组特别好用,但也特别容易因为边界没想清楚而出问题。

比如你的数组定义是 1 到 10,那么你用 FOR 遍历时,就必须严格对应这个范围。
如果你写成 1 到 12,或者从 0 开始,就可能出问题。

所以每次用数组时,都要问自己:

下标从几开始
到几结束
循环范围是不是一致
有没有越界风险
我有没有漏掉第一个或最后一个元素

这和前一篇讲循环时的边界意识是完全连在一起的。

一句实在话:

数组本身不难,真正容易出错的是“编号范围”和“访问边界”。

八、数组为什么特别适合和循环配合

我们前面讲过,循环的本质是“对一组对象重复同样处理”。

而数组的本质是“把一组对象按编号组织起来”。

这两者一结合,就非常顺。

例如你要对 8 路温度做超温报警:

FOR i := 1 TO 8 DO
    IF TempPV[i] > TempHighLimit[i] THEN
        TempHighAlarm[i] := TRUE;
    ELSE
        TempHighAlarm[i] := FALSE;
    END_IF;
END_FOR;

这段程序的价值不只是代码短。
更重要的是,它表达了一个非常清晰的工程规则:

对 8 路温度,都按同样的规则判断。

这就是结构化编程的味道。

九、数组适合做“同类数据”,但不适合硬塞“不同意义的数据”

这一点很重要。

比如下面这些适合数组:

8 路温度
16 路输入
12 个工位占用状态

因为它们本质上是同一类数据的多个元素。

但如果你把这些放在一个数组里,就不太合适:

启动按钮
温度设定
报警代码
产品名称

因为它们不是同一类数据,意义完全不同。
这时候如果硬塞成数组,程序会变得很别扭,也不利于维护。

所以你要记住:

数组适合“横向一排同类对象”,
不适合把风马牛不相及的数据硬放成一组。

第二部分:结构体
十、结构体到底是什么

如果说数组解决的是“很多个同类元素怎么放在一起”,
那么结构体解决的就是:

一个对象有很多不同属性,这些属性怎么归到一起。

例如一台电机,它可能有这些信息:

启动命令
停止命令
运行反馈
故障状态
热继电器报警
允许启动
当前速度
速度设定

这些变量彼此不是“同类元素排成一列”,而是“同一个对象的不同方面”。

这时候,结构体就特别合适。

你可以把结构体理解成:

给一个对象做一张信息表,把它相关的字段集中放在一起。

十一、结构体和数组最大的区别是什么

这个问题非常关键。

数组

强调的是:

一组元素
元素类型通常相同
通过下标区分第几个
结构体

强调的是:

一个对象
对象有多个字段
字段可以类型不同
通过字段名区分是什么属性

例如:

数组更像这样

8 路温度值:

Temp[1]
Temp[2]
Temp[3]

这是“同一类数据的一组”。

结构体更像这样

1 号电机的信息:

RunCmd
StopCmd
RunFB
Fault
SpeedSP
SpeedPV

这是“一个对象的多种属性”。

所以你可以把它们这样区分:

数组是很多个同类点排成一列;
结构体是一个对象展开成很多属性。

十二、结构体为什么特别适合工程项目

因为工程项目里的很多对象,本来就不是单一变量,而是一组相关数据。

例如:

一个气缸

它至少可能包括:

ExtendCmd
RetractCmd
ExtendFB
RetractFB
TimeoutAlarm
ManualEnable
AutoEnable
一个电机

可能包括:

StartCmd
StopCmd
RunFB
Fault
Overload
Permit
Ready
SpeedSP
SpeedPV
一个工位

可能包括:

Occupied
ProductID
ProcessDone
ClampOK
NGFlag
一条报警记录

可能包括:

AlarmID
Active
Acked
Timestamp
Description

这些东西如果全散着写,后面越来越大时很难维护。
而如果用结构体组织,你会明显感觉程序变得更有“模块感”。

十三、结构体最典型的工程价值:让程序更像“对象”,而不是一堆碎变量

这一点特别值得体会。

以前你可能写的是:

Motor1_RunCmd
Motor1_RunFB
Motor1_Fault
Motor1_Permit
Motor1_SpeedSP

看起来也没错。
但如果项目里再来一台 Motor2、Motor3、Motor4,你很快就会进入复制命名的世界。

而结构体思路更像是:

“电机”本身就是一个对象,它天然有一组属性。

一旦你这样思考,后面的程序组织会完全不一样。
尤其做标准化模块、重复设备、批量对象管理时,结构体会非常有价值。

十四、结构体特别适合和功能块、数组继续结合

这一点虽然现在你还没有完全展开,但先建立概念非常有帮助。

结构体本身已经能组织一个对象的字段。
而一旦后面你把它和功能块结合,就能形成更清晰的模块边界。
如果再进一步和数组结合,甚至还能形成:

一组对象,每个对象内部又有自己的多项属性。

例如:

10 个工位,每个工位都有 Occupied、ProductID、DoneFlag
4 台电机,每台电机都有 RunCmd、Fault、SpeedSP、SpeedPV

这种写法在大型工程里非常常见,也很有力量。

所以你现在先记住:

数组和结构体不是互相替代,而是经常配合使用。

十五、什么时候应该想到结构体

以后你遇到这些场景时,就应该本能想到结构体。

1. 一个设备单元有很多相关状态和命令

比如电机、气缸、阀门、工位。

2. 一条记录包含多个字段

比如报警记录、配方记录、产品数据。

3. 想让程序更模块化、更容易维护

尤其项目开始变大后,这一点越来越重要。

4. 不想再到处写一长串前缀变量名

例如不想一直写:

Station1_XXX
Station1_YYY
Station1_ZZZ

而是想把它们归在同一对象下。

十六、结构体使用时最重要的一个工程意识:字段命名要有层次

结构体虽然能让程序更规整,但如果字段名本身乱起,依然会混乱。

例如一个电机结构体里,如果字段叫:

A
B
C
D1
New2

那结构体也救不了程序。

结构体字段依然要清楚表达含义,例如:

RunCmd
StopCmd
RunFB
Fault
Ready
SpeedSP
SpeedPV

也就是说:

结构体不是让你少思考命名,而是要求你更认真思考命名层次。

因为它本质上是在给对象建立“内部属性表”。

第三部分:字符串
十七、字符串到底是什么

字符串最简单的理解就是:

一段文本。

例如:

产品型号
条码
报警说明
配方名称
设备名称
通信报文字段

很多 PLC 工程师早期接触字符串不多,所以容易觉得它离现场控制有点远。
但实际上,只要你开始接触这些内容,字符串就会很快出现:

扫码器
HMI 文本显示
报警描述
通信协议里的文本字段
产品名称和批次信息

所以字符串虽然不像 BOOL 和 REAL 那么“天天都在用”,但一旦碰到相关项目,它会非常关键。

十八、为什么字符串和数值变量不一样

这点必须先有直觉。

例如:

25.6 这是一个数值
“25.6” 这是一个字符串文本

人看起来可能差不多,但程序眼里完全不是一回事。

数值可以直接比较大小、加减乘除。
字符串更适合做:

显示
拼接
比较是否一致
提取某段文本
作为标识符

所以你一定要记住:

字符串不是“带引号的数字”,它本质上是文本。

十九、PLC 项目里字符串最常见的应用场景
1. 扫码器与条码处理

例如:

读取产品条码
判断条码是否为空
对比条码是否匹配当前配方
保存最近一次扫码结果
2. 配方名称

例如:

A 产品
B 产品
配方001
配方002
3. 报警描述或状态说明

虽然有些系统用报警编号加 HMI 文本表,但在某些场景下也会直接涉及字符串处理。

4. 通信报文内容

例如某些串口通信、文本协议、扫码枪、打印机指令。

5. 设备识别信息

例如工件编号、订单号、批次号。

二十、字符串处理时最重要的意识:它不是数值运算逻辑,而是文本逻辑

比如你处理温度值时,关心的是:

大于多少
小于多少
相加后是多少
平均值是多少

但字符串处理关心的是:

是否相等
是否为空
长度是多少
是否包含某段内容
能否拼成完整文本

所以字符串思路和数值思路不一样。
这也是为什么很多工程师一开始对字符串会稍微不适应。

不是它很难,而是它不像你平时常见的开关量和模拟量控制。

二十一、字符串在工程里最大的风险:看起来简单,实际容易牵扯长度、格式、空值问题

例如你拿到一个扫码结果,表面上只是“一个字符串”。
但实际工程里你可能要考虑:

它是不是空字符串
长度够不够
是否有前后空格
是否包含回车换行
是否和目标型号完全一致
设备发送过来的格式有没有固定前缀

所以字符串虽然看起来只是“文字”,但用在工程里,细节往往不少。

二十二、数组、结构体、字符串这三者,真实工程里常常是一起出现的

这点特别重要。

例如你做一个产品工位管理,可能会同时有:

每个工位是一个结构体

里面包括:

Occupied
ProductCode
OKFlag
DoneFlag
多个工位组成一个数组
Station[1]
Station[2]
Station[3]
其中 ProductCode 又是字符串

这样你就会形成一个很典型的工程数据组织方式:

一组对象,每个对象内部有多个字段,其中某些字段还是文本。

你一旦接受了这种思路,SCL 程序的层次感会一下提升很多。
这也是为什么这一篇非常关键。
因为它开始把你从“单个变量控制”带向“数据结构控制”。

二十三、为什么很多人学到这里,才开始真正觉得 SCL 和梯形图拉开差距了

因为前面 IF、CASE、FOR 这些,虽然已经是文本编程,但逻辑上你还能比较容易用梯形图思维去类比。

可到了数组、结构体、字符串这里,你会越来越明显地发现:

SCL 不只是另一种写法,它开始让你可以更自然地处理“复杂数据组织”。

而这正是很多复杂工程逻辑的核心。

例如:

配方系统
报警系统
多工位管理
产品追踪
通信解析
条码处理
历史数据记录

这些内容如果只靠传统散点变量去堆,会非常辛苦。
而 SCL 在这方面明显更顺手。

二十四、初学者在这一部分最容易犯的几个错误
错误一:明明是一组同类数据,却还是散着命名

例如:

Temp1
Temp2
Temp3
Temp4

而不是考虑数组。

错误二:明明是一个对象的多属性,却硬拆成大量独立变量

例如:

Motor1_RunCmd
Motor1_RunFB
Motor1_Fault
Motor1_Ready

后面再来 10 台电机,程序就越来越难看。

错误三:把不同意义的数据硬塞成一个数组

这样虽然“凑成了一组”,但程序逻辑并不自然。

错误四:对字符串缺乏格式意识

例如只知道读到文本了,但没考虑长度、空值、格式匹配。

错误五:只会“定义”,不会“组织”

也就是说,虽然知道有数组和结构体这些词,但程序里还没有真正形成数据分层意识。

二十五、从工程角度看,什么时候优先考虑数组,什么时候优先考虑结构体

这个判断非常实用。

优先考虑数组的时候

当你面对的是:

一组同类对象
每个对象处理规则类似
需要按编号遍历
需要统一批量处理

例如:

16 路输入
8 路温度
20 路报警
12 个工位的占用状态
优先考虑结构体的时候

当你面对的是:

一个对象有多种属性
属性类型可能不同
希望把它们归成一个整体
后面可能要模块化、复用

例如:

一个电机
一个气缸
一个工位对象
一条报警记录
一套配方记录
两者配合的时候

当你面对的是:

很多个对象
每个对象又有多项属性

例如:

10 个工位,每个工位有状态、编号、完成标志
4 台电机,每台有命令、反馈、报警、速度

这时候通常就是“结构体数组”的思路。

二十六、给初学者一个很实用的数据组织判断法

以后你拿到一个需求,可以先问自己三个问题:

第一,这是“一组同类元素”,还是“一个对象的多个属性”

如果是一组同类元素,优先想数组。
如果是一个对象的多个属性,优先想结构体。

第二,这里面有没有文本信息

如果有产品号、条码、名称、描述,就要考虑字符串。

第三,这些数据后面是要单点处理,还是批量处理

如果要批量处理,数组价值会非常高。
如果要模块化维护,结构体价值会非常高。

只要这三个问题想清楚,很多数据组织方式就不会乱。

二十七、这一篇最后,给你一个非常实在的工程理解

你可以这样想:

以前你写 PLC 程序,像是在桌子上摆很多零散的小零件。
每个变量都是一个零件,哪里需要就拿哪里。

而数组、结构体、字符串的出现,相当于你开始学会:

把同类零件装进抽屉
给一个设备建立完整档案夹
把文字标签也纳入管理

也就是说,程序不再只是“有没有这个变量”,而开始变成:

这些数据应该怎么归类、怎么组织、怎么让后面处理更顺。

这就是为什么这一篇很重要。
因为从这里开始,你的 SCL 编程会越来越有“工程结构感”。

小结

这一篇你最应该记住这些核心点:

数组适合处理一组同类型、按编号排列的数据,特别适合与循环配合做批量处理。
结构体适合组织一个对象的多项属性,它强调的是“一个对象的完整数据集合”。
字符串用于表示和处理文本数据,在扫码、报警描述、配方名称、通信文本中很常见。
数组和很多个相似变量的本质区别在于,数组是真正被程序作为“一组数据”来处理的。
结构体和数组不是互相替代,而是经常配合使用,尤其适合做一组对象的管理。
字符串处理和数值处理思路不同,它更关注文本内容、格式和比较。
当项目开始涉及多工位、多参数、多对象、条码、配方、记录等复杂信息时,这些数据组织方式会变得非常重要。
SCL 的一个核心优势,就是它能比传统散点式写法更自然地处理复杂数据结构。
下载资料前请先绑定手机号码
对不起,请登录后再发表评论!

触屏端
扫一扫手机也能发信息
明扬工控商城-工控网-工控自动化真品,一站式专业服务!