PLC结构化文本(ST)——指针和引用(Pointer&Reference)

PLC Structured Text Object Oriented Programming

PLC结构化文本(ST)——指针和引用(Pointer&Reference)

指针的定义

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。---C++ 指针|菜鸟教程

解释一下这里为什么不继续引用C#Java的定义,因为C#Java明确删除了指针,所以找不到关于指针的介绍。

引用的定义

引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。---C++ 引用|菜鸟教程

指针与引用的区别

引用很容易与指针混淆,它们之间有三个主要的不同:

  • 不存在空引用。引用必须连接到一块合法的内存。
  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
  • 引用必须在创建时被初始化。指针可以在任何时间被初始化。
    ---C++ 引用 vs 指针

指针的使用

在程序(PRG)中声明整型(INT)变量in01,再声明指针变量指向INT类型。

PROGRAM Main
VAR
    in01    : INT;
    pint    : POINTER TO INT;
END_VAR

在代码编辑区使用取址(ADR)运算符获取变量“ in01 ”的内存地址赋值给指针变量“ pint ”,然后对指针变量解除地址引用赋值44,最终变量in01当前值为44

pint := ADR(in01);
if pint<>0 then
    pint^ := 44; 
END_IF

引用的使用

PROGRAM Main
VAR
    in01    : INT;
    refint    : REFERENCE TO INT;
END_VAR
------------
refint REF= in01;
if __ISVALIDREF(refint) then
    refint := 11;
END_IF

在代码编辑区引用类型变量refint使用REF=运算符与整型变量in01建立引用关系,然后将refint赋值11,最终变量in01当前值为11

Tips : 某些情况下会存在空引用,所以在使用REFERENCE引用类型时,一般做有效引用的判断运算符 __ISVALIDREF,若引用对象不为空则返回TRUE,若为无效引用则返回FALSE

指针实现Fluent

  • 创建 FB_StringBuilder 功能块
FUNCTION_BLOCK FB_StringBuilder
VAR
	sContent : STRING;
END_VAR
  • 实现 Append 方法,返回指针类型指向 FB_StringBuilder
METHOD Append : POINTER TO FB_StringBuilder
VAR_INPUT
	sText : STRING;
END_VAR
-------------------
sContent := CONCAT(STR1 := sContent, STR2 := sText);
Append := THIS; // THIS指针指向自身实例对象
  • 实现 Clear 方法,返回指针类型指向 FB_StringBuilder
METHOD Clear : POINTER TO FB_StringBuilder
VAR_INPUT
END_VAR
------------------
sContent := '';
Clear := THIS; // THIS指针指向自身实例对象
  • 实现 ToString 方法,返回STRING类型
METHOD ToString : STRING
VAR_INPUT
END_VAR
------------------
ToString := sContent;
  • Main函数声明及调用
PROGRAM MAIN
VAR
	// 输出'Hello world'
	fbStringBuilder : FB_StringBuilder;
	sResult : STRING;
	bTest : BOOL;
END_VAR
------------------
IF bTest THEN
	sResult := fbStringBuilder.Clear()^
								.Append('H')^
								.Append('e')^
								.Append('l')^
								.Append('l')^
								.Append('o')^
								.Append(' ')^
								.Append('W')^
								.Append('o')^
								.Append('r')^
								.Append('l')^
								.Append('d')^
								.ToString();
	bTest := FALSE;
END_IF

使用指针也能实现“ Fluent ”效果,只是看起来一点都不优雅。

引用实现Fluent

  • 创建 FB_StringBuilder 功能块
FUNCTION_BLOCK FB_StringBuilder
VAR
	sContent : STRING;
END_VAR
  • 实现 Append 方法,返回引用类型 FB_StringBuilder
METHOD Append : REFERENCE TO FB_StringBuilder
VAR_INPUT
	sText : STRING;
END_VAR
-------------------
sContent := CONCAT(STR1 := sContent, STR2 := sText);
Append REF= THIS^;
  • 实现 Clear 方法,返回引用类型 FB_StringBuilder
METHOD Clear : REFERENCE TO FB_StringBuilder
VAR_INPUT
END_VAR
------------------
sContent := '';
Clear REF= THIS^;
  • 实现 ToString 方法,返回STRING类型
METHOD ToString : STRING
VAR_INPUT
END_VAR
------------------
ToString := sContent;
  • Main函数声明及调用
PROGRAM MAIN
VAR
	// 输出'Hello world'
	fbStringBuilder : FB_StringBuilder;
	sResult : STRING;
	bTest : BOOL;
END_VAR
------------------
IF bTest THEN
	sResult := fbStringBuilder.Clear()
								.Append('H')
								.Append('e')
								.Append('l')
								.Append('l')
								.Append('o')
								.Append(' ')
								.Append('W')
								.Append('o')
								.Append('r')
								.Append('l')
								.Append('d')
								.ToString();
	bTest := FALSE;
END_IF

使用REFERENCE类型实现“ Fluent ”效果。综合比较实现流式编程使用引用(REFERENCE或者接口(INTERFACE 效果会更好,编码便捷。

总结

指针就是地址,引用是对指针的包装,指针容易出现空指针,引用相对更安全,但仍需要注意出现空引用的情况。
这是目前IEC61131-3标准中我能想到的实现“Fluent”三种编程方式。若还有其它我不知道的方法,欢迎大神留言讨论。

posted @   J_Sheng  阅读(881)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验
点击右上角即可分享
微信分享提示