声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2882|回复: 5

[LabView] LabVIEW 代码中常见的错误

[复制链接]
发表于 2006-10-23 09:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
发现了程序的问题再回头去调试,在查找程序错误时就不可避免地要花大量时间。要调高开发效率,最好是在编写代码时就避免一些常见的低级错误,这样可以节约大量的调试时间。
    有些编程错误差不多是每个 LabVIEW 程序员都曾遇到过的。在编写相关代码的时候,对这些问题多留心一下,就可以大大减少调试时间。

1. 数值溢出
1.png
图1:数值溢出错误

    图1 中的 VI 只做了一个简单乘法 300*300 ,不加思索就应该知道答案是 90000,但程序中乘法节点给出的结果却是 24464。乘法节点是不会错的,错误是由于程序中使用的数据类型是 I16。I16 能表示的最大数目只有32767,所以在乘法计算中出现了溢出。
    避免此类错误的方法是,在程序中使用短数据类型时,一定要确认程序中的数据绝不会超出该类型可以表示的范围。

2. For 循环的隧道
    数据传入传出循环结构可以通过移位寄存器(Shift Register)和隧道(Tunnel)两种方式。隧道又有两种类型:带索引的和不带索引的。
    移位寄存器一般用在需要局部变量的情况下,循环运行一次的输出数据要作为下次运行的输入数据使用;循环外的数组数据通过带索引的隧道在循环体内就可以直接得到数组元素;除此之外,简单地在循环内外传递数据,使用一般的隧道就可以了。
    值得一提的是,如果一个数据传入循环体,又传出来,那么就应该使用移位寄存器或带索引的隧道来传递这个数据,尽量不要使用不带索引的隧道。因为 For 循环在运行时,循环次数有可能为0。在循环次数为0时,大多数情况,用户还是希望传出循环的数据就是传入值,但使用不带索引隧道时,输入值有时会被丢失的。如果使用移位寄存器,即使循环次数为0,也不会丢失传入的数据。因为移位寄存器在循环上的两个接线柱指向的实际是同一块内存(参考:LabVIEW 程序的内存优化),而输入输出两个隧道指向的是不同的内存,数据不一定相同。

2.png
图2:For 循环上的隧道

    图2中的程序, vi reference 传入,再传出循环均使用了隧道。如果循环次数为0(Controls数组为空),vi reference 再传出循环时,信息就丢失了。这不但有可能造成后续程序的错误,而且由于 vi reference 的信息丢失,再无法关闭打开的 vi,造成了程序泄漏。
    Error 数据线(黄绿色的粗线)在传入传出数组时,一定要使用移位寄存器。原因还不仅是为了防止在循环次数为0时,错误信息丢失。通常一个节点的 Error Out 有错误输出,意味着后续的程序都不应该执行。在错误的情况下继续执行程序代码,风险非常大,可能会引起程序,甚至系统崩溃。只有使用移位寄存器,某次循环产生的错误才会被传递到后续的循环中,从而及时阻止后续循环中的代码被运行。

3. 循环次数
    LabVIEW 的 For 循环与其它语言相比,有一大特点是在某些情况下不一定要输入循环次数,For 循环可以根据输入数组的大小决定循环次数。把一个数组通过带索引的隧道把数组分解成元素传递到循环体内,同时不要设置循环次数N,这时,循环的次数就是数组的长度。每次循环,带索引的隧道给出一个元素。
    容易引起错误的情况是,循环体上有两个或更多的输入数组使用了带索引的隧道。这时,循环的次数是几个数组中长度最短的那个数组的长度。如果还设置了循环次数N,那么循环的循环次数是N、输入数组长度中最小值。在调试的时候,如果发现一个本该运行多次的循环没有运行,那么很可能就是因为它的一个输入数组是空的。

   While 循环同样也可以使用带索引的隧道,但是我不建议大家这么用——如果需要用到带索引的隧道,那么就使用 For 循环。原因是 while 循环的循环次数不由数组个数决定,而是由停止条件决定的。如使用带索引的隧道,你还需要考虑在数组大于、小于循环次数时,程序如何处理,这样还是在循环体内作索引比较方便。如果希望循环次数与数组大小保持一致,那自然是用 For 循环,程序更加清晰易懂。

4. 移位寄存器的初始化
3.png
图3:没有初始化的移位寄存器

    看图3中这个程序,因为它在 while 循环上使用了带索引的隧道,所以可读性不那么好。array out 的运行结果是什么,还真的想一阵才能给出答案。实际上这个程序,即使输入不变,每运行一次,array out 的结果都不一样,他的长度一致在增加。这个问题就出在没有给程序中的移位寄存器一个初始值。

    没有初始化的移位寄存器,总是保存上次运行结束时的数据。这点在某些情况下可以别程序员利用,比如用它当作全局变量,随时把数据存入或取出。(一个例子是《如何使用 VI 的重入属性》中的图4)但多数情况下移位寄存器还是被用作为循环内部的局部变量的,这是就一定要对它初始化,以防止潜在的错误。

5. Cluster
4.png
图4:Cluster 传递数据出错

    图4的程序中有个奇怪的错误,明明应该是 weight 加 1 怎么运行完后的结果变成了high 加 1 了呢?直接揭开谜底吧,原因是 Cluster 中的元素有个顺序,这个顺序可以和界面上看到的顺序不一致。分别鼠标右击程序中的两个 Cluster,选择“Reorder Controls in Cluster”。

转自http://ruanqizhen.spaces.live.co ... 8W8PfmDA!1073.entry
版权归原作者所有
回复
分享到:

使用道具 举报

发表于 2006-10-24 18:04 | 显示全部楼层

http://ruanqizhen.spaces.live.com/

我不知道你们是否是同一个人???

http://ruanqizhen.spaces.live.com/
发表于 2006-10-24 18:57 | 显示全部楼层
原帖由 labview 于 2006-10-24 18:04 发表
我不知道你们是否是同一个人???

http://ruanqizhen.spaces.live.com/

即使引用也是没有关系的,只是用于学习而已。
发表于 2006-10-25 06:30 | 显示全部楼层

请你注明“转载”还是“原创“!!!!!!

原帖由 realhappy 于 2006-10-24 18:57 发表

即使引用也是没有关系的,只是用于学习而已。


尊重别人,别人才会尊重你!
发表于 2006-10-25 09:02 | 显示全部楼层
原帖由 labview 于 2006-10-25 06:30 发表


尊重别人,别人才会尊重你!

这倒有必要注明一下!
 楼主| 发表于 2006-10-26 18:20 | 显示全部楼层
原帖由 labview 于 2006-10-24 18:04 发表
我不知道你们是否是同一个人???

http://ruanqizhen.spaces.live.com/


不是这是专贴,很早以前收集到个人的oneNote中,所以不知道出处,也就没有标明了,在第一帖中已经标明转贴
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-5-9 21:46 , Processed in 0.101710 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表