THE BEGINNER'S PAGE
Tom R. Halfhill, Editor
Assembly Line Computing
Henry Ford is recognized as a famous person for founding the Ford Motor Company, inventing the Model T automobile, and making himself a multimillionaire. But historians point out that his greatest contribution may well have been popularizing the assembly line. The concept of the assembly line offers a practical solution to a common problem: automating a repetitive task for greater efficiency.
In last month's column we discussed how subroutines—programs within a program—can save time, memory, and increase execution speed by performing tasks that are required over and over again. But there's yet another way you can increase the efficiency of your programs whenever a repetitive job is called for: looping.
Looping is such a powerful, valuable technique that—like subroutines—it is a primary technique in all computer programming languages. And nearly any program you write will contain some kind of loop. (In fact, most programs are one giant loop.) A program shorn of its loops would be about as efficient as a modern factory without assembly lines. Fortunately this indispensable technique is easy to learn, and in its simplest form, involves only two BASIC keywords: FOR and NEXT.
When To Loop
By the way, it's important to realize that there's not much overlap between subroutines and loops. In other words, you won't often encounter a situation when a subroutine or a loop will be equally efficient ways of solving a certain programming problem. Generally, subroutines are useful when you need to perform a particular task again and again in different parts of a program; loops are useful when you need to repeatedly perform a task in one section of a program. Let's demonstrate this difference by setting up a sample problem.
Suppose for some reason you want to print a column of asterisks (*) down the left side of the screen, perhaps as a border for a title screen. Without using either subroutines or loops, you might take this approach:
10 PRINT "*" 20 PRINT "*" 40 PRINT "*" 50 PRINT "*" 60 PRINT "*" 70 PRINT "*" 80 PRINT "*" …
This obviously isn't very efficient.
Creating a subroutine to do the job doesn't help because you have to repeatedly call the routine:
10 GOSUB 100 20 GOSUB 100 30 GOSUB 100 40 GOSUB 100 50 GOSUB 100 60 GOSUB 100 70 GOSUB 100 80 GOSUB 100 90 END 100 PRINT "*" 110 RETURN
Clearly, there's a better way. Here's how to solve the problem with a loop that is constructed with an IF-THEN and a GOTO statement:
10 X = 0 20 PRINT "*" 30 X = X + 1 40 IF X<8 THEN 20
Line 10 sets the variable X to a value of 0. Line 20 prints an asterisk. Line 30 adds 1 to the value of X. Line 40 checks the value of X to see if it is less than 8. If so, it jumps back to line 20.
The loop in this case consists of lines 20-40. At the conclusion of the first pass through the loop, X equals 1. During each pass, line 30 adds 1 to X again (increments X). Therefore, after the second pass through the loop, X equals 2; after the third pass, X equals 3; and so on. (When a variable is used like this, it's called a counter.) Line 40, the last line in the loop, always checks to make sure X is less than 8, because we want to print no more than eight asterisks. Each time line 40 determines that X is less than 8, it circles back to line 20 for another pass through the loop, and another asterisk is printed.
After eight passes (or iterations), the counter X finally reaches a value of 8. Then it fails the IF-THEN test in line 40, and the program ends.
A Better Way
Notice how this simple loop prints the eight asterisks with only half as many program lines as the two crude methods above. Its efficiency becomes even more apparent when you realize that you could print any number of asterisks without making the program longer—simply reset the maximum value for the counter by changing the 8 in line 40 to 10, or 50, or 1000, or whatever you want.
Incidentally, this loop can be made to repeat in a couple of different ways (only the third example works on the TI without Extended BASIC):
40 IF X = 8 THEN END 50 GOTO 20
40 IF X>7 THEN END 50 GOTO 20
40 IF X <> THEN 20
Like any versatile language, BASIC usually has more than one way to say the same thing.
In fact, BASIC includes two special keywords that let you construct loops in an even more compact fashion:
10 FOR X = 1 TO 8 20 PRINT "*" 30 NEXT Y
Now we're getting somewhere. Even if you don't understand yet how this loop works, it simply looks more efficient—or, in programming jargon, more elegant. Besides that, it's the easiest way to make a loop.
Looping With FOR-NEXT
Constructing a loop by incrementing a counter (X = X + 1), checking the counter to see if it has reached a certain value (IF-THEN), and circling back for another pass (GOTO) is a useful programming technique, but it has some pitfalls. The most common mistake is to accidentally GOTO the wrong line number and reinitialize the counter variable during each pass:
10 X = 0 20 PRINT "*" 30 X = X + 1 40 IF X<8 THEN 10
When this program runs, it never ends. After the first pass through the loop, X has been incremented to a value of 1, and then line 40 circles back for another pass. Okay so far. But line 40 circles back to line 10 instead of line 20 as intended. Line 10 sets X equal to 0 again, and the process repeats. X never reaches 8. The result is an endless or infinite loop—the computer obediently keeps printing asterisks forever, or at least until you break out of the program or cut off the power.
Sometimes, depending on the circumstances, you have to make a loop with counter variables and IF-THENs. But a better alternative is the FOR-NEXT statement. FOR-NEXT automatically increments the counter for you and always circles back to the right line. All you have to do is set up the FOR-NEXT statement correctly in the first place, and that requires only three easy steps:
- Mark the beginning of the loop by entering FOR X = 1 TO 8 (of course, you can define the number of times the loop will repeat by substituting any number you want for the 8).
- Enter the program lines for the repetitive task you want the computer to perform during each pass through the loop (such as PRINT "*" in the example above).
- Mark the end of the loop by entering NEXT X.
That's it. The FOR part of the statement takes care of incrementing the counter X during each pass. It also replaces the IF-THEN statement in the earlier example by performing the loop only the number of times you specify. And the NEXT part of the statement always circles back to the FOR. By using FOR-NEXT, potential mistakes are avoided, less memory is consumed, and the program probably runs faster, too.
There's much more to FOR-NEXT loops; this month we've just scratched the surface. Next month's column will reveal some additional techniques and cover some peculiarities of FOR-NEXT on different computers.