Both NUM and ARRAY double precision variables, not sure how the if block will execute. When will it stop? What is it actually doing?, If we go to 8, then are we exiting the do loop?
Thanks
DO 7 I = 1,28
IF (NUM - ARRAY(I)) 8,7,7
7 CONTINUE
I=29
8 NUM = ARRAY(I)
....
....
....
....
As previously stated the conditional in the loop is an arithmetic if statement.
We know (and that's explicitly stated in the previous answer here) that if num
is less than array(i)
the label 8
is chosen, otherwise label 7
is chosen. It's also stated in that other answer that these have the effect of exiting the loop or cycling it. To be precise, I'll continue.
A DO construct has a range. A nonblock DO construct like the one in the question has range consisting of the statements between and including the do
statement and the DO termination statement (in this case 7 continue
). The DO termination statement is a valid target for a jump from within the range of the construct.
When the DO termination statement is jumped to, execution remains within the scope of the construct. That termination statement is executed (in this case, continue
, doing nothing) and the loop iteration condition is again tested. That is, the loop cycles.
From within a DO construct, a jump to a statement outside the range of the construct terminates execution of the construct: like an exit.
This example, then, has the equivalent form using an IF construct (with go to
s - bear with me)
DO 7 I = 1,28
IF (NUM < ARRAY(I)) THEN
GO TO 8
ELSE
GO TO 7
END IF
7 CONTINUE
I=29
8 NUM = ARRAY(I)
Now, because the statement labelled 7
is a continue
statement, we can write this as
DO 7 I = 1,28
IF (NUM < ARRAY(I)) THEN
GO TO 8
ELSE
CYCLE
END IF
7 CONTINUE
I=29
8 NUM = ARRAY(I)
That's still pretty ugly (and not just because of all the upper case). Fortunately, we can make this prettier. The i=29
statement will be executed only when the loop terminates without the statement labelled 8
being jumped to. Now, the loop index i
has control I = 1,28
so when the loop terminates naturally the index already has the value 29
. That assignment does nothing (in modern Fortran) so we can remove it. Which leaves us with
DO 7 I = 1,28
IF (NUM < ARRAY(I)) THEN
GO TO 8
ELSE
CYCLE
END IF
7 CONTINUE
8 NUM = ARRAY(I)
When we also note that the IF construct is immediately followed by the end of the loop (and so we don't need to explicitly cycle) we have
DO 7 I = 1,28
IF (NUM < ARRAY(I)) EXIT
7 CONTINUE
NUM = ARRAY(I)
or (more nicely)
DO I = 1,28
IF (NUM < ARRAY(I)) EXIT
END DO
NUM = ARRAY(I)
All this example is doing is finding the value of the earliest element in array(1:28)
which is larger than num
, or array(29)
if none is.