Bernhard: Schleifen abbrechen

Beitrag lesen

Hi!

Hat etwas länger gedauert, sorry. Ich hab auch nicht lang Zeit; zur return-Diskussion vielleicht morgen mehr.

Ja gut, du kannst statt des continue mit if-else-Gebilden die Abarbeitung von Code verhindern. Das ergibt dann ungefähr so einen Code

*
    *
      *
        *

statt einem solchen mit Abbrüchen

*
  *
  *
  *

Ja, aber: die Fälle, wo wirklich 4 Verschachtelungsebenen nötig sind, sind meiner Einschätzung nach extrem rar. Das abstrakt zu diskutieren geht mir aber wieder zu weit. Beispiele wäre mir wieder lieber; falls deines von unten ein solches ein soll, dann siehe ebendort.

Gegeben sei eine Datenstruktur. Zum Beispiel ein Array. Der Arrayzeiger steht auf einem der Elemente.

$found = false;

while ($found) {
  if (current($array) == ...) {
    $found = true;
    continue;
  }
  next($array);
}
unset($found);


>   
> Ergebnis ist, dass der Arrayzeiger nun auf dem gesuchten Element steht. Ohne continue stünde er auf dem nächsten Element. Das continue verhindert das unerwünschte Weiterstellen des Arrayzeigers.  
  
Erstens hast du im Kopf das ! vergessen. Außerdem ist  
~~~php
$found = false;  
while ($found) {  
  if (current($array) == ...) {  
    $found = true;  
  } else {  
    next($array);  
  }  
}
~~~ in meinen Augen weder unübersichtlich noch schlecht nachzuvollziehen. Ohne break; ohne continue.  
  
Vergleich mit deiner Variante:  
~~~php
  
$found = false;  
while ($found) {                 while (true) {  
  if (current($array) == ...) {    if (current($array) == ...) {  
    $found = true;                   break;  
  } else {                         }  
    next($array);                  next($array);  
  }                              }  
}

Eingespart hast du eine aus einer schließenden Klammer bestehende Zeile (neben der booleschen Variable).

Nicht nur, dass nun eine Variable namens $found rumliegt, die man mit einem weiteren Schritt aufräumen müsste/kann

Bitte, das ist eine lokale Variable innerhalb einer Funktion, die geht ex nach Ende des Funktionsaufrufs. Speicherlecks sind da nicht zu befürchten.

Und dein

while (true) {

$current = current($array);

if ($current == dies)
    break;

if ($current == das)
    break;

if ($current == jenes)
    break;

next($array);
}

würde ich als  
~~~php
  
$found = false;  
while(!$found) {  
  if ($current == dies || $current == das || ...) {  
   found = true;  
  } else {  
    next($array);  
  }  
}

schreiben.

Bei keinem deiner beiden Beispiele kann ich in meinen Varianten gröbere Nachteile entdecken. Wie gesagt, ich setz mich aber auch gern mit deiner Ansicht nach möglichst fiesen Beispielen auseinander, falls du noch welche liefern möchtest.

Ja, aber das was du da im Kopf siehst, ist nur das Auswerten einer Hilfsvariable und nicht die eigentliche Abbruchbedingung. Diese steckt weiterhin im Schleifenkörper. Wenn sie wirklich im Kopf steckte, braucht es dafür weder return/break noch Hilfsvariablen/continue.

Nun ja, ich möchte mich hier nicht an der Terminologie aufhängen. Fakt ist: betrachtet man einen derartigen Schleifenkopf ohne die Variable found, dann sagt der Kopf eindeutig, dass die _gesamte_ Liste (oder das gesamte Array) durchlaufen wird. Das trifft aber nicht zu.

Dem liegt die Annahme zu Grunde, dass eine _vernünftige_ Schleife (1:1-Übertragungen mathematischer Algorithmen vielleicht ausgeschlossen) sowieso nie so lang sein wird, dass man sie nicht als ganzes erfassen kann.

Naja, du kannst eine komplexe Aufgabenstellung nicht weniger komplex machen, indem du sie aufteilst. Wenn du Glück hast, wird sie durch das Aufteilen übersichtlicher, dafür erhöht sich aber die Komplexität.

Wenn für dich ein Funktionsaufruf mit (Hausnummer) 2 Parametern und möglicherweise einem Rückgabewert "Komplexität" darstellt, dann schon. Für mich sind Funktionsaufrufe keine Komplexität sondern einfach normal und gut.

Es ist im Grunde wie mit Hundekot. Wenn da ein großer Haufen liegt, ist das zwar ärgerlich, aber wenn du ihn in Kotabschnitte auf- und über den Fußweg verteilst, kann man diese zwar einzeln betrachten, benötigt aber auch gezielte Sprünge und Schritte um alle Teile (zwecks Beseitung) erfassen zu können. Ganz abgesehen von den unschönen Nebenwirkungen beim unbeabsichtigten Fortführen des Kots ...

Eine, wie soll ich sagen, sehr bildliche Metapher... ;-)

Du gehst vielleicht eher von einer unübersichtlich langen Schleife aus, von der du _nur einen Teil_ betrachten willst. Für mich wäre da schon wieder Kern des Problems, dass die Schleife zu lang ist. Wie auch bei unserer Diskussion über die sinnvolle Länge von Funktionen.

Um Code zu erfassen, muss ich das sicherlich Stück für Stück machen. Ich bin mir nur nicht sicher, ob es generell besser sein soll, diese Teile zu separieren oder sie an einem Ort zu lassen. Ich denke, für diesen Punkt der Diskussion gibt es keine allgemeingültige Lösung.

Ja, wir streiten natürlich im Grunde hier über Geschmack.

Nunja, mit Fehlern sollte man immer rechnen. Davor ist die Abbruchvariablen-Variante auch nicht gefeit. Rein rechnerisch steigt dabei die Fehlerwahrscheinlichkeit durch die zusätzliche Variable sogar noch.
Du hast aber nicht mit der Fehlerwahrscheinlichkeit argumentiert. Die halte ich durch die Einführung einer einzigen, sinnvoll benannten und verwendeten booleschen Variable nur für unwesentlich erhöht.

Diese eine Variable kommt an mindestens zwei Stellen vor. [...] Jede Stelle ist einen weitere potentielle Fehlerstelle.

Ich muss dir natürlich grundsätzlich zustimmen, jedoch halte ich die Fehlerwahrscheinlichkeit für in der Praxis (wieder habe ich angemessen kurze Schleifen vor Auge) zu vernachlässigen.

Grüße
Bernhard