Two Loops
两种循环
If you've ever programmed in any language, you've probably wanted to repeat the execution of a section of code. LabVIEW offers two loop structures to make this easy. You can use the For Loop or While Loop to control repetitive operations in a VI. A For Loop executes a specified number of times; a While Loop executes until a specified condition is true (or false, depending on how the While Loop is configured). You can find both loops under the Programming>>Structures subpalette of the Functions palette.
如果你曾经做过其它语言的编程, 你或许想重复执行某段代码. LabVIEW提供了两种循环结构来使得你的这个想法变得简单. 你能够使用For Loop 或者While Loop来控制重复性的操作. For Loop执行指定次数的循环; While Loop执行至少1次的循环并直到指定的条件为真 (或假, 依赖于While Loop是如何配置的) 才停止运行. 你可以在函数模板上的结构子模板上(Programming>>Structures)找到这两个循环.
The For Loop
计数循环
A For Loop executes the code inside its borders, called its subdiagram, for a total of count times, where the count equals the value contained in the count terminal. You can set the count by wiring a value from outside the loop to the count terminal. If you wire 0 to the count terminal, the loop does not execute.
一个For Loop执行在其边框内部的代码, 称之为子框图(subdiagram), 循环的总次数等于总数端子(count terminal)的数值. 你可以通过连线一个在循环边框外部的数字到该端子上来设置该值. 如果你连接0到计数端子上, 该循环将不会执行.
Figure 6.1. For Loop
图6.1. 计数循环

![]()
The iteration terminal contains the current number of completed loop iterations: 0 during the first iteration, 1 during the second, and so on, up to N-1 (where N is the number of times you want the loop to execute).
重复计数端子(iteration terminal)包含着当前已经完成的循环的次数: 在第一次循环时该数值为0, 第二次循环为1, 如此类推, 直到N-1次(这儿的N是你所需要循环执行的总次数)
The For Loop is equivalent to the following pseudocode:
一个For Loop可相当于如下的伪代码:
![]()
for i = 0 to N-1
Execute subdiagram
![]()
The While Loop
直到循环
![]()
The While Loop executes the subdiagram inside its borders until the Boolean value wired to its conditional terminal is TRUE (meaning "yes, stop the loop"), as shown in Figure 6.2. LabVIEW checks the conditional terminal value at the end of each iteration. If the value is FALSE (meaning "no, don't stop the loop"), another iteration occurs.
While Loop执行它的子框图代码直到连接到条件端子(conditional terminal)上的布尔量为真(TRUE表示”是, 停止循环”)时方停止执行, 如图6.2所示. LabVIEW在每一次循环结束时将检查它的循环条件端子的值. 如果值为假(FALSE, 表示”否, 不停止循环”), 继续下一次循环.
Figure 6.2. While Loop
图6.2. 直到循环

The While Loop's iteration terminal behaves exactly like the one in the For Loop.
While Loop的重复计数端子(iteration terminal)的特性完全类似与For Loop中的重复计数端子.
The While Loop is equivalent to the following pseudocode:
While Loop可相当于如下的伪代码:
![]()
Do
Execute subdiagram
While condition is FALSE
(Until condition is TRUE)
![]()
You can also change the state that the conditional terminal of the While Loop checks, so that instead of looping while false, you can have it loop while true. To do this, you pop up on the conditional terminal, and select "Continue if True." The While Loop will look like Figure 6.3.
你也可以改变While Loop的循环条件端子的检查状态, 就是用当”条件为真则循环”来代替”当条件为假则循环”. 如果要那样, 你可以弹出条件端子的快捷菜单, 将会浮起一个提示框并选择” Continue if True”. 该While Loop将如图6.3所示.
Figure 6.3. While Loop with "Continue if True" conditional terminal
图6.3. 带有”Continue if True”条件端子的While Loop

The While Loop in Figure 6.3 is equivalent to the following pseudocode:
图6.3中的While Loop可相当于如下的伪代码:
![]()
Do
Execute subdiagram
While condition is NOT TRUE
![]()
As of LabVIEW 7.0, the initial behavior of the While Loop's conditional terminal (when first dropped onto the block diagram of a VI) is Stop if True. However, in LabVIEW 6.1 and earlier, the default state of the conditional terminal is Continue if True. When you are following along with the examples in this book, make sure that you have correctly configured any While Loop conditional terminals to match those in the examples.在LabVIEW 7.0中, While Loop条件端子的初始状态(即在一个VI框图中初次放入While Loop)是Stop if True. 但是, 在LabVIEW 6.1中或先前版本中, 条件端子的初始自定义的状态是Continue if True). 当你在阅读本书中的例程时, 确认你已经正确配置了任一个的While Loop条件端子以符合例程中的设置.
If you want to convert a structure to a different type (for example, turn a For Loop into a While Loop), you can right-click on the outer edge of the structure and select a Replace item from the shortcut menu. You can only replace a structure with similar structures. Experiment with this feature to see how it works.
如果你想转换一个结构到不同的类型(例如, 将一个For Loop换程 While Loop), 你可以右击结构的外框并从快捷菜单中选择Replace选项. 但你仅能够用类似的结构来替换另一个结构. 你可以体验这个特性来看它是如何工作的.
Placing Objects Inside Structures
放置对象到结构里
![]()
For Loop Cursor
For Loop指针
![]()
While Loop Cursor
While Loop指针
When you first select a structure from the Programming>>Structures subpalette of the Functions palette, the cursor appears as a miniature of the structure you've selected; for example, the For Loop or the While Loop. You can then click where you want one corner of your structure to be, and drag to define the borders of your structure. When you release the mouse button, the structure will appear, containing all objects you captured in the borders.
当你初次从函数模板的Programming>>Structures上选择结构模块时, 指针是以缩小的图形显示的; 例如, 对于For Loop或者While Loop. 你能够鼠标单击你所选定Loop的某个边角, 然后拖拽就可以改变该Loop的边框. 当你再释放鼠标时, 该Loop结构就会出现, 该结构可以包括了你所捕捉选定的所有在边框以内的目标.
Once you have the structure on the diagram, you can place other objects inside either by dragging them in, or by placing them inside when you select them from the Functions palette. To make it clear to you that you are dragging something into a structure, the structure's border will highlight as the object moves inside. When you drag an object out of a structure, the block diagram's border (or that of an outer structure) will highlight as the object moves outside.
一旦结构存在于框图中, 你就可以放置其它的目标到该结构中, 或通过拖拽, 或从模板上选择某个目标放置进去. 但需要清楚的是, 当你拖拽某个目标进入结构时, 结构的边界将会加亮(hightlight) 突出显示. 当你拖拽某个目标移出结构时, 整个框图(block diagram)的边界(或者是在该结构更外一层的结构)也会加亮突出显示.
You can resize an existing structure by grabbing and dragging a resizing handle on an edge with the Positioning tool.
你可以调整现有结构的尺寸大小, 通过使用定位工具(Positioning tool)抓取和拖拽结构目标的边缘部分的尺寸操纵柄.
If you move an existing structure so that it overlaps another object, the overlapped object will be visible above the edge of the structure. If you drag an existing structure completely over another object, that object will display a thick shadow to warn you that the object is over or under rather than inside the structure. Both of these situations are shown in Figure 6.4.
如果你移动现有的结构, 致使它与其它的目标交迭时(overlap), 被交迭的目标在结构的边缘时将是可见的. 但你拖拽该结构完全地覆盖了另一个目标, 这个被覆盖的目标将显示一个厚厚的阴影以警示你它是在结构之外而不是在结构之内的. 这两种情形在图6.4中表示.
Figure 6.4. A subVI that is not inside a structure, floating above it and hiding beneath it
图6.4. 子VI不在结构中, 浮在上面或隐藏在后面

