Let's write a simple program that contains a single loop. Create a new project and name it SimpleLoop. Place two text boxes, two labels, and two button objects on the form, as shown in Figure 12.1.
Figure 12.1. The form for the simple loop program.
We have named the buttons btnStart and, as usual, btnExit . The txtResult text box is a little different from those we've used before. If you look closely at the Properties window, you'll see that we've set the Multiline property to True . This allows the text box to show multiple lines of text. We've also set the ScrollBars property to Vertical . This enables us to scroll the text box contents up and down if we need to.
To implement our loop, we're going to use the Visual Basic .NET equivalent of the old assembly language JUMP instruction, similar to the way loops were written 50 years ago! The code is shown in Listing 12.1.
Listing 12.1 The btnStart Click Event Code Creating a Program Loop
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles btnStart.Click Dim i As Integer, Sum As Integer, Terminate As Integer Dim NewLine As String NewLine = Chr(13) & Chr(10) ' Carriage-Return, Linefeed Terminate = CInt(txtPasses.Text) ' Target iterations Sum = 0 ' Clear out the running total i = 1 ' This is our loop counter txtResult.Text = "" LoopStart: Sum += i ' Calculate a running total txtResult.Text += CStr(Sum) & " (i = " & CStr(i) & ")" & NewLine If i < Terminate Then ' Are we done yet? i += 1 ' Nope...increment loop counter GoTo LoopStart ' Do another iteration End If End Sub
The program begins by defining a number of working variables . The NewLine variable consists of a carriage return, linefeed pair of characters. When added to a string and displayed, it causes the next sequence of characters to appear on the next line. That is, the carriage return character (that is, the 13 ) causes the cursor to move to the beginning of the line. The linefeed character (that is, the 10 ) moves the cursor down one line. The effect, therefore, is to display the next part of the string on a new line. This is exactly how we want to display the string that's built in the loop.
The code then sets txtResult to an empty string. We do this so that if you run the program a second time, you start with a clean text box.
The Terminate variable is set by the user and determines how many passes are made through the loop. Sum is used to maintain a running sum of the loop counter. It really doesn't do anything useful as far as the management of the loop is concerned . Notice that we did use the shorthand summation arithmetic operator with Sum .
txtResult.Text += CStr(Sum) & " (i = " & CStr(i) & ")" & NewLine
simply builds a display string for display in the txtResult text box. If you break down the statement, you'll see that it displays the running total of i (as stored in Sum ) and then parenthetically displays the loop counter, i . On the first pass through the loop, the txtResult text box would display
1 (i = 1)
Concatenating the Newline variable prepares the next pass of the loop to display the string on the next line in the text box.
The variable i is the loop counter. An If test checks to see whether i is less than Terminate . If i is less than Terminate , we need to perform another pass through the loop. As long as the If relational test is True , the Then statement block is executed. On each pass through the loop, i is incremented. (Again, we used the shorthand arithmetic operator for addition.) The GoTo statement then sends program control to the label named LoopStart .
A label statement in Visual Basic .NET is simply a placeholder in a program. (Labels are hangovers from the old days when BASIC programs used line numbers at the start of each program statement.) Label names follow the same rules as do variables, except they must end with a colon character ( : ). If you think about it, what do you suppose Visual Basic .NET puts in the symbol table for a label besides its name? Clearly, it must be a memory address because we're branching back to a previously executed set of instructions in memory. Therefore, an lvalue must be one part of the symbol table entry for a label. More specifically , it's the memory address of the program instructions that immediately follow the label. In Listing 12.1, the lvalue would be the memory address where the instructions for the
Sum += i
statement are stored.
The program loop is formed by the LoopStart label and its corresponding GoTo statement. A sample run is shown in Figure 12.2.
Figure 12.2. Sample run of the simple loop program.
You should single-step through this program to watch how GoTo sends control back to the LoopStart label.
Is This a Well-Behaved Loop?
Yes, it is. Notice that we initialize a loop counter (variable i ) just before we enter the loop. Also, we have a check to see whether we should terminate the loop or make another pass. Equally important is the increment operation of the loop counter i on each pass through the loop so that we know when to stop.
This is a fairly simple loop, but it exhibits all the characteristics of a program loop.
A Short Digression
I have a confession to make. Virtually all programmers hate Goto statements in their code. Indeed, when we talked about how early programs got so unwieldy, the greatest single culprit causing the confusion was the GoTo . The GoTo statement can cause what is called spaghetti code; that is, code that's so confusing it's difficult to trace what the program is supposed to do.
Because of these negative aspects of the GoTo , you'll hear some people say you should never use it. I think that's a bit too strong. You may find a situation where the GoTo provides a clean, easily understood means to solve a particular problem. If that's the case, by all means, use it. Still, they should be used very sparingly.
Well, because I've discouraged you from using the GoTo as a loop structure, let's explore a more conventional loop structure.