非负整数n的阶乘简记为n!,在数学上定义为所有小于等于该数的正整数的乘积,并且定义0的阶乘等于1,用公式表示为:
n!=1×2×3×......×(n-1)×n
对于n!也可以用递归方式定义为如下形式:
n!=(n-1)!×n,且0!=1
根据这两种定义方式,下面给出在LabVIEW中编程实现求解n!的两种方法。
阶乘求解方法1:使用for循环 移位寄存器实现这种方法实现相对来说比较简单,程序框图如下图所示:
在上图中,直接根据阶乘定义使用for循环与移位寄存器的思路实现n!的计算,for循环的次数为n次,移位寄存器的初始值为1,作n次乘法运算即可计算出n的阶乘。
注意,上图中,当n为0时,for循环执行次数为0次,n!的输出值直接为移位寄存器的初始值1,符合n阶乘的定义。
阶乘求解方法2:使用递归调用方法实现这种方法根据阶乘的递归方式的定义进行实现。递归VI程序顾名思义是指一个VI在运行中可以调用自身的VI程序,在LabVIEW中可以容易的实现递归VI程序的设置。
对于本例要求计算n的阶乘,因为在程序运行中要调用自身,所以要将其设置为子程序,即在LabVIEW编程环境的图标/连接口区域定义该VI的输入输出参数,本例参数比较简单,在前面板中设计一个输入控件n、一个输出控件n!,两个控件的数据类型皆设置为U32类型,输入输出参数定义完成后,其前面板如下图所示:
其程序框图如下图所示:
根据阶乘的递归定义,n的阶乘为(n-1)!×n,当n=0时,n!=1。所以在上面程序框图中,先判断n是否为0,若为0,则n!输出1,否则,如上图所示,在程序内部通过引用调用自身,实现(n-1)!×n的计算,输出n!。
这种思路实现的关键点有两个,其一是将该VI设置为可重入的类型,其设置方式是,在LabVIEW菜单中选择“文件”---->“VI属性”弹出VI属性设置对话框,在“类别”下拉框中选择“执行”,设置“重入”方式为“共享副本重入执行”,如下图所示:
其二是如何通过引用调用自身。这儿用到了两个关键函数:“打开VI引用”和“通过引用调用”函数,这两个函数均可以在函数面板的“编程”---->“应用程序控制”中找到。
在“打开VI引用”函数中设置3个参数,其中,“选项”参数设置为8,这样可以使通过引用调用可重入VI有效;“VI路径”参数设置为本VI所在的路径;“类型说明符”参数设置较为麻烦,先在这个参数上通过右键菜单创建一个常量,然后在这个常量的右键菜单中选择“选择VI服务器类”---->“浏览”,在弹出的文件选择对话框中选择当前VI即可,设置完成后,创建的常量外观自动变为如上面程序框图中所示的一输入一输出参数的样式。
成功打开VI引用后,将其引用连接到“通过引用调用”函数中,则该函数自动出现对应VI的输入/输出连接口,将n-1连接到输入端,输出即为n-1的阶乘,然后与n相乘,即得到当前n!。
通过层层调用直到0!=1后,即可退出递归流程,返回n!。
需要注意的一点是,在递归调用编程中,必须保证递归VI有一个退出情,也就是说,必须在某些情况下使这个VI只返回一个值,而不是再次调用自己,否则将陷入到无限递归中。
总结本文通过一个简单的阶乘计算例子,可以学到LabVIEW中循环、移位寄存器及递归调用等编程知识点。需要指出的是,递归编程方式其优点是编程实现比较直观简单,但缺点是在递归调用过程中,涉及到内存中自身VI程序的多重复制,在运行效率上较低,同时也存在着程序运行中调用栈溢出的风险,所以,在程序编写过程中一般不提倡过多使用递归架构。
如果你觉得这篇文章对你有用的话,关注 收藏 点赞吧。
,