2016-06-28 4 views
1

Nach minimal Beispiel:Beenden äußerte Schleife von Unterprogramm ohne logisches Variable

L1: do while(.true.) 
    L2: do while(.true.) 
     if(something=.true.) exit L1 
    end do L2 
end do L1 

So, jetzt will ich die innere Schleife L2 in ein Unterprogramm in einem separaten Modul schreiben, um sie miteinander zu verknüpfen, wenn Sie den Code kompiliert, wie gfortran main.f95 innerloop.o -o somename

module innerloop 
contains 
    subroutine innerloop() 
    L2: do..... 
     if(something=.true.) exit L1 
    ... 
end module innerloop 

ich verschiedene Fehler bekommen, auch wenn ich den Namen Schleifen mit globalen variabels zu einem globalen Charakter über ein Modul eingestellt. Aufgrund einer großen Anzahl verschiedener if-Fälle ist es keine Idee, eine globle-Variable als Flag zu definieren und so etwas zu tun: if (something = .true.) Exitvar = .true. und dann ein if-case hinter jeder Unterroutine oder Funktion zu schreiben, wenn die Variable .true ist. oder nicht und alle Schleifen Schritt für Schritt verlassen. Gibt es eine andere Möglichkeit, eine äußere Schleife innerhalb eines separaten Unterprogramms im Modul zu verlassen?

+0

Beachten Sie, dass Sie '==' für logische Vergleiche benötigen. –

+1

Beachten Sie auch, dass '(etwas ==. Wahr.) == (etwas)', der Vergleich mit '.true.' ist redundant. –

+1

@HighPerformanceMark und auch nicht-Standard. – IanH

Antwort

4

Ihr Ansatz verstößt gegen die Fortran-Regeln bezüglich des Umfangs von "Sprüngen", egal ob sie s oder goto s oder ähnliche Konstrukte sind. Mit anderen Worten, Sie können exit-aus einer beschrifteten Do-Schleife in der Art, wie Sie vorschlagen, vergessen.

ich verschiedene Fehler bekommen, auch wenn ich die Schleife Namen zu einem globalen Zeichensatz Ja, der Konstrukt-name auf ein do (oder ähnlichem) Konstrukt ist kein Zeichen Variable oder Konstante oder eine andere Sache, dass kann während der Ausführung eingestellt werden.

Dies, Fortran's Vernunft auf dem Scoping von Sprüngen, ist eine gute Sache, die es schwieriger macht, Spaghetti Code zu schreiben. Sie möchten eine globale Variable nicht als Flag verwenden oder wollen. Verwenden Sie eine lokale Variable, vielleicht so etwas wie diese

module innerloop 
contains 
    subroutine innerloop(l1return) 
    logical, intent(out) :: l1return 
    l1return = .false. 
    L2: do..... 
     if (something) then 
      l1return = .true. 
      exit L2 
     end if 
    ... 
end module innerloop 

Ja, Sie jetzt testen, ob das Unterprogramm zu früh oder noch nicht fertig, aber das ist ein kleiner Preis zu zahlen, um den Wahnsinn zu vermeiden, die aus Rahmen von unbeschränkten Springen folgen zum Umfang.

+0

Danke für Ihre sehr gute Erklärung. :) –