Auto Grow
自动增加
All structures have a property called Auto Grow, which can be toggled by checking or unchecking the Auto Grow item of the structure's pop-up menu. When enabled, this feature causes two very useful behaviors. First, it causes the structure to grow automatically when you move objects inside the structure, to positions that overlap the structure's border. Second, this feature prevents you from resizing a structure to a size smaller than the objects inside it. Both of these features prevent objects inside the structure from being hidden inside the structure but outside its frame.
所有的结构都拥有一种被称之为自动增加的属性, 该属性可以通过该结构的快捷菜单中的Auto Grow选项中的”选中”或”不选”来转换. 当被选中时, 这个属性有两个非常有用的特性, 一是它能够使结构在你将一个目标移进该结构内部时而在其边界上就可以自动改变大小, 二是这个特性可防止你调整一个结构的大小以至于小于了其内部目标的大小. 这两个特性可以防止在结构内部的目标被隐藏.
You can change whether LabVIEW enables this setting for new structures placed onto the block diagram by changing the Place structures with Auto Grow enabled checkbox in the Block Diagram section of the Tools>>Options . . . dialog.
你可以改变LabVIEW是否能够使得对新放置到框图中的结构也有同样自动增加的效果, 方法是通过在Tools>>Options…菜单中的Block Diagram部分对话框中激活Place structures with Auto Grow enabled检验栏.
Removing Structures: Don't Just Delete Them
去除结构: 并非删除
Whenever you want to remove a structure, be careful. If you just delete that While Loop, you'll also delete all the objects inside of itfunctions, subVIs, wires, and all.
但是当你想去除一个结构, 请当心. 如果你就只是删除While Loop, 你将会删除在该结构内部的所有的目标, 函数, 子程序, 连线等所有的目标都会被删除.
Unless you want to delete all the code inside a structure, you should pop up on the structure and select "Remove While Loop" (for While Loops) or "Remove For Loop" (for For Loops). This will remove the structure, but leave all the other code on the block diagram. It will also leave all wires intact that pass through the frame of the structure via tunnels and shift registers.
除非你想删除在结构内部所有的代码, 否则你应该在结构的快捷菜单中选择"Remove While Loop" 或 "Remove For Loop ". 这只是删除了结构的框架, 但是可以保留在该框图内的所有代码. 这也保留了穿过该结构框架的隧道和移位寄存器的所有的完整的连线.
Terminals Inside Loops and Other Behavioral Issues
循环内的端子和其它行为特性
![]()
Data passes into and out of a loop through a little box on the loop border called a tunnel. Because LabVIEW operates according to dataflow principles, inputs to a loop must pass their data in before the loop executes. Loop outputs pass data out only after the loop completes all iterations.
数据进出一个循环结构并经由在循环边界上的小方盒, 称之为隧道(tunnel). 因为LabVIEW遵循数据流原理. 输入端必须在循环执行之前就将数据传递给循环. 循环的输出端必须在所有循环重复完成之后才将数据传递出来.
Also, according to dataflow, you must place a terminal inside a loop if you want that terminal checked or updated on each loop iteration. For example, the While Loop in Figure 6.5 checks its Boolean control each time it loops. When the loop reads a TRUE value, it terminates.
因而, 遵循数据流原则, 如果你需要在每一次循环执行时都要监控或更新某个端子, 你就必须放置该端子在循环的内部. 例如, 在图6.5中的While Loop, 必须在每次循环运行时检查它的布尔控件. 当循环读到真值TRUE时, 循环就停止.
Figure 6.5. Stop button inside a loop (reads the value, every loop iteration)
图6.5. 循环内的停止按钮(每一次循环重复时, 读取数值)

If you place the terminal of the Boolean control outside the While Loop, as pictured in the right loop of Figure 6.6, you create an infinite loop or a loop that executes only once, depending on the Boolean's initial value. True to dataflow, LabVIEW reads the value of the Boolean before it enters the loop, not within the loop or after completion.
如果你放置的这个布尔控件端子是在While Loop的外部, 如图6.6, 你创建的将是一个无限循环(infinite loop)或仅运行一次的循环, 具体依赖于这个布尔控件的初始值. 实际对于数据流而言, LabVIEW读取这个布尔量是在它进入循环之前, 而非在循环以内或循环完成之后.
Figure 6.6. Stop button outside a loop (reads the value only once, before the loop executes)
图6.6. 循环外部的停止按钮 (在循环执行前只读取数值一次)

Similarly, the Digital Indicator in the loop in Figure 6.7 will update during each loop iteration. The Digital Indicator in the loop in Figure 6.8 will update only once, after the loop completes. It will contain the random number value from the last loop iteration.
同样地, 在图6.7中循环中的Digital Indicator将在每次循环重复时刷新. 在图6.8中的Digital Indicator将在循环完成之后仅刷新一次. 并且该显示值是最后一次循环中产生的随机数.
Figure 6.7. An indicator inside a loop (updated each iteration)
图6.7. 循环内部的指示器 (每次循环重复就更新)

Figure 6.8. An indicator outside a loop (updated only once, on loop completion)
图6.8. 循环外部的指示器 (只在循环完成时才更新一次)

Remember, the first time through a For Loop or a While Loop, the iteration count is zero! If you want to show how many times the loop has actually executed, you must add one to the count!
记住, 无论For Loop 还是While Loop, 第一次循环的重复计数值(重复计数端子)是零! 如果你想显示具体的已经完成的循环数量, 必须在重复计数值上加一.
Activity 6-1: Counting the Loops
练习6-1: 循环计数
In this activity, you get to build a For Loop that displays its count in a chart on the front panel. You will choose the Number of Iterations, and the loop will count from zero up to that number minus one (because the iteration count starts at zero). You will then build a While Loop that counts until you stop it with a Boolean switch. Just for fun (and also to illustrate an important point), you will observe the effect of putting controls and indicators outside the While Loop.
在这个练习中, 你要创建一个For Loop, 并在前面板上的图表(Chart)中显示它的循环次数.你将选择Number of Iterations, 并且该循环从0计数直到该数减去1 (因为重复计数值是从0开始的). 你也要创建一个While Loop计数直到你按下了一个布尔量开关. 仅仅有趣而已 (还有就是为了说明一个重要点), 你将观察放置控件和显示件在While Loop之外的影响.
1. Create a new panel by selecting New VI from the File menu or by clicking the New VI text in the LabVIEW Getting Started dialog box.
1.创建一个新的面板, 从File菜单中选择New VI, 或从LabVIEW Getting Started对话框中单击New VI.
2. Build the front panel and block diagram shown in Figures 6.9 and 6.10. The For Loop is located in the Programming>>Structures subpalette of the Functions palette. You might use the Tile Left and Right command from the Windows menu so that you can see both the front panel and the block diagram at the same time.
2.创建一个前面板和程序框图如图6.9和6.10. For Loop位于Programming>>Structures 子模板中. 你可以使用Windows菜单中的Tile Left and Right命令使得你可以同时看到前面板和程序框图.
Figure 6.9. The front panel of the VI you will build during this activity
图6.9. 在本练习中你将要创建的VI的前面板

Figure 6.10. The block diagram of the VI you will build during this activity
图6.10. 在本练习中你将要创建的VI的程序框图

Drop a Waveform Chart from the Modern>>Graph subpalette of the Controls palette onto your front panel. Label it For Loop Count. We'll talk more about charts and graphs in Chapter 8, "LabVIEW's Exciting Visual Displays: Charts and Graphs." Use a digital control from the Programming>>Numeric subpalette for your Number of Iterations control.
从控件模板中的Modern>>Graph子模板中选择并放入一个波形图表(Waveform Chart) 到前面板中. 并给其加个标签为” For Loop Count”, 我们将在第8章"LabVIEW的虚拟显示: Charts 和Graphs"中讨论更多的关于图表(Chart)和图形(Graph)细节. 从Programming>>Numeric中选用一个数字控件连接到循环的Number of Iterations上.
3. Pop up on the Waveform Chart and select AutoScale Y from the Y Scale pull-out menu so that your chart will scale to fit the For Loop count. Then pop up on the chart and Visible Items>>Digital Display. Input a number to your Number of Iterations control and run the VI. Notice that the digital indicator counts from 0 to N-1, NOT 1 to N (where N is the number you specified)! Each time the loop executes, the chart plots the For Loop count on the Y axis against time on the X axis. In this case, each unit of time represents one loop iteration.
3.点击波形图表的快捷菜单并从Y Scale下拉菜单中选择AutoScale Y 以使图表的显示刻度匹配于For Loop的计数. 然后点击图表的弹出菜单打开Visible Items>>Digital Display. 输入预定重复的次数到Number of Iterations控件内, 并运行该VI. 注意该图表的数值显示是从0到N-1, 而非1到N (这儿的N是你所指定循环的重复次数)! 循环执行的每一次, 这个图表将绘制该循环的计数值到Y轴上并相对于X轴. 既然如此, 每个时间单位就是一次循环.
4. Notice the little gray dot present at the junction of the count terminal and the Number of Iterations wire. It's called a coercion dot, and we'll talk about it after this exercise. Pop up on the Number of Iterations control and choose I32 Long from the subpalette to make it go away.
4.注意在总数端子和Number of Iterations控件的连线交汇处的浅灰色点. 它被称之为强制点, 并且我们将在后面讨论. 点击Number of Iterations控件的弹出菜单并选择I32长整型数值.
5. You can save the VI if you want, but we won't be using it again. Open up another new window so you can try out the While Loop.
5.你可以保存该VI, 但是我们将不再使用这个VI. 打开另一个新窗口练习While Loop.
6. Build the VI shown in Figures 6.11 and 6.12. Remember, Booleans appear on the front panel in their default FALSE position. Also, remember to set the While Loop's conditional terminal to Continue if True.
6.创建VI如图6.11和6.12. 记住, 出现在前面板上的布尔量的默认值为FALSE. 也记住, 设置While Loop条件端子的条件状态为Continue if True.
Figure 6.11. The front panel of the VI you will build
图6.11. 你所创建的VI前面板

Figure 6.12. The block diagram of the VI you will build
图6.12. 你创建的VI程序框图

7. Flip the switch up to its TRUE position by clicking on it with the Operating tool and run the VI. When you want to stop, click on the switch to flip it down to FALSE. Loop Count will update during each loop iteration.
7.设置布尔量开关到TRUE位置, 运行该VI. 当你要停止运行, 点击开关到FALSE. Loop Count计数指示器将在每一次循环重复运行时更新一次.
![]()
Operating Tool
操作工具
8. With the switch still in the FALSE position, run the VI again. Notice that the While Loop executes once, but only once. Remember, the loop checks the conditional terminal at the end of an iteration, so it always executes at least once, regardless of what value is wired to it.
8.在布尔量开关仍然在FALSE位置时, 再次运行该VI. 注意这个While Loop只运行一次, 仅仅一次. 记住, 循环将在一次重复结束时检查条件端子, 因而, 它总是会运行一次, 无论接入的值是什么.
9. Now go to the block diagram and move the Loop Count indicator outside the loop as shown in Figure 6.13. You will have to rewire the indicator; the tunnel is created automatically as the wire leaves the loop.
9.现在回到程序框图并移动该Loop Count计数指示器到循环的外面如图6.13所示. 你将必须重新连线, 当连线离开循环时将自动地创建一个隧道.
Figure 6.13. Your VI, after moving the Loop Count indicator outside the While Loop
图6.13. 你的VI, 在移动Loop Count指示器到循环外部之后

10. Make sure the switch is TRUE and run the VI. Notice that the indicator updates only after you flip the switch FALSE and the loop has finished executing; it contains the final value of the iteration count, which is passed out after the loop completes. You will learn more about passing data out of loops in Chapter 7, "LabVIEW's Composite Data: Arrays and Clusters." Until then, do not try to pass scalar data out of a For Loop like you just did in a While Loop, or you will get bad wires and you won't understand why. It can easily be done, but you will have to learn a little about auto-indexing first.
10.确认布尔量开关的值为真TRUE时并运行该VI. 注意仅当在布尔量开关变为假FALSE和循环结束运行时显示控件才会更新; 该显示的值是重复计数端子最后的数值. 在第7章将可以学习关于传递数据到循环外部. 到目前为止, 不要试图传递标量数据到一个For Loop的外部, 如同在While Loop中所做的, 否则你将获得一些断线并且还不知道为什么. 其实也容易解决, 但你需要先学习一点自动索引(auto-indexing)的知识.
11. Save the VI. Place it in your MYWORK directory and call it Loop Count.vi.
11.保存该VI, 放置到MYWORK K的目录中命名为Loop Count.vi.
12. Now, just to demonstrate what not to do, drag the switch out of the loop (but leave it wired). Make sure the switch is TRUE, run the VI, and then hit the switch to stop it. It won't stop, will it? Once LabVIEW enters the loop, it will not check the value of controls outside of the loop (just like it didn't update the Loop Count indicator until the loop completed). Go ahead and hit the Abort button on the Toolbar to halt execution. If your switch had been FALSE when you started the loop, the loop would have only executed once instead of forever. Close the VI and do not save changes.
12.现在, 就示范那些不要做的, 拖拽开关出循环(但保留连线). 确认开关为真值, 运行该VI. 然后关闭开关去停止运行. 但停不了, 它怎么了? 一旦LabVIEW进入循环, 它将不会检查在循环之外的控件的值(就如它在循环结束运行时不会更新Loop Count指示器一样). 继续点击工具栏上的Abort按钮来中断运行. 如果开关已被置为假时你运行该循环, 循环就运行一次而不是永远循环. 关闭该VI并不要保存更改.
Abort Button中断按钮
The Coercion Dot
强制点
![]()
Remember the little gray dot present at the junction of the For Loop's count terminal and the Number of Iterations wire in the last activity? It's the coercion dot, so named because LabVIEW is coercing one numeric representation to fit another. If you wire two terminals of different numeric representations together, LabVIEW converts one to the same representation as the other. In the previous exercise, the count terminal has a 32-bit integer representation, while the Number of Iterations control is by default a double-precision floating-point number until you change it. In this case, LabVIEW converts the double-precision floating-point number to a long integer. In doing so, LabVIEW makes a new copy of the number in memory, in the proper representation. This copy takes up space. Although the extra space is negligible for scalar numbers (single-valued data types), it can add up quickly if you are using arrays (which store multiple values). Try to minimize the appearance of the coercion dot on large arrays by changing the representation of your controls and indicators to exactly match the representation of data they will carry.
记住了在上一个练习中For Loop的总数端子与Number of Iterations控件连线交汇处的小灰点吗? 它是强制点(coercion dot), 如此命名是因为LabVIEW强制一个数字的表示法以匹配另一个数字的表示法.如果你连接两个不同数字表示形式的端子, LabVIEW将转换该数字的表示形式相同于另一个. 在先前的练习中, 总数端子是32位的整型数字, 而Number of Iterations控件在你改变它之前将会是一个默认的双精密度的浮点数字. 既然如此, LabVIEW转换双精密度浮点数成为一个长整型数. 在如此操作下, LabVIEW将会在内存中以合适的表现形式复制一个新的备份. 这个备份将占据空间. 尽管这额外的空间对于标量(单一数据类型)是微不足道的, 但是如果你使用数组(保存着成倍的数值)将使得空间增加很快. 设法减少在大块数组中出现这种情形, 通过改变你的控件端子和显示端子的数值表示形式以精确地匹配他们所携带的数据类型.
To make it easier to identify coercion dots on the block diagram (which encourages you to follow the preceding rule), you can change their color from the default gray, to a more noticeable color such as bright red. To change the color, open the Tools>>Options . . . dialog and uncheck the Use default colors option (in the Colors category). Click on the Coercion Dots color and change it to any color you like, from the color palette that appears.为了更容易辨别在程序框图中的强制点(建议你遵循前面的规则), 你可以改变它们的颜色, 从默认的灰色改变成更加容易识别的颜色例如大红色. 要改变颜色, 打开Tools>>Options…的菜单, 提示并关闭使用默认颜色的选项(在Colors类别中).点击Coercion Dots颜色并从调色板中选择你喜欢的颜色.
When a VI converts floating-point numbers to integers, it rounds to the nearest integer. A number with a decimal value of ".5" is rounded to the nearest even integer.
当一个VI转换浮点数到整型数时, 它将取与该数最近的整数. 一个带有".5"小数位的数将被换算成与其最近的偶整数
An easy way to create a count terminal input with the correct data type and representation is to pop up on the count terminal and select Create Constant (for a block diagram constant) or Create Control (for a front panel control). Likewise, you can create indicators in a similar manorfor example, you can pop up on the iteration terminal and select Create Indicator (for a front panel indicator) to view the iteration count as the loop executes.创建带有合适数据类型和表示形式的总数端子的一个简单方法是从该总数端子的弹出菜单中选择创建常数Create Constant (针对于程序框图的常数)或创建控件Create Control (针对于前面板控件). 同样地, 你可以以类似的方式创建显示端子Create Indicator, 例如, 你可以从重复计数端子的弹出菜单中选择创建显示控件(针对于前面板), 在循环运行时可观察到该重复计数值






