简体   繁体   中英

Restart a loop in Fortran

I have an algorithm that looks like this:

10 WRITE (*,*) "Start"
DO I = 1, 10
WRITE (*,*) "Step"
IF(I .EQ. 5) then 
    go to 10
END IF
END DO

I want to restart the loop, when that if statement executes. However, I don't want to have to use a go to, I tried this:

10 WRITE (*,*) "Start"
DO I = 1, 10
WRITE (*,*) "Step"
IF(I .EQ. 5) then 
    I = 0; CYCLE
END IF
END DO

But then I get the error that I can't redefine the I variable, inside a loop. So I'm not sure how to approach this. Any help would be much appreciated

A conceptually simple way to phrase this problem is: "I want to repeat a loop until it completes, where there is some abort condition".

This "repeat until it completes" is idiomatically a do construct with indeterminate iterations:

do
  ...  ! Our actions; we exit this outer loop when we are satisfied
end do

[This could also be phrased as a do-while loop.]

With the inner loop:

do
  do i=1,10
     ... ! A conditional statement which aborts the inner loop
     ... ! And some actions
  end do
  ! And once we're complete we exit the outer loop
end do

Now it's just a matter of handling "abort inner" and "exit outer". Here cycle and exit :

outer: do
  print*, 'Start'
  do i=1,10
    print*, 'Step'
    if (...) cycle outer   ! Abort the inner loop
  end do
  exit outer  ! The inner loop completed, so we're done
end do outer

The outer loop is labelled so that the cycle statement in the inner loop can reference it. Without that label the cycle will cycle the innermost loop containing it.

Likely a typo here somewhere, but this has some other ideas in a "do while" sense.

ie One could poll something coming in.

... USE ISO... etc stuff.
REAL(KIND=C_FLOAT), DIMENSION(10) :: A
LOGICAL(KIND=C_BOOL)              :: Question1 = .TRUE.
LOGICAL(KIND=C_BOOL)              :: Question2 = .TRUE.
INTEGER(KIND=C_INT)               :: Index     = 0
INTEGER(KIND=C_INT)               :: I         = 5

WRITE(*,*)'Enter first index to skip:"
READ(*,*) I

Outer_Loop: DO WHILE (Question1)    ! .eq. .TRUE.

  Inner_Loop:  DO WHILE (Question2) ! .EQV. .TRUE.
    Index = Index + 1
    IF(Index > UBOUND(A,1)) THEN
      Question1 = .FALSE.
      Question2 = .FALSE.
      Exit
    ENDIF
    IF(Index == I) EXIT

    !Whatever like  A(INdex) = something....

  ENDDO Inner_Loop

  IF(Question1) THEN   !We must have more to possibly read or do...
    WRITE(*,*)'Do more? 1=yes, 0=No"
    READ(*,*) I
    IF(I == 1) THEN
      WRITE(*,*)'Enter next index to skip:"
      READ(*,*) I
      Question2 = .TRUE.
  !and one can do a reset of I=0 here, which then becomes I=1 the next time through the inner loop...
    ELSE
      Question1 = .FALSE.
      Question2 = .FALSE.
      EXIT
    ENDIF
  ELSE   !Must have gotten here to exit at the end of array?
    EXIT
  ENDIF
ENDDO Outer_Loop

I can suggest to ways of solving this issue: either use a while loop or a recursive function (highly depends on your actual algorithm). I am attaching a sample code for both cases (keep in mind that having variables with save qualifier is not the best idea, it's much better to do that with by passing variables as arguments to function - here it is used just for simplicity)

module functions

    implicit none

    integer :: restarted, save = 0
contains

    recursive subroutine restart_loop
        integer :: i

        do i = 1, 10
            print*, i
            if ( i == 5 .and. restarted < 5 ) then
                restarted = restarted + 1
                call restart_loop
                exit
            end if            
        end do        
    end subroutine restart_loop

    subroutine while_loop
        integer :: i = 1

        do while (i <= 10)
            print*, i
            if ( i == 5 .and. restarted < 5 ) then
                i = 1
                restarted = restarted + 1
            end if
            i = i + 1
        end do
    end subroutine while_loop
end module functions

program test_prog
    use functions

    implicit none

    call while_loop
end program test_prog

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM