Werbung einblenden Werbung ausblenden


Home / Tutorials / Perl Handbuch / Schleifen

die foreach Schleife
den Schleifendurchgang wiederholen, wenn eine Bedingung erfüllt ist - redo
die Schleife abbrechen werden, wenn eine bestimmte Bedingung erfüllt ist - last
innerhalb einer Schleife einen Durchlauf überspringen - next
verschachtelte Schleifen mit  next, redo und last
die for Schleife

die while Schleife

die foreach Schleife

Es gibt wohl in allen Programmiersprachen die gleichen Schleifen, abgesehen von Exoten wie apl. Perl ist hier nur insofern exotisch, da es eine foreach Schleife gibt, die in anderen Sprachen, mal abgesehen von PHP, nicht existiert. Auf die foreach Schleife wurde im Zusammenhang mit Arrays/Hashes schon eingegangen, siehe die Kapitel Funktionen zur Bearbeitung von Arrays und Funktionen zur Bearbeitung von Hashes.

Die foreach Schleife taucht nur im Zusammenhang mit Arrays/Hashes auf. Die einfachste Variante davon sieht so aus:

@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");

foreach (@aprikose)
{
   print "$_ \n";
}

Ist kein Wert angegeben, dann übergibt die foreach Schleife die Werte an die Sondervariable $_.
Das ist praktisch, weil auch match im Default Operator, siehe Regular Expressions , auf diese Variable angewendet wird.

Wer den Rückgabewert der foreach Schleife umlenken will, schreibt vor die Klammer eine Variable:

@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");

foreach $eigenschaften(@aprikose)
{
   print "$eigenschaften\n";
}

Wer sich nur bestimmte Werte des Arrays anschauen will, definiert eine Laufvariable:

@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");

