In Chapter 4, we learned how to use the GO TO and CONTINUE statements to set up a basic loop to execute a block as many times as needed (see Section 4.4). In this chapter, we learn how to set up an improved loop construct using the DO and DO WHILE statements. Once the DO and DO WHILE constructs are mastered, there is no need to rely on the GO TO statement to set up a loop. Together with the block IF construct (Section 4.2), DO loops and the related block DO constructs are the work horses of the Fortran language. A DO loop entails the repeated execution of a block encompassed within a corre sponding pair of DO and END DO statements. A block DO construct consists of (1) a DO statement, (2) a block, and (3) an END DO statement, in that order. Alternatively, a CONTINUE statement may be substituted for the END DO statement. A DO loop is controlled by its DO statement, which can be (1) indexed or (2) conditional. The indexed (DO) loop is fixed from the start to execute the block a specified number of times, unless it is interrupted by the transfer of control to a statement located outside of the loop. The conditional (DO WHILE) loop can executed zero or more times, depending upon the satisfaction of the logical expression included in the DO WHILE statement. 7.1 INDEXED DO STATEMENT
The indexed DO statement executes the block that immediately follows it, repeatedly, for a specified number of times. It has the form: DO label, variable = e1, e2, e3 in which
Examples of the indexed DO statement follow: DO 10 J= 1,11,2 DO J= 1,11,2 DO 30 J= 1,13,3 DO 40 J= 1,11 DO 50 J= 11,1,-2 The block DO construct executes the block encompassed between a corresponding pair of DO and END DO statements. If the DO statement has a label, the corre sponding END DO is that which follows the DO and has the same label. Moreover, if the DO has no label, the corresponding END DO is the first END DO that follows the DO. The CONTINUE statement can be used instead of the END DO statement. However, while the END DO statement may or may not have a label, the CONTINUE statement must have a label. In the following examples, the symbol ... stands for a block, i.e., a sequence of executable statements that is treated as a unit. Example 1: Block Do Construct With END DO DO J= 1,11 ... ! Block END DO Example 2: Block Do Construct With CONTINUE DO 10 J = 1,11 ... ! Block 10 CONTINUE DO Iteration Control The indexed DO statement DO label, variable = e1, e2, e3 performs a number of passes through the loop (iterations). The control of the number of iterations is as follows:
For example, the following DO statement
DO 10, J= 1,11,2 is the top of a loop which ends in the statement labeled 10. In this loop, the variable J is increased from 1 to 11 in increments of 2. According to the iteration count formula, the loop will be executed n = (11 - 1 + 2) / 2 = 6 times. Note that this is also the initial value of the iteration count (n = 6). With J= 1, the first pass through the loop is completed. The value of J is incremented to J= 3; the iteration count is now n = 5, and the second pass is completed. The value of J is incremented to J= 5; the iteration count is now n = 4, and the third pass is completed. The value of J is incremented to J= 7; the iteration count is now n = 3, and the fourth pass is completed. The value of J is incremented to J= 9; the iteration count is now n = 2, and the fifth pass is completed. The value of J is incremented to J= 11; the iteration count is now n = 1, and the sixth pass is completed. The value of J is incremented to J= 13; the iteration count is now n = 0, and the execution of the loop is finished, with control transferring to the statement immediately following the END DO (or CONTINUE) statement. Example 1DO 10 J= 1,11,2 ... ! Block 10 END DO This loop is executed 6 times, for values of J= 1, 3, 5, 7, 9, and 11. Example 2 DO J= 1,11,3 ... ! Block END DO This loop is executed 4 times, for values of J= 1, 4, 7, and 10. Note that the label has been omitted from both indexed DO and END DO statements. Example 3 DO K= 1,20 ... ! Block END DO This loop is executed 20 times, for values of the control variable K varying from 1 to 20, in increments of 1 (e3 = 1 is assumed). Example 4 DATA LB,LE,LI /15,1,-3/ DO 20 L= LB,LE,LI ... ! Block 20 CONTINUE This loop is executed 5 times, for values of the control variable L= 15, 12, 9, 6, and 3. Example 5 DATA XB,XE,XI /-2.5,3.5,0.5/ DO 30 X= XB,XE,XI ... ! Block 30 CONTINUE Values of the control variable real X vary from -2.5 to 3.5, in increments of 0.5. (-2.5, -2.0, -1.5, ... 3.5). This loop is executed 13 times {[3.5 - (-2.5)] / 0.5 + 1 = 13}. The CONTINUE statement is used to end the loop. The label 30 is required. Due to roundoff errors, the number of passes through a loop in which the control variable is of real type may not be precisely determined in all cases. Transfer of Control in Block DO Constructs Often there is a need to transfer control within and between Block DO constructs. For example, if a condition met during the loop processing makes it necessary to exit the loop prematurely:
Example 1: Transfer of Control Within Block DO DO J= 1,11,2 ... ! Partial block IF(J.GE.7) GO TO 5 ... ! Partial block 5 CONTINUE END DO This loop is executed 6 times, for values of the control variable J= 1, 3, 5, 7, 9, and 11. For J ≥ 7, the second partial block is bypassed. Example 2: Transfer of Control Between Block DO and Outside Statement DO J= 1,11,2 ... ! Partial block IF(J.EQ.7) GO TO 20 ... ! Partial block END DO 20 CONTINUE This loop is set to be executed 6 times, for values of J= 1, 3, 5, 7, 9, and 11. However, for J= 7, control passes to statement 20 and the loop is prematurely terminated, i.e., terminated before the iteration count n has had a chance to decrease to zero. Example 3: Invalid Block DO Transfer of Control DO K= 1,20 ... ! Partial block 5 CONTINUE ... ! Partial block END DO GO TO 5 This loop is executed 20 times. Then, it is attempted to pass control to statement 5, located inside the block DO. This operation is invalid and will cause an error during program execution. Example 4: Valid Block DO Transfer of Control N= 0 5 CONTINUE N = N + 1 DO K= 1,20 ... ! Block END DO IF(N.LE.10) GO TO 5 The block inside the loop is executed 20 times. Then, provided N ≤ 10, control is transferred to statement 5 and the loop is restarted. The entire loop is executed 10 times. Each statement in the block is executed 20 × 10 = 200 times. Rules for Control Variable in Block DO Constructs The control variable in block DO contructs DO label, variable = e1, e2, e3 is subject to specific rules. Variable cannot be redefined within a DO block, that is, it cannot appear on the left side of an assignment statement. However, variable can be referenced within a DO block, that is, it can appear on the right side of an assignment statement. Note that the final value of the control variable is the last one calculated right before the loop termination. Example 1: Referencing a Control Variable DO J= 1,11,2 ... ! Partial block K= J + 1 ... ! Partial block END DO This loop is executed 6 times, for values of the control variable J= 1, 3, 5, 7, 9, and 11. The control variable J is referenced within the DO block. The integer K is assigned a value of J+1 prior to the execution of the second partial block. Example 2: Redefining a Control Variable DO J= 1,11,2 ... ! Partial block J= J + 1 ... ! Partial block END DO The control variable J is redefined within the DO block (J = J+1). This operation is invalid and will cause an error during execution. Example 3: Final Value of a Control Variable DO J= 1,11,2 ... ! Partial block IF(J.EQ.7) THEN ... ! Partial block ENDIF END DO For J= 13, the iteration count n = 0, and the loop is terminated. Therefore, the final value of the control variable is J= 13. The last value of the control variable for which a pass through the loop was executed is J= 13 - 2 = 11. DO Loops and Fortran 90 A block DO construct, as described in this chapter, ends with either an END DO or CONTINUE statement only. A nonblock DO construct ends with any executable state ment, excluding GO TO, IF, END, RETURN, or another DO. A nonblock DO construct is allowed in Fortran 77; however, Fortran 90 has categorized the nonblock DO construct as obsolescent. Fortran 90 has also declared the use of real variables to specify control variable, initial, terminal, and increment parameters of an indexed DO statement as obsolescent. Users should avoid these features in new programming applications. Nested DO Loops If is often necessary to place one or more DO loops inside of another DO loop. This is referred to as "nesting" DO loops. When two DO loops are nested, the outer loop is referred to as the nesting loop and the inner loop is the nested loop. The nested loop should be completely contained within the nesting loop. Nested and nesting DO loops cannot share the same unlabeled END DO statement. However, they can share the same labeled END DO or CONTINUE statement. Moreover, if two or more nested DO loops share the same labeled END DO or CONTINUE statement, control can be transferred to that statement only from within the inner most DO block. Example 1: Labeled END DO Statements C234567890 DO 30 J= 1,4 ... ! Block A DO 20 K= 1,3 ... ! Block B DO 10 L= 1,2 ... ! Block C 10 END DO 20 END DO 30 END DO In this example, block A is executed 4 times; block B 3 × 4 = 12 times; and block C 2 × 3 × 4 = 24 times. (The inner loop spins fastest; the middle loop spins slower; the outer loop spins slowest; see Table 7.1). Example 2: Unlabeled END DO Statements C234567890 DO J= 1,5 ... ! Block A DO K= 1,4 ... ! Block B DO L= 1,3 ... ! Block C END DO END DO END DO Block A is executed 5 times; block B is executed 4 × 5 = 20 times; and block C is executed 3 × 4 × 5 = 60 times. Note that for each of 5 values of J, there is 4 values of K; and for each value of K, there is 3 values of L. Also, note that each loop has its own unlabeled END DO statement. Example 3: Sharing of Labeled END DO Statement C234567890 DO 30 J= 1,5 ... ! Block A DO K= 1,4 ... ! Block B DO L= 1,3 ... ! Block C 30 END DO Block A is executed 5 times; block B is executed 4 × 5 = 20 times; and block C is executed 3 × 4 × 5 = 60 times. All three loops share the same labeled END DO statement. Example 4: Labeled CONTINUE Statements C234567890 DO 60 J= 1,6 ... ! Block A DO 50 K= 1,4 ... ! Block B DO 40 L= 1,2 ... ! Block C 40 CONTINUE 50 CONTINUE 60 CONTINUE Block A is executed 6 times; block B is executed 4 × 6 = 24 times; and block C is executed 2 × 4 × 6 = 48 times. The CONTINUE statement has been used instead of the END DO statement. Example 5: Shared CONTINUE Statement C234567890 DO 60 J= 1,6 ... ! Block A DO 60 K= 1,4 ... ! Block B DO 60 L= 1,2 ... ! Block C 60 CONTINUE Block A is executed 6 times; block B is executed 4 × 6 = 24 times; and block C is executed 2 × 4 × 6 = 48 times. Example 6: Shared Labelled END DO Statement C234567890 DO 70 J= 1,10 DO 70 K= 1,15 DO 70 L= 1,5 ... ! Block 70 END DO Block is executed 5 × 15 × 10 = 750 times. Example 7: Invalid Loop Nesting C234567890 DO 90 J= 1,7 DO 80 K= 1,5 DO 70 L= 1,2 ... ! Block A 90 CONTINUE ... ! Block B 80 CONTINUE ... ! Block C 70 CONTINUE In this example, the DO loops are nested incorrectly because they overlap each other. This construct will cause an error during execution. Example 8: Valid Loop Nesting C234567890 DO 90 J= 1,7 DO 80 K= 1,5 DO 70 L= 1,2 ... ! Block A 70 CONTINUE ... ! Block B 80 CONTINUE ... ! Block C 90 CONTINUE This is the same as Example 7, but the labels have been corrected so that the loops do not overlap. Example 9: Optional Trailing Comments C234567890 DO J= 1,5 !300 ... ! Block A DO K= 1,4 !200 ... ! Block B DO L= 1,3 !100 ... ! Block C END DO !100 END DO !200 END DO !300 This is the same as Example 2, but with the addition of trailing comments to help identify the respective nested DO loops. This improves the readability of the program. Table 7.1 shows the variation pattern of the control variables J, K, and L for Example 1 above. The innermost variable, L, is executed completely (2 times) before K, the middle variable, is incremented by 1. In turn, K is executed completely (3 times) before J is incremented by 1. Thus, the outer loop is executed 4 times; the middle loop is executed 3 × 4 = 12 times, and the inner loop is executed N = 2 × 3 × 4 = 24 times.
7.2 DO WHILE STATEMENT
In many cases, it is convenient to combine the features of the block DO and block IF constructs into one construct featuring the best of both. The DO WHILE statement is a conditional loop construct that performs this function. The block DO WHILE construct conditionally executes a block as many times as necessary, as long as the tested logical expression included in the DO WHILE statement continues to be satisfied at every iteration of the loop. The DO WHILE statement has the form: DO label WHILE (logexp) in which
For instance,
DO 10 WHILE (A.LT.3.) The block DO WHILE construct executes the block encompassed between a corresponding pair of DO WHILE and END DO statements, determined in the same way as the DO-END DO pair (see Section 7.1). Furthermore, the DO WHILE-END DO pair is subject to the same labeling rules as the DO-END DO pair. For the DO WHILE loop to properly terminate, at least one of the values in the logical expression logexp must change with each pass through the loop. The change must be such that eventually the logical expression is no longer satisfied (no longer true), at which point the DO WHILE loop is logically terminated. In other words, the directive "DO THAT WHILE THIS IS TRUE" comes to an end. If this is not the case, the total number of iterations is not logically limited, and the loop continues to execute in definitely. This infinite loop condition should be avoided because it ties up the processor and leads to unnecessary delays. Example 1: Labeled Block DO WHILE Construct C234567890 DATA A /1./ ... ! Block DO 10 WHILE (A.LE.5.) WRITE(6,*)'THE VALUE OF A IS= ',A ... ! Partial block A = A + 1. 10 END DO This loop is executed 5 times, with A being incremented by 1. at every iteration of the loop. The loop comes to an end when A is greater than 5. Example 2: Block DO WHILE with Continue Statement C234567890 DATA A /1./ ... ! Block DO 10 WHILE (A.LE.5.) WRITE(6,*)'THE VALUE OF A IS= ',A ... ! Partial block A = A + 1. 10 CONTINUE This is the same as Example 1, but the CONTINUE statement is used in place of the END DO statement. Example 3: Block DO WHILE with Unlabeled END DO C234567890 DATA B /100./ DO WHILE (B.GE.5.) WRITE(6,*)'THE VALUE OF B IS= ',B ... ! Partial block B = B - 10. END DO This loop is executed 10 times, with B being decremented by 10. at every iteration of the loop. The loop finishes when B is less than 5. Example 4: Invalid DO WHILE Loop (Infinite Loop) C234567890 DATA B /5./ DO WHILE (B.GE.0.) WRITE(6,*)'THE VALUE OF B IS= ',B B = B + 1. END DO This loop continues to execute while B ≥ 0. The loop is set up in such a way that this condition is always satisfied. The initial value of B is 5., and B continues to increase with every iteration of the loop. Therefore, there is no way to logically terminate the loop. This construct will not produce an error upon execution, but will tie up the processor in an infinite loop. To stop an infinite loop, it is necessary to abort processing with a processor-dependent command such as Control/Y or similar. Nested DO WHILE Loops Just as with DO loops (Section 7.1), it is often necessary to place one or more DO WHILE loops inside of another DO WHILE loop. This is referred to as "nesting" DO WHILE loops. As stated previously, the nested loop should be completely contained within the nesting loop. The following rules apply to nested DO WHILE loops:
Example 1: Labeled Nested DO WHILE Statements C234567890 DO 20 WHILE (A.GE.0.) ... ! Block 1 A= A - 0.5 DO 10 WHILE (B.GE.5.) ... ! Block 2 B= B - 1.5 10 END DO 20 END DO Block 1 is executed if A ≥ 0. If block 1 is executed, block 2 is also executed, provided B ≥ 5. Both A and B need to decrease at every iteration of the loop if the nested DO WHILE construct is to eventually terminate. Example 2: Sharing of Labeled END DO in Nested DO WHILE Statements C234567890 DO 20 WHILE (A.GE.0.) ... ! Block 1 A= A - 0.5 DO 20 WHILE (B.GE.5.) ... ! Block 2 B= B - 1.5 20 END DO This is the same as Example 1, but nested and nesting DO WHILE loops share the same labeled END DO statement. Example 3: Sharing of Labeled CONTINUE in Nested DO WHILE Statements C234567890 DO 20 WHILE (A.GE.0.) ... ! Block 1 A= A - 0.5 DO 20 WHILE (B.GE.5.) ... ! Block 2 B= B - 1.5 20 CONTINUE This is the same as Example 2, but the CONTINUE statement is used in place of the END DO statement. Example 4: Three Nested DO WHILE Loops C234567890 DO WHILE (A.GE.0.) ... ! Block 1 DO WHILE (B.GE.5.) ... ! Block 2 DO WHILE (C.GE.10.) ... ! Block 3 END DO END DO END DO This is an example of three nested DO WHILE loops. Block 1 is executed if A ≥ 0. If block 1 is executed, block 2 is also executed provided B ≥ 5. If block 2 is executed, block 3 is also executed provided C ≥ 10. Again, a provision needs to be made for all three variables, A, B, and C, to decrease at every iteration of the loop if the nested DO WHILE construct is to eventually terminate. Example 5: Three Nested DO WHILE Loops with Optional Trailing Comments C234567890 DO WHILE (A.GE.0.) !300 ... ! Block 1 DO WHILE (B.GE.5.) !200 ... ! Block 2 DO WHILE (C.GE.10.) !100 ... ! Block 3 END DO !100 END DO !200 END DO !300 This is the same as Example 4, but with the addition of trailing comments to properly identify the respective nested DO WHILE loops. Like indenting, trailing comments improve the readability of the program.
7.3 EXAMPLE PROGRAM
Example Program 1: Table of Trigonometric Functions Using a DO Loop Compare this program with Example Program 1 of Section 6.4. This program uses a DO loop instead of an IF-GO TO loop.
Example Program 2: Tic-Tac-Toe Board Using DO Loop and Block IF The following program writes the tic-tac-toe board of Example 2, Section 5.5, directly to the screen, using a DO loop and block IF combination.
Included features of this program are:
Example Program 3: Tic-Tac-Toe Board Using DO WHILE Loop and Nested Block IF The following program also writes the tic-tac-toe board of Example Program 2, Section 5.5, directly to the screen. This program differs from the previous program in that it uses a DO WHILE loop and nested block IF combination.
Included features of this program are:
1.5 SUMMARY
PROBLEMS
|
Documents in Portable Document Format (PDF) require Adobe Acrobat Reader 5.0 or higher to view; download Adobe Acrobat Reader. |
FORTRAN FOR SCIENTISTS AND ENGINEERS VICTOR M. PONCE • ONLINE EDITION • | |||||||
Copyright © 2014 • Victor M. Ponce • All rights reserved. |