资源描述
在LabVIEW中实现VI的递归调用LabVIEW中使用递归调用不是很方便。不过递归并不是编程必须程序结 构,任何需要使用递归调用的地方,都可以用循环结构来代替。但是在某些情况 下,使用递归调用的确可以大大简化程序代码,对缩短编程时间、提高程序可读 性都非常有帮助,所以学习一下递归的实现方法还是有好处的。一、为什么VI不能够被静态的递归调用LabVIEW不能通过静态调用的方法(把子VI直接放到另一 VI的程序框 图上)来实现递归。对于一个非可重入的subVI,在每一个时间,这个subVI只能被运行一次。 LabVIEW需要借此来保证多线程时的数据安全。对于被递归调用的代码,是需 要在它执行到中间的时候,就再次被调用的。所以默认设置下的VI不能被静态 递归调用。对于被设置为可重入的VI,是可以被同时调用多次的,但也不能被静态的 递归调用。除非是通过VI Server动态的调用VI,否则,LabVIEW是在一个程序被 调入内存,开始运行之前就为它的所有VI分配好内存空间的,包括数据区。如 果一个VI不是可重入的,LabVIEW会在这个VI运行时局部变量所在的数据 区开辟在这个VI所在的空间内;对于可重入的VI,LabVIEW把它的数据区开 辟在调用者VI上,这样就可以保证这个可重入VI在不同的地方被同时调用 时使用不同的数据区,以防止多线程运行时数据混乱。因此,可重入VI虽然可以被同时多次调用,但是被调用的次数是运行前就 确定的。而递归运算时的调用次数是运行时决定的。这样,如果是静态调用, LabVIEW根本没有办法提前为参与递归的VI开辟好数据区。、用动态调用方法实现递归图1是一个采用递归算法计算阶乘的例子error cut-fVo 1Factorial图1:利用递归结构计算阶乘正如前文说过的,所有的递归都可以使用循环来代替,计算阶乘也可以使用 循环结构,但是这里介绍的是使用递归结构的方法。因为n!=n*(n-1)!,所以我 们只要编写一个VI实现功能F(n)=n*F(n-1)就可以了。程序中,递归调用VI自身的结构由三个VI动态调用节点实现:Open VI Reference, Call By Reference Node, Close Reference。这三个节点分别负责动态打 开一个VI(本例中就是这个VI自身),运行这个VI,再关闭它。使用Call By Reference Node需要在打开VI句柄的时候就要知道VI连 线板(Connector Pane)的布局,因此,我们在用Open VI Reference打开VI的时 候要提供VI连线板的布局信息,在例子中就是Open VI Reference节点上方的 那个常量。三、使用递归时的几点注意事项递归调用的退出或结束条件,本例中当输入数据小于1时,就需要结束递归调用返回最底层的值了。如果递归调用的退出条件设置不当,可能会引起程序死循环甚至崩溃。LabVIEW中也可以实现A调用B, B又调用A这种用多个VI相互调 用的递归结构。参与递归调用的VI必须被设置为可重入。动态调用的需要把VI在运行时调入内存,这个过程是比较耗时的。因此递 归结构的运行效率远不如可实现相同功能的循环结构,内存占用也会更大一些。 决定使用递归结构之前要考虑到这些因素。
展开阅读全文