首页 > 其他分享 >PLC结构化文本(ST)——指针和引用(Pointer&Reference)

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

时间:2024-09-04 17:52:45浏览次数:10  
标签:END Reference ST FB PLC 引用 VAR Append 指针

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

在代码编辑区使用取址运算符获取变量“ 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”三种编程方式。若还有其它我不知道的方法,欢迎大神留言讨论。

标签:END,Reference,ST,FB,PLC,引用,VAR,Append,指针
From: https://www.cnblogs.com/JSheng/p/18397051

相关文章

  • 在Android中发送网络请求(post和get的区别)
    get//将参数附加到URLStringurlWithParams=HttpConfig.GET_USER_NAME+"?qrCodeContent="+msg;//构建请求Requestrequest=newRequest.Builder().url(urlWithParams).addHeader("Authorization&q......
  • [Python图论]在用图nx.shortest_path求解最短路径时,节点之间有多条边edge,会如何处理?
    问:在使用图求最短路径时,如果节点之间有多条路径,shortest_route=nx.shortest_path(G,source=start_node,target=end_node,weight='length')会如何处理,会自动选择最短那条吗?#输出图G各节点之间有多少条边edge,并给出其长度Edgesbetween103928and25508583:共2条Edge......
  • python_August(函数对象、功能选择)
    目录python中一切皆对象功能选择函数的嵌套功能选择增加内容版python中一切皆对象#python中一切皆对象#print(self_max)#<functionself_maxat0x0000020E4456CF28>#print(id(self_max))#print(type(self_max))#print(type([1,2]))#print(type(1))#print(type(......
  • 如何使用confluence rest api(wiki自动化),如何解决confluence登录认证问题
    想要使用AtlassianConfluence提供的RESTAPI中的getUser方法来获取用户信息。1.如何使用账号密码登录以下是一个示例Python脚本,演示如何使用该API:importrequestsimportjson#设置ConfluenceAPI的基本URL和登录的用户名密码base_url='https://your-confluence-url/......
  • 今日分享——stream流和方法引用
    1.不可变集合1.1什么是不可变集合是一个长度不可变,内容也无法修改的集合1.2使用场景如果某个数据不能被修改,把它防御性地拷贝到不可变集合中是个很好的实践。当集合对象被不可信的库调用时,不可变形式是安全的。简单理解:不想让别人修改集合中的内容比如说:1,斗......
  • pytest
    一、Pytest特点基于Python语言的自动化测试框架最知名的有如下1、unitest2、pytest3、robotframework前两款框架主要聚焦在开发者的白盒单元测试而robotframework主要聚焦在系统测试上。Pytest可以用来做系统测试的自动化,它的特点有:1、用Python编写测试用例,简便易用2......
  • 性能、成本与 POSIX 兼容性比较: JuiceFS vs EFS vs FSx for Lustre
    JuiceFS是一款为云环境设计的分布式高性能文件系统。AmazonEFS易于使用且可伸缩,适用于多种应用。AmazonFSxforLustre则是面向处理快速和大规模数据工作负载的高性能文件系统。在本文中,我们将通过一系列测试,来评估这三种主流文件系统的性能与成本表现,帮助用户快速了解这些......
  • (5-4-05)基于Stable Diffusion的文生图系统:(5)概率分布+编码和嵌入
    5.概率分布文件distributions.py定义了与概率分布相关的抽象类和具体实现,包括抽象分布类AbstractDistribution、狄拉克分布DiracDistribution和对角高斯分布DiagonalGaussianDistribution。这些类提供了样本生成、模式计算和KL散度等功能,支持概率模型中的采样和分布计......
  • docker安装logstash7
     一、创建网络dockernetworkcreate-dbridgeelastic#和elasticsearch使用同一个网络 二、拉取logstash镜像dockerpulllogstash:7.1.1 三、创建logstash容器dockerrun-it\--namelogstash\-p9600:9600\-p5044:5044\--netelast......
  • orcla的timestamp与date如何判断是否相等 oracle的date和timestamp区别
    orcla的timestamp与date如何判断是否相等oracle的date和timestamp区别转载mob6454cc6d3e232024-04-2513:03:57文章标签sql数据字符串获取时间文章分类架构后端开发阅读数777我整理的一些关于【IT人转技术管理】的项目学习资料(附讲解~~)和大家一起分享、学习......