foreach $z(1..$#aprikose)
{
   print "$aprikose[$z]\n";
}
den Schleifendurchgang wiederholen, wenn eine Bedingung erfüllt ist - redo

Die Art wie Schleifen abgearbeitet werden, kann durch last, next und redo feiner gesteuert werden.
Zuerst kommt ein Beispiel für redo. HALT ! DAS BEISPIEL NICHT AUSLÖSEN ! ENDLOSSCHLEIFE !

@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");

foreach $z(1..$#aprikose)
{
   print "$aprikose[$z]\n";
  if ($aprikose[$z] eq steinig)
     {
        redo;
     }
}

Das Beispiel oben produziert eine Endlosschleife, da der Schleifendurchgang immer wieder wiederholt wird, wenn er auf den Wert "steinig" trifft.

Sinnvoll eingesetzt wird redo in folgendem Beispiel:

@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");
$summe=1;
foreach $z(0..$#aprikose)
{
$summe +=1;
    if ($summe == 1)
     {
        redo;
     }
}
print $summe;

Was kommt raus? 4 oder 5? 5 kommt raus, weil bei 1 die Schleife wiederholt wird.

die Schleife abbrechen werden, wenn eine bestimmte Bedingung erfüllt ist - last

Mit dem Befehl last kann die Schleife abgebrochen werden, wenn eine bestimmte Bedingung erfüllt ist:

@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");
$summe=1;
foreach $z(0..$#aprikose)
{
$summe +=1;
    if ($summe == 3)
     {
        last;
     }
}
print $summe;

Was kommt da raus? Natürlich: 3.
Erreicht $summe den Wert 3, bleibt es bei diesem Wert, weil die foreach Schleife mit last abgebrochen wird.

innerhalb einer Schleife einen Durchlauf überspringen - next

Mit next kann innerhalb einer Schleife ein Durchlauf übersprungen werden:

@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");
$summe=1;
foreach $z(0..$#aprikose)
{
    if ($summe == 3)
     {
        next;
     }
$summe +=1;
print "hallo $summe \n";
}
print $summe;

Dies ist leider kein gutes Beispiel. Hat $summe den Wert 3, ist die if Bedingung immer true, dass heißt der Schleifendurchlauf macht nur noch next.
Ein besseres Beispiel ist:

@aprikose=("gelb","steinig","süß","ähnlich wie Pflaume");

foreach $z(0..$#aprikose)
{
    if ($aprikose[$z] eq  "steinig")
     {
        next;
     }
print "$aprikose[$z]  \n";
}

Das heißt, steinig wird jetzt nicht mehr gedruckt, weil die Schleife vorher abgebrochen wird.

verschachtelte Schleifen mit  next, redo und last

Wenn Schleifen in einander verschachtelt sind, stellt sich die Frage, aus welcher Schleife mit next, redo und last eigentlich gesteuert wird.
Es ist erst mal die Schleife, in der sich die Funktion befindet:


@aprikose=("gelb","steinig","suess","aehnlich wie Pflaume");
@pflaume=("blau","gross","suess sauer","aehnlich wie aprikose");


	foreach $t(0..$#pflaume)
		{
   			 print "$pflaume[$t] \n";

				foreach $z(0..$#aprikose)
					{
  						  if ($aprikose[$z] eq  "steinig")
   						  {
     						     last;
    						  }
							print "$aprikose[$z]  \n";
					}
					print "------------------------------------------------------------\n";	
		}

Als Ergebnis liefert das Skript:

C:\test>perl test.pl
blau
gelb
------------------------------------------------------------
gross
gelb
------------------------------------------------------------
suess sauer
gelb
------------------------------------------------------------
aehnlich wie aprikose
gelb
------------------------------------------------------------

C:\test>

Die äußere foreach Schleife wird durchlaufen, die innere wird immer an der selben Stelle abgebrochen.
Soll die äußere foreach Schleife abgebrochen werden, muss sie benannt werden (AUSSEN):

@aprikose=("gelb","steinig","suess","aehnlich wie Pflaume");
@pflaume=("blau","gross","suess sauer","aehnlich wie aprikose");


	AUSSEN:foreach $t(0..$#pflaume)
		{
   			 print "$pflaume[$t] \n";

				foreach $z(0..$#aprikose)
					{
  						  if ($aprikose[$z] eq  "steinig")
   						  {
     						     last AUSSEN;
    						  }
							print "$aprikose[$z]  \n";
					}
					print "------------------------------------------------------------\n";	
		}

Das Ergebnis dieses Skripts sieht dann so aus:

C:\test>perl test.pl blau gelb C:\test>

Wie deutlich zu erkennen ist, beendet last jetzt auch die äußere Schleife. Das in Bezug auf last, next und redo Gesagte gilt auch für die for Schleife.
die for Schleife

Die for Schleife hat folgende Syntax:

for (Initialisierung der Laufvariablen;Bedingung;Inkrementierungsfaktor der Laufvariablen) { Befehle; }

Das sieht konkret so aus:

for ($i=0;$i<5;$i++)
{
   print "Hallo, das ist die $i. Runde \n";
}
die while Schleife

Meistens lässt sich das, was mit einer while Schleifer realisierbar ist, auch mit einer for oder foreach Schleife realisieren.
Allerdings verändert sowohl die foreach Schleife, als auch die for Schleife die Inkrementierungsvariable nach einem festen, vom Programmierer steuerbaren Muster. Das setzt voraus, dass es ein solches Muster gibt. Es sind aber auch Fälle denkbar, bei denen ein solches Muster nicht existiert. Nämlich, wenn die Schleife dann starten soll, wenn ein anderer Prozess irgendwas gemacht hat, man aber nicht weiß, wie lange dieser andere Prozess dauert. Das heißt, es gibt kein festes Muster.
Ein einfaches Beispiel ist:

$bedingung=1;
while ($bedingung)
{
   print "Ich laufe, bis jemand die Bedingung umstellt";
  $bedingung=0;
}

Diese while Schleife macht einen Durchgang, weil innerhalb der while Schleife die Variable $bedingung auf 0 gesetzt wird. 0 entspricht aber, ähnlich wie undef, dem Wert false.
$bedingung könnte aber auch den Wert aus einer Datei holen, den irgend ein anderer Prozess beschreibt. Bei der konkreten Anwendung der while Schleife, sollte man wissen, dass jeder Wert, der von 0 oder undef verschieden ist, als true gilt:

while(undef)
{
   print "da passiert nichts";
}
while(0)
{
   print "Da passiert auch nichts";
}

$bedingung="Himbeertorte";
while($bedingung)
{
  print "Einmal wird durchmarschiert";
   $bedingung=0;
}
vorhergehendes Kapitel