Loop Construct
Control flow constructs Control Flow constructs seen so far sequential flow two-way or multi-way branching flow These constructs are not enough!
Sum of Square roots Problem: Compute sum of square roots of numbers from 1 to 5 One solution: program sum_sqroot implicit none real :: sum,sum1,sum2,sum3,sum4 sum1 = sqrt(1.0) sum2 = sum1 + sqrt(2.0) sum3 = sum2 + sqrt(3.0) sum4 = sum3 + sqrt(4.0) sum = sum4 + sqrt(5.0) print *, sum end program
Summing Square roots What are the problems with this solution? No need for so many sum variables; use instead sum = sum + sqrt(..) what if 10, 20 or 100 numbers to be added? code repetition possible but undesirable what if an unknown numbers (given as input) to be added? code repetition not possible at all
Looping Loop constructs are designed to solve the above problems Loop constructs enable execution of same piece of code a specified number of time Two kinds of loop constructs: Controlled loop Uncontrolled loop The above problem can be solved using controlled loop
Example Program sum_sqrt implicit none real :: x,sum sum = 0.0 !initialization needed. why? see the loop !looping construct do i = 1,5 !loop body executed five times x = real(i) sum = sum + sqrt(x) !each time i incremented by 1 end do print *, sum end program
Controlled Loop Construct General form: do var = init, fin, inc loop_body end do var, called control variable, must be integer init,fin,inc are integer expressions inc must be non-zero, can be negative and default value is 1 loop_body must not modify value of var
Iteration loop_body is executed repeatedly each execution is called an iteration initially, var = init after every iteration inc is added to var loop is terminated when value of var exceeds fin (or smaller than fin) Loop body is executed a fixed number of times number of iterations may depend on values of variables
Controlled Loop number of iterations (for +ve inc) iter-count = (fin-init+inc)/inc iter-count is computed when the do statement is first encountered if iter-count <= 0 , loop is not executed if iter-count > 0, loop_body is executed, iter-count is decremented by 1 and var is incremented in every iteration loop terminates finally when iter-count <= 0, i.e., the control flows to the statement immediately following the loop statement
Controlled Loop iter-count is computed when the do statement is first encountered Its value depends upon the values at that point values of init, fin, inc should not be changed inside the loop var is incremented by the value of inc in every iteration It is assigned the value init when do is first encountered
Cycle and Exit statements loop_body can contain two special statements Cycle It terminates the current iteration and the next iteration is started, if there is one Exit This terminates the loop moving the control to the statement following the loop
Example Read a line of characters, Count the number of e occurring in the line Replace every a by # Lines of length 80 or ended by $ sign
program e_count character(len=80) :: line integer :: counter,index read *, line index=1 counter = 0 do index = 1, 80 if (line(index:index) = = "$“) exit !exit the loop if end of line if (line(index:index) == "e“) then counter = counter +1 cycle !skip the rest of the loop endif if (line(index:index) == "a“) then line(index:index) = "#" endif end do print *, counter, line
Uncontrolled Loop The controlled loop is a simple loop computation The loop body executed for a number of times that is fixed a priori or at least prior to the execution of the do statement Many times repeat a computation till certain condition holds No upper bound on the number of iterations exists More general loops are required for describing these Uncontrolled loops are meant for this
Another Example Similar to the earlier problem there is no upper bound on the length of the line all lines should be terminated by $ index =0 do !uncontrolled loop index = index +1 if (line(index:index) == "$“) exit if (line(index:index) == "e" ) then counter = counter +1 cycle endif if (line(index:index) == "a" ) then line(index:index) = "#" endif end do
Uncontrolled loop Controlled loop does many things implicitly control variable updation, exit condition checking In uncontrolled version, these have to be done explicitly Termination is guaranteed in the controlled one Termination need to be ensured in the uncontrolled one explicit inclusion of exit statements is required In e_count1, for termination of the loop, the end of line condition is required In e_count, the loop terminates automatically after reading at most 80 characters Controlled loop is safe but less general
General Form do loop_body end do Any number of exit statements can occur in the loop_body At least one required Possibility of non termination, in any case
Loops Loop is an important construct Most programs will involve loops Loops encode potentially unbounded computations Mastering loops is important Loops cause non termination, a most common programming error Correct programs should be terminating Every loop is associated with a condition called loop invariants Loop invariant holds at the beginning of every iteration
Nested Loops Like many other constructs loops can also be nested do statement1 do statement2 end do statement3 end do Note that `inner do' ends before the `outer do‘ Exit and cycle in statement2 refers to the inner loop Exit and cycle in statement1 and statement3 refer to the outer loop
Labeling loops For ease of understanding loops can be labeled: outer: do statement1 inner: do statement2 end do inner statement3 end do outer exit and cycle statements can name the loop exit outer, cycle outer unnamed statements refer to the innermost enclosing loops
Labeling control constructs Like loops all other constructs can be labeled Examples: cond1: if (test1) then statement elseif (test2) then cond1 statement else cond1 statement endif cond1 Similarly for select case construct