Sergej: sprung aus der n-ten in die m-te Schleife ?

Hallo,

kann man irgend wie aus der n-ten Schleife in die m-te springen?
Bsp:

for (.. ;.. ;.. ) {      <== 1. Schleife
        * <= hier will ich herspringen
 for (.. ;.. ;.. ){   <== 2. Schleife
     if (..) {   <== 3. Bedingung
       foreach (@xxx) { <== 4. Schleife
          if (..) {  <== 5. Bedingung für Sprung
                                  .. Ab hier will ich in die 2. Schleife rein also nach *
          }
    }
         }
    }
}

Geht das mit dem next Befehl, oder anderen?
Also soweit ich verstanden habe, geht der Sprung nur aus der aktuellen Schleife.

Danke für die Hilfe,
Gruß Sergej

  1. Hallo,

    for (.. ;.. ;.. ) {      <== 1. Schleife
             * <= hier will ich herspringen
      for (.. ;.. ;.. ){   <== 2. Schleife
          if (..) {   <== 3. Bedingung
            foreach (@xxx) { <== 4. Schleife
               if (..) {  <== 5. Bedingung für Sprung
                                       .. Ab hier will ich in die 2. Schleife rein also nach *
                 }
            }

    KORREKTUR, sonst macht die Frage kein Sinn ;-) !!

    natürlich habe ich hier Ausgaben und Berechnungen!
          }
           natürlich habe ich hier Ausgaben und Berechnungen!

    }
     }

  2. Hi

    for (.. ;.. ;.. ) {      <== 1. Schleife
            * <= hier will ich herspringen
    for (.. ;.. ;.. ){   <== 2. Schleife
         if (..) {   <== 3. Bedingung
           foreach (@xxx) { <== 4. Schleife
              if (..) {  <== 5. Bedingung für Sprung
                                      .. Ab hier will ich in die 2. Schleife rein also nach *
              }
        }
             }
        }
    }

    Geht das mit dem next Befehl, oder anderen?

    "next" springt an den anfang der aktuellen Schleife.
    "last" verläßt die aktuelle Schleife.
    Du landest also in der übergeordneten schleife. Hinter dem Aufruf der aktuell verlassenen Schleife !!!
    Du mußt also wohl irgend wie "flags" setzen und in der übergeordeneten Schleife diese auswerten um eventuell dort auch ein "last" zu setzen um noch eine Schleife "höher" zu kommen.

    Oder Du nutzt ein "goto <Label>".

    Bye
    Timothy

    --
    Zwei Dinge im Leben kannst du nicht zurück holen. Den Pfeil, den du verschossen. Und das Wort, das du gesprochen.
    (alte indianische Weisheit)
    1. Du mußt also wohl irgend wie "flags" setzen und in der übergeordeneten Schleife diese auswerten um eventuell dort auch ein "last" zu setzen um noch eine Schleife "höher" zu kommen.

      klingt verlockend.

      Oder Du nutzt ein "goto <Label>".

      goto gefält mir besser!
      Danke

      Bye
      Timothy

      Gruß Sergej

      1. Hi

        goto gefält mir besser!

        ist aber schlechter Stil ;-)

        Bye
        Timothy

        --
        Zwei Dinge im Leben kannst du nicht zurück holen. Den Pfeil, den du verschossen. Und das Wort, das du gesprochen.
        (alte indianische Weisheit)
        1. goto gefällt mir besser!

          ist aber schlechter Stil ;-)

          Du meinst der Script würde nicht korrekt ablaufen,
          oder besser: es könnten Fehler bei Sprüngen auftauchen?

          Gruß Sergej

          1. Hi

            Du meinst der Script würde nicht korrekt ablaufen,
            oder besser: es könnten Fehler bei Sprüngen auftauchen?

            Im Sinne der strukturierten Programmierung sind "goto"s eigentlich verboten. Programme werden daurch unübersichtlich. Aber das muß jeder für sich entscheiden. Ich nutze "goto"s grundsätzlich nicht.
            Ob das (!!!) Script nicht korrekt abläuft hängt nicht vordergründig von "goto"s ab.
            Sie stellen aber eine potenzielle Fehlerquelle dar.

            Deshalb meine Empfehlung: Nicht verwenden !!!

            Bye
            Timothy

            --
            Zwei Dinge im Leben kannst du nicht zurück holen. Den Pfeil, den du verschossen. Und das Wort, das du gesprochen.
            (alte indianische Weisheit)
  3. Hallo,

    kann man irgend wie aus der n-ten Schleife in die m-te springen?
    Bsp:

    for (.. ;.. ;.. ) {      <== 1. Schleife
            * <= hier will ich herspringen
    for (.. ;.. ;.. ){   <== 2. Schleife
         if (..) {   <== 3. Bedingung
           foreach (@xxx) { <== 4. Schleife
              if (..) {  <== 5. Bedingung für Sprung
                                      .. Ab hier will ich in die 2. Schleife rein also nach *
              }
        }
             }
        }
    }

    Geht das mit dem next Befehl, oder anderen?
    Also soweit ich verstanden habe, geht der Sprung nur aus der aktuellen Schleife.

    Es geht mit Labels. (nicht mit goto, sondern z.b. next LABEL)
    Aber ich würde dir raten so nicht zu programmieren, du wirst irgendwann keine Freude mehr an deinem Code haben.

    Nimm Funktionen, aus denen kannst du überall rausspringen.

    for (.. ;.. ;.. ) {      <== 1. Schleife
    [...]
    next unless func1(....);

    [... mach weiter]
    }

    sub func1
    {
      for (.. ;.. ;.. ){   <== 2. Schleife
       if (..) {   <== 3. Bedingung
           foreach (@xxx) { <== 4. Schleife
            if (..) {  <== 5. Bedingung für Sprung
             return 1;
            }
           }
       }
      }
      return 0;
    }

    Das macht deine Programme wesentlich übersichtlicher, vor allem, wenn du den Subs aussagekräftige Namen gibst.

    Struppi.

    1. Hi

      Es geht mit Labels. (nicht mit goto, sondern z.b. next LABEL)

      Okay - hast ja recht.
      Hier also ganz konkret:

      9.4 Labeled Blocks

      What if you want to jump out of the block that contains the innermost block, or to put it another way, exit from two nested blocks at once? In C, you'd resort to that much maligned goto to get you out. No such kludge is required in Perl; you can use last, next, and redo on any enclosing block by giving the block a name with a label.

      A label is yet another type of name from yet another namespace following the same rules as scalars, arrays, hashes, and subroutines. As we'll see, however, a label doesn't have a special prefix punctuation character (like $ for scalars, & for subroutines, and so on), so a label named print conflicts with the reserved word print and would not be allowed. For this reason, you should choose labels that consist entirely of uppercase letters and digits, which will never be chosen for a reserved word in the future. Besides, using all uppercase stands out better within the text of a mostly lowercase program.

      Once you've chosen your label, place it immediately in front of the statement containing the block followed by a colon, like this:

      SOMELABEL: while (condition) {
          statement;
          statement;
          statement;
          if (nuthercondition) {
              last SOMELABEL;
          }
      }

      We added SOMELABEL as a parameter to last. This tells Perl to exit the block named SOMELABEL, rather than just the innermost block. In this case, we don't have anything but the innermost block. But suppose we had nested loops:

      OUTER: for ($i = 1; $i <= 10; $i++) {
          INNER: for ($j = 1; $j <= 10; $j++) {
              if ($i * $j == 63) {
                  print "$i times $j is 63!\n";
                  last OUTER;
                  }
              if ($j >= $i) {
                  next OUTER;
              }
          }
      }

      This set of statements tries all successive values of two small numbers multiplied together until it finds a pair whose product is 63 (7 and 9). Once the pair is found, there's no point in testing other numbers, so the first if statement exits both for loops using last with a label. The second if ensures that the bigger of the two numbers will always be the first one by skipping to the next iteration of the outer loop as soon as the condition would no longer hold. This means that the numbers will be tested with ($i, $j) being (1,1), (2,1), (2,2), (3,1), (3,2), (3,3), (4,1), and so on.

      Even if the innermost block is labeled, the last, next, and redo statements without the optional parameter (the label) still operate with respect to that innermost block. Also, you can't use labels to jump into a block - just out of a block. The last, next, or redo has to be within the block.

      Bye
      Timothy

      --
      Zwei Dinge im Leben kannst du nicht zurück holen. Den Pfeil, den du verschossen. Und das Wort, das du gesprochen.
      (alte indianische Weisheit)