QBasic - Step By Step :: Section 5
Author: Mike Ware
Website: [warebiz] :: "The Programmer's Domain" - http://warebiz.tripod.com
Email: warebiz@yahoo.com
Copyright © 2002 Michael Shawn Ware, All Rights Reserved.


You are here --> [Section 5 :: Controlling Execution With Loops ]

"Jump To Articles"
    --> What is Looping?
    --> DO...LOOP
    --> FOR...NEXT
    --> Nested Loops
    --> Exiting Prematurely: Good or Bad?


What is Looping?

Loops allow a specified group of statements to be executed a certain number of times. Because the exact same code is being executed a certain number of times, we call this "looping" or "iteration" in programming. QBasic offers two type of looping statements: DO...LOOP and FOR...NEXT. Situations may arise when you need to perform the same task many times in a program. For instance, consider a problem where you need to get the same information for twenty students in a class. Instead of writing the exact same tedious and error-filled code twenty times in a program to get the information, you could set up a loop to control execution so it "loops" or "cycles" through a certain block of code twenty times and then kicks back out to the next executable statement in the program. We can use a loop control variable, which is used to determine whether or not a loop will be repeated, to allow the loop to be executed twenty times. We call the statements inside the actual loop the loop body.

Before the loop begins the loop process, a loop control variable is initialized to a value. The compiler will then "test" the loop control variable to see if the loop will be executed or should end. This "test" is determined by a test expression in the loop. If the loop control variable does not meet the conditions for it to stop execution, the body of the loop will be executed, and then execution moves back to "test" the loop control variable again, and so on. At some point during the loop process, the value of the loop control variable will have to be modified so the loop will eventually be forced to end execution. If the loop control variable is never modified, the loop will continue until the computer has now more resources; we call this an infinite loop. You can end an infinite loop by pressing CTRL-Break at the keyboard during execution. Once loop execution has stopped, execution will move to the next statement in the program.

DO...LOOP

The DO...LOOP has two forms in QBasic: DO WHILE...LOOP and DO UNTIL...LOOP. Let's begin with the DO WHILE...LOOP. This type of loop is executed "while" the test expression in the loop is true. The test expression is a boolean expression which means that it either evalutes to true or false. When using this type of loop, you normally will use two other key programming terms but you don't necessarily need to use them: a sentinel value and a prime read. A sentinel value is a value that should not been in the range of formal input supplied by the user but is of the correct type, used as a value (condition) for the "test" expression. A prime read is a variable that holds the value of the loop control variable before the loop is entered for the first time; in other words, the prime read is "read" before the loop process. The following is the form of a DO WHILE...LOOP:


DO WHILE (test expression)
    REM loop body goes here
    REM the loop control variable must be manipulated at some point to avoid infinite loop
LOOP

For example, consider the following simple loop:


numberTotal = 0;
INPUT "Enter a number to be added (-999 to quit): "; number
DO WHILE number <> -999
     numberTotal = numberTotal + number
     INPUT "Enter a number to be added (-999 to quit): "; number
LOOP

In the above loop, the loop control variable is ( number ), ( -999 ) is used as a sentinel value, and ( number ) is used as a prime read. The user has the oppurtunity to input a number before the loop begins. If the number inputted is not equal to -999, then the loop process will begin. Notice that there is another INPUT statement at the end of the loop. This is provided so the user can enter another value for number, which is acting as the loop control variable. The user can enter as many numbers as he/she wishes, and can therefore exit the loop by inputting -999.

A counter is also used to control execution of a loop; it increments/decrements each time through the loop and it is "tested" in the loop expression. A counter is good to use when you specifically know how many times you need to execute the loop. For example, consider the following loop where ( count ) is used as a counter:


count = 1
DO WHILE count <= 10
     PRINT count
     count = count + 1
LOOP

The DO UNTIL...LOOP is very similar to the DO WHILE...LOOP. The only difference is that the loop is executed "until" a certain condition is reached rather than "while" a certain condition is met. Any DO WHILE...LOOP can be rewritten as a DO UNTIL...LOOP and vice versa. The form of the DO UNTIL...LOOP is as follows:


DO UNTIL (test expression)
    REM loop body goes here
    REM the loop control variable must be manipulated at some point to avoid infinite loop
LOOP

FOR...NEXT

A FOR...NEXT loop is generally used as a counter loop when you know exactly how many times you need to execute the loop. The form of a FOR...NEXT loop is as follows:


FOR (loop control variable) = initialValue TO endValue STEP stepValue
    REM loop body goes here
    REM the loop control variable must be manipulated at some point to avoid infinite loop
NEXT (loop control variable)

The loop control variable is any variable used as a counter. It will be first intialized to the specified initialValue. The endValue marks the condition when the loop should end "looping". The optional stepValue specifies how large to increase/decrease the loop control variable. If not provided, the default stepValue is 1. For example, consider the following:


FOR count = 0 TO 100 STEP 5
      PRINT count
      PRINT
NEXT (loop control variable)

The above code would output the multiples of 5 up to 100, including 0. For another example, consider the following which would perform the exact opposite:


FOR count = 100 TO 0 STEP -5
      PRINT count
      PRINT
NEXT (loop control variable)

Nested Loops

Just like we saw how to "nest" decision statements [see Section 3 - Controlling Execution With Control Structures], we can also "nest" loops. The outside loop would be evaluated first, and then execution would move into the body which would contain a "nested" loop to be evaluated and processed. Everytime through each cycle of the outside loop, the inside loop will be completely processed. The form of nested loops is as follows:


FOR outer = 1 TO 5
       FOR inner = 1 TO 10
           REM loop body goes here
      NEXT inner
NEXT outer

Exiting Prematurely: Good or Bad?

There is a way to "exit" or end the execution of loop prematurely. The statement EXIT is used to perform this operation. It will simply terminate the current executable statement and place control to the next statement in the program. You can also use the EXIT statement to exit sub procedures [see Using Modules (section 4)]. It is important to note that this is not considered good programming practice and should be avoided because it generally leads to errors, bugs, and spaghetti code (code that is hard to understand and follow).

The following is a complete program example demonstrating most of the information covered up to this point in the tutorial:


\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

DECLARE SUB GetData (type$, regPrice!, regMonth!, effPrice!, effMonth!)
DECLARE SUB PrintReport (type$, regPrice!, regMonth!, effPrice!, effMonth!, years!)
DECLARE SUB DetermineYears (regPrice!, effPrice!, regMonth!, effMonth!, years!)

REM *******************************************************************
REM This program prompts the user to enter information
REM (type, cost, monthly cost, efficient cost, efficient monthly cost)
REM about a certain computer (modern computer and high-tech computer)
REM and will determine how long it will take for the user to start
REM saving money based on his computer purchase. The high-tech
REM computer is assumed to be more expensive than the modern computer
REM but should have a yearly maitenance cost considerable less.
REM *******************************************************************

CLS

answer$ = "Y"
DO WHILE answer$ = "Y"

   CLS
   header = (80 - LEN("COMPUTER SHOP AND SAVE")) / 2
   PRINT TAB(header); "COMPUTER SHOP AND SAVE"
   PRINT

   CALL GetData(type$, regPrice, regMonth, effPrice, effMonth)

   CALL DetermineYears(regPrice, effPrice, regMonth, effMonth, years)

   CALL PrintReport(type$, regPrice, regMonth, effPrice, effMonth, years)

   INPUT "Do you wish to enter data on another appliance (Y/N): ", answer$
   PRINT
LOOP

END

SUB DetermineYears (regPrice, effPrice, regMonth, effMonth, years)

years = 0
cost1 = regPrice
cost2 = effPrice

DO UNTIL cost1 > cost2
   cost1 = cost1 + regMonth
   cost2 = cost2 + effMonth
   years = years + 1
LOOP

END SUB

SUB GetData (type$, regPrice, regMonth, effPrice, effMonth)

INPUT "Enter the type of the computer (laptop/desktop): ", type$
INPUT "Enter the price of regular model: ", regPrice
INPUT "Enter the yearly operating cost of regular model: ", regMonth
INPUT "Enter the price of high-tech model: ", effPrice
INPUT "Enter the yearly operating cost of high-tech model: ", effMonth

END SUB

SUB PrintReport (type$, regPrice, regMonth, effPrice, effMonth, years)

format$ = "\                \     $$####.##               $$##.##"
PRINT
PRINT "COMPUTER:", type$
PRINT
PRINT "MODEL"; SPC(17); "PURCHASE PRICE"; SPC(9); "YEARLY COST"
PRINT USING format$; "Modern"; regPrice; regMonth
PRINT USING format$; "High-Tech"; effPrice; effMonth
PRINT
PRINT "You will begin saving money after"; years; "years."
PRINT

END SUB

/////////////////////////////////////////////////////////////////////////////////////////////////

In the next section, we will discuss some handy "built-in" functions and how you can create your own user-defined functions to perform particular tasks.

Move on to next set of topics: Section 6 - Using and Creating Functions

Back to Top