百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

[西门子PLC] 博途编程之递归算法

itomcoil 2025-08-02 18:49 2 浏览


首先跟大伙讲一讲哈,递归算法瞅着是挺优雅挺不错的,可实际上没啥大用,在真正的项目里能不用就别用递归,为啥呢?因为用了递归可能会惹出大麻烦,后面会给大伙举例讲讲原因。

那啥叫递归呢?从名字上就能看出来,就是先传出去,再弄回来。举个例子哈,好比有个集团公司要统计月度产量数据,分成总部、工厂、车间这三级。假设每个层级都能去执行统计产量数据这个命令,那递归的表现就是,领导要看数据的时候,给总部层级下达执行统计产量数据的命令,总部层级执行命令的时候,发现数据得靠工厂层级,所以就先给工厂层级下达执行统计产量的命令,同样的,工厂层级依赖车间层级的数据,也先给车间层级下达执行统计产量数据的命令,这就是递归里的“递”,也就是一级一级地往下传命令。



那命令到了车间层级之后呢,车间是最底层啦,产量数据就在它那儿,不依靠别的啥了,所以它能直接执行命令,弄完之后把结果交给工厂层级。工厂层级拿到车间层级的数据再汇总一下,命令就算执行完了,把结果再交给总部层级。总部层级拿到工厂层级的数据也汇总一下,命令执行结束,把结果交给领导,这就是递归里的“归”,也就是一级一级地往上交结果。



所以递归的想法呢,

一是把自己这一级的事儿做好,

二是把下一层级的事儿用同样的办法处理完了再回来,

三是到了最下面那一层级处理完就回来。

所以递归有个特别明显的特点,就是会自己调用自己,也就是函数 A 调用函数 A 调用函数 A ,一直到最下面那一层级。好多刚开始学的人看到这儿可能就不太明白了,函数咋能调用它自己呢?函数都还没执行完,咋就调用自己了?这是操作系统的一个基本常识,咱们可以这么想,函数写完之后,就好比是一份做 5 层套娃的图纸,当你开始按照图纸做套娃的时候,做了一半,也就是在图纸的中间部分,图纸告诉你,最外面第 1 层先做到这儿,回到图纸开头,按照 4/5 的尺寸做第 2 层,第 2 层做到一半的时候,又到了图纸中间部分,又告诉你,第 2 层先到这儿,再回去做第 3 层,就这么依次往下,一直到第 5 层的时候,图纸在中间没打断你,能顺利做完,在图纸最下面,告诉你第 5 层做完之后回到图纸中间做第 4 层,就这么依次往下,一直到第 1 层结束。

注意哈,这里咱们看到的都是同一份图纸,函数就像这图纸似的,咱们做套娃的这个过程就好比 PLC 在执行咱们的函数一样。这样是不是能好理解一点儿啦?




下面通过三个程序示例来展示展示。

示例 1 是反转位序的功能。

在和第三方设备通讯读取一些状态字的时候,有时候会碰到位序反过来的情况。正常来说,一个字节的位序从低到高,是位 0 到位 7 ,反过来的话,从低到高,就是位 7 到位 0 ,所以就得把位序给反转一下。




咱们来试着用递归来实现。函数的输入参数有要反转的字节 byte ,还有层级变量 bitPos ,以及返回的结果。

实现的部分呢,

一是先把自己这一层级的事儿做好,读取当前层级变量 bitPos 位置以及对应逆序位置指示的位变量是不是 1 ,然后把对应逆序位置的位变量设置成 0 或者 1 ,这里用了一些位运算,新手可以拿来练练。

二是对于下一层级的事儿,用同样的办法去处理,也就是调用函数自己去处理下一层级。

三是到了最下面那一层级的时候,就返回数据。因为咱们处理的是字节,所以到了位 3 的时候,就是最下面那一层级啦。




先不管上面处理位运算的那部分,就看下面这一块儿,是不是觉得特别优雅特别神奇,自己调用自己就把事儿给办了。


下面来测试一下,结果是正确的。


再来看示例2,


比如说 PLC 带着好多 Profinet 节点,要求要是有节点出现通讯之类的故障时,得有个指示。

输入的参数里,nodeHwIds 是 Profinet 节点的标识符,pos 是层级,返回的结果是 Bool 型的,用来指示有没有故障。

实现的部分呢,同样是先把本层级的事儿做好,然后用一样的方法去处理下层级的事儿,到了最下层级就直接返回。





咱们测试一下哈,建立一个有 10 个元素的数组,把其中一个值改成 4 (FC_HW_Error 是用来仿真的,当节点标识符除以 5 余数是 4 的时候,就代表故障),能看到结果是对的。




当系统的节点增多之后,比如说变成 20 个,这时候只要把数组的长度改成 20 个就行。不过当你修改完然后下载程序之后,就会发现,PLC 出故障啦,报告函数超出了嵌套深度。




那这到底是为啥呢?要晓得,函数执行是得耗费系统资源的,会消耗内存里栈空间那部分,这个资源是有限的,就跟俄罗斯套娃似的,总归是有局限的。

而递归呢,因为是自己调用自己,每一层级在还没执行完的时候,都会分别占用栈空间的资源,当层级太多超过栈空间了,就会造成栈空间溢出。所以就算递归的想法看上去挺优雅挺不错的,咱们在实际的项目里也别用它。

因为能用递归完成的功能,都能够用循环来完成,而且用循环往往执行效率还更高。下面就是用循环实现的版本。



PLC编程之美丽又危险的递归算法

http://bbs.plcjs.com/forum.php?mod=viewthread&tid=507223&fromuid=17

(出处: PLC论坛-全力打造可编程控制器专业技术论坛)

#非标自动化#

#西门子PLC#

相关推荐

C|经典实例理解算法之顺推、逆推、迭代、递归思想

递推算法可以不断利用已有的信息推导(迭代)出新的信息,在日常应用中有如下两种递推算法。①顺推法:从已知条件出发,逐步推算出要解决问题的方法。例如斐波那契数列就可以通过顺推法不断递推算出新的数据。②...

[西门子PLC] 博途编程之递归算法

首先跟大伙讲一讲哈,递归算法瞅着是挺优雅挺不错的,可实际上没啥大用,在真正的项目里能不用就别用递归,为啥呢?因为用了递归可能会惹出大麻烦,后面会给大伙举例讲讲原因。那啥叫递归呢?从名字上就能看出来,就...

SQL 也能递归?一文搞懂 Recursive CTE的魔力

很多人以为递归(Recursive)只属于编程语言,和SQL没什么关系。但其实SQL中也能实现递归操作,特别是在处理树结构、路径查找时,WITHRECURSIVE展现出强大威力。本文将带你...

10张动图学会python循环与递归

  一图胜千言!  循环难学?十张动图GIFS有助于认识循环、递归、二分检索等概念的具体运行情况。  本文代码实例以Python语言编写。  一、循环  GIF1:最简单的while循环  GIF...

C语言学习之-----(十三) 函数递归

(十三)函数递归一、栈在说函数递归的时候,顺便说一下栈的概念。栈是一个后进先出的压入(push)和弹出(pop)式数据结构。在程序运行时,系统每次向栈中压入一个对象,然后栈指针向下移动一个位置。当系...

Python自动化办公应用学习笔记19—— 循环控制:break 和 continue

在Python的循环结构中,break和continue是两个特殊的保留字,主要用于改变循环的执行流程。1.定义与核心作用break:立即终止当前循环,跳出整个循环体(仅限最内层循环)conti...

循环与递归的那些事
循环与递归的那些事

大家好,我是贠学文,点击右上方“关注”,每天为您分享java程序员需要掌握的知识点干货。在任何的编程语言中,循环和递归永远都是一个避不开的话题,因为在某些特定的场景下,用递归确实要比循环简单得多,比如说遍历文件夹目录等等,但是,递归也有下面...

2025-08-02 18:49 itomcoil

漫谈递归、迭代、循环——人理解迭代,神理解递归

后续计划好几天没有更新了,没有偷懒。随着源码的阅读,学习到了字典和集合的底层实现。字典这种数据结构的搜索效率很高,底层结构采用了效率优于红黑树的哈希表。红黑树是一种平衡二叉树,C++中的map和lin...

Excel递归与循环——货物分箱问题

递归指通过函数自身调用实现复杂计算,在Excel中多通过支持递归的函数(如LAMBDA)实现。第一,简化复杂逻辑表达:对于有明确递推关系的问题,递归能将多层嵌套的逻辑转化为简洁的自我调用形式,比手...

MongoDB入门之索引

索引就像书的目录,如果查找某内容在没有目录的帮助下,只能全篇查找翻阅,这导致效率非常的低下;如果在借助目录情况下,就能很快的定位具体内容所在区域,效率会直线提高。索引简介首先打开命令行,输入mongo...

MongoDB之集合管理一

最近的几篇博客都是关于MongoDB的,虽然个人感觉也没多少知识点,但没想到竟然有转载我的博客的,不管有经过我同意还是没经过我同意,说明写的应该还是有价值的,这也是我写博客的一个动力之一吧。上一博客学...

SpringBoot集成扩展-访问NoSQL数据库之Redis和MongoDB!

与关系型数据库一样,SpringBoot也提供了对NoSQL数据库的集成扩展,如对Redis和MongoDB等数据库的操作。通过默认配置即可使用RedisTemplate和MongoTemplate...

揭秘你不会画“信息结构图”的本质

编辑导语:产品信息结构图有助于清晰地展示产品信息,一定程度上可以为后台上传数据提供依据,但不少人可能觉得产品信息结构图很难,这可能是对数据库表结构不理解等因素导致的。本篇文章里,作者就产品信息结构图的...

MongoDB导入导出备份数据

要提前安装mongodb-database-tools参考:centos离线安装mongodb-database-tools导出数据常用的导出有两种:mongodump和mongoexport,两种方...

mongodb导入导出及备份

-------------------MongoDB数据导入与导出-------------------1、导出工具:mongoexport1、概念:mongoDB中的mongoexport...