Control Structures - Iteration
The last chapter showed how a sequence of instructions can be executed once, if a condition is true. The need also frequently arises to execute a sequence of instructions repeatedly, while a condition is true, or until a condition becomes true. Such repetitive execution is called iteration.
Write a program to read the marks of a class of students in an exam, print the number of marks and compute and print the average mark. The marks are to be read one at a time, with a 'dummy' mark of 999 marking the end.
The outline of the program is:
Unlike more modern programming languages, FORTRAN lacks a while structure as such, but the effect can be obtained using an IF structure and a new statement, the GOTO.
The GOTO statement has the form:
where label is the label of an executable statement, with certain restrictions which will be considered later.
A GOTO statement causes the flow of execution to 'jump' to the labelled statement and resume from there.
We can use a GOTO to complete the program of Example 1:
PROGRAM AVMARK INTEGER TOTAL,COUNT TOTAL = 0 COUNT = 0 READ *, MARK 10 IF (MARK.NE.999) THEN COUNT = COUNT+1 TOTAL = TOTAL+MARK READ *, MARK GOTO 10 END IF IF (COUNT.GT.0) THEN AVER = 1.0*TOTAL/COUNT C MULTIPLY BY 1.0 TO CONVERT TO REAL AND AVOID TRUNCATION PRINT *, COUNT, 'MARKS WERE READ.' PRINT *, 'AVERAGE MARK IS', AVER ELSE PRINT *, 'NO MARKS WERE READ.' END IF END
Figure 8: Average mark program
The average mark program provides for the possibility that the data consists only of the terminator 999, but does no other checking. If the range of valid marks is 0 to 100, alter the program to check the validity of each mark, printing a suitable message if it is invalid, and print a count of any invalid marks with the results.
Any iterative structure is usually called a loop. As in Example 1, a loop of any kind can be constructed using an IF structure and one or more GOTO's.
Often a loop is controlled by a variable which is incremented or decremented on each iteration until a limiting value is reached, so that the number of iterations is predetermined. Such a loop is shown in Example 2.
Write a program to print a table of angles in degrees and their equivalents in radians, from 0 to 360 degrees, in steps of 10 degrees.
The program outline is:
and the program is:
PROGRAM CONVRT INTEGER DEGREE CONFAC = 3.141593/180.0 C CONVERSION FACTOR FROM DEGREES TO RADIANS DEGREE = 0 10 IF (DEGREE .LE. 360) THEN RADIAN = DEGREE*CONFAC PRINT *, DEGREE,RADIAN DEGREE = DEGREE + 10 GOTO 10 END IF END
Figure 9: Degrees to radians conversion program (version 1)
Loops of this kind occur frequently. Their essential features are:
FORTRAN provides for such loops with a structure called a DO loop, which is more concise and readable than a construction using IF and GOTO.
A DO loop is a sequence of statements beginning with a DO statement. This has the form:
DO label, var = e1, e2, [,e3]
the square brackets indicating that ',e3' may be omitted.
label is the label of an executable statement sequentially following the DO statement called the terminal statement of the DO loop.
var is an INTEGER or REAL variable called the loop control variable.
e1, e2 and e3 are arithmetic expressions (i.e. INTEGER or REAL constants, variables or more complex expressions).
The sequence of statements beginning with the statement immediately following the DO statement and ending with the terminal statement is called the range of the DO loop.
A DO loop is executed as follows:
increment > 0 var limit
increment < 0 var limit
If the condition tested is TRUE, then:
DO 10, I = 1,5
causes the range of statements beginning with the next and ending with the statement labelled 10 to be executed 5 times.
DO 10, I = 0,100,5
causes the range to be executed 21 times for values of I of 0,5,10...100.
DO 10, I = 100,0,-5
causes the range to be executed 21 times for values of I of 100,95...0.
DO 10, I = 0,100,-5
In this case, the range is not executed at all, as the test in step 3 fails for the initial value of I.
DO 10, J = I,4*N**2-1,K
Here, e1, e2 and e3 are more complex expressions.
We can now rewrite the program of Example 2 using a DO loop. The outline becomes:
and the program follows:
PROGRAM CONVRT INTEGER DEGREE CONFAC = 3.141593/180.0 C CONVERSION FACTOR FROM DEGREES TO RADIANS DO 10, DEGREE = 0,360,10 RADIAN = DEGREE*CONFAC 10 PRINT *, DEGREE,RADIAN END
Figure 10: Degrees to radians conversion program (version 2)
This is clearer and more concise than version 1. Note the use of indentation to clarify the loop structure.
Restrictions and other notes
To protect the integrity of the loop structure, there are various restrictions affecting DO loops.
Increment must not be zero.
The terminal statement must be one which is self-contained and allows execution to continue at the next statement. This rules out STOP, END and another DO statement. It is often convenient to end a DO loop with a CONTINUE statement, which has no effect whatever, serving only to mark the end of the loop.
The range of a DO loop can be entered only via the initial DO statement. Thus a GOTO cannot cause a jump into the range of a DO loop. However, GOTOs can be included in the range to jump to statements either inside or outside it. In the latter case, this can cause iteration to stop before the control variable reaches the limiting value.
GOTO 10 . DO 20, I = 1,5 . 10 . . 20 CONTINUE
is wrong, but
DO 20, I = 1,5 . 10 . . IF (...) GOTO 10 . IF (...) GOTO 30 . 20 CONTINUE . 30 .
is all right.
The control variable can be freely used in expressions in the range of the loop (as in Figure 10) but it cannot be assigned a value.
The loop parameters are the values of the expressions e1, e2 and e3 on entry to the loop. The expressions themselves are not used. Therefore if any of e1, e2 and e3 are variables, they can be assigned values within the loop without disrupting its execution.
The control variable
As explained under 'Execution' the control variable is incremented and tested at the end of each iteration. Thus, unless iteration is interrupted by a GOTO, the value of the control variable after execution of the loop will be the value which it was assigned at the end of the final iteration. For example, in a loop controlled by the statement:
DO 10, I = 0,100,5
the control variable I is incremented to exactly 100 at the end of the 20th iteration. This does not exceed limit, so another iteration is performed. I is then incremented to 105 and iteration stops, with I retaining this value.
If the control variable is REAL, inconsistent results may be obtained unless allowance is made for approximation. For example, in a loop controlled by:
DO 10, C = 0,100,5
the control variable C is incremented at the end of the 20th iteration to a value of approximately 100. If it is less, execution continues for a further iteration, but if it is greater, iteration stops.
To avoid such effects, a higher value of limit should be used, e.g.
DO 10, C = 0,101,5
Nested DO loops
DO loops, like IF structures, can be nested, provided that there is no overlapping. (i.e. that the range of each nested loop is entirely within the range of any loop in which it is nested).
Valid Invalid DO 20 ... DO 20 ... . . DO 10 ... DO 10 ... . . 10 CONTINUE 20 CONTINUE . . 20 CONTINUE 10 CONTINUE
The following provides a simple, if not very useful example of a nested loop structure.
Write a program to print a set of multiplication tables from 2 times up to 12 times.
The outline is:
and the program is:
PROGRAM TABLES DO 20, I = 2,12 PRINT *,I,' TIMES TABLE' DO 10, J = 1,12 10 PRINT *,I,' TIMES',J,' IS',I*J 20 CONTINUE END
Figure 11: Multiplication tables program
There is no logical need for the CONTINUE statement in this program as nested loops can share a common terminal statement. Thus the program could be rewritten as:
PROGRAM TABLES DO 10, I = 2,12 PRINT *,I,' TIMES TABLE' DO 10, J = 1,12 10 PRINT *,I,' TIMES',J,' IS',I*J END
However, to clarify the structure, it is better to use separate terminal statements and indentation as in the first version.