“Unterbrechung;” aus “if”-Anweisung?

Lesezeit: 7 Minuten

Können Sie aus einer if-Anweisung ausbrechen oder wird es zu Abstürzen kommen? Ich fange an, mich mit C vertraut zu machen, aber das scheint umstritten zu sein. Das erste Bild stammt aus einem Buch über C (“Head First C”), und der Ausschnitt zeigt Code, der von den Mitarbeitern der Harvard-CS-Klassen geschrieben wurde. Was ist eigentlich los und hat das etwas mit C-Normen zu tun?

breaks unterbrechen nicht if-Anweisungen.

Am 15. Januar 1990 stürzte das Fernsprechsystem von AT&T ab und 60.000 Menschen verloren ihren Telefondienst. Die Ursache? Ein Entwickler, der an dem in den Börsen verwendeten C-Code arbeitete, versuchte, a break aus einem ausbrechen if Aussage. Aber breaks brechen nicht aus ifs. Stattdessen hat das Programm einen ganzen Codeabschnitt übersprungen und einen Fehler eingeführt, der 70 Millionen Telefonanrufe über neun Stunden unterbrochen hat.

for (size = 0; size < HAY_MAX; size++)
{
    // wait for hay until EOF
    printf("\nhaystack[%d] = ", size);
    int straw = GetInt();
    if (straw == INT_MAX)
        break;

    // add hay to stack
    haystack[size] = straw;
}
printf("\n");

  • Du kannst nicht break aus if Erklärung bis zum if befindet sich in einer Schleife.

    – Ankur

    12. Juli 2014 um 15:05 Uhr

  • so funktioniert die Sprache.. ein Umbruch ist im Allgemeinen nur nützlich, wenn er bedingt ist, und um bedingt zu sein, muss er ziemlich genau in einer if-Anweisung stehen, richtig

    – Grady-Spieler

    12. Juli 2014 um 15:19 Uhr

  • Das Verhalten der break Aussage ist gut spezifiziert und im Allgemeinen gut verständlich. Ein unerfahrener Codierer kann durch mangelndes Verständnis in vielerlei Hinsicht Abstürze verursachen. Missbrauch der break Aussage ist nichts Besonderes.

    – CB Bailey

    12. Juli 2014 um 15:22 Uhr

  • Ich habe positiv abgestimmt, weil ich kein Duplikat finden konnte … Auch wenn dies eine offensichtliche Frage ist, denke ich, dass es eine gültige Frage ist.

    – Alberto Bonsanto

    12. Juli 2014 um 15:31 Uhr


  • Das bricht nicht aus ifes bricht aus der while Schleife. C erlaubt nicht break wenn nicht drinnen a while, foroder switch.

    – Jongware

    12. Juli 2014 um 15:32 Uhr

break interagiert nur mit der nächsten umschließenden Schleife oder dem nächsten Schalter, sei es ein for, while oder do .. while Typ. Es wird häufig als getarntes goto bezeichnet, da alle Schleifen in C tatsächlich in eine Menge bedingter gotos umgewandelt werden können:

for (A; B; C) D;
// translates to
A;
goto test;
loop: D;
iter: C;
test: if (B) goto loop;
end:

while (B) D;          // Simply doesn't have A or C
do { D; } while (B);  // Omits initial goto test
continue;             // goto iter;
break;                // goto end;

Der Unterschied ist, continue und break Interagieren Sie mit virtuellen Etiketten, die automatisch vom Compiler platziert werden. Das ist ähnlich was return Wie Sie wissen, springt es im Programmablauf immer weiter. Switches sind etwas komplizierter und erzeugen Arrays von Labels und berechneten Gotos, aber die Art und Weise, wie break mit ihnen arbeitet, ist ähnlich.

Der Programmierfehler, auf den sich der Hinweis bezieht, ist ein Missverständnis break als Interaktion mit einem umschließenden Block und nicht mit einer umschließenden Schleife. In Betracht ziehen:

for (A; B; C) {
   D;
   if (E) {
       F;
       if (G) break;   // Incorrectly assumed to break if(E), breaks for()
       H;
   }
   I;
}
J;

Jemand dachte angesichts eines solchen Stück Codes, dass G würde einen Sprung zu verursachen Iaber es springt zu J. Die beabsichtigte Funktion würde verwenden if (!G) H; stattdessen.

  • Ihre Antwort scheint großartig zu sein. Könnten Sie “für (A; B; C) D; // übersetzt in” auf welche Weise genau erläutern? Ist es Assembler oder Pseudocode, den Sie geschrieben haben? Scheint Pseudocode zu sein. Ich bin mir ziemlich sicher, dass ich es verstehe, und ich stimme ihm zu, dachte, ich frage nur, weil ich sehr interessiert bin.

    – Santropedro

    4. Juli 2019 um 20:18 Uhr

  • Es ist eigentlich kein Pseudocode, abgesehen von den Großbuchstaben für einige willkürliche Ausdrücke oder Anweisungen. so Etiketten und goto sind in C geschrieben. Der Compiler führt diese Ersetzungen im Wesentlichen durch, außer dass er eindeutige Namen für die Labels auswählt, die zu jeder Schleife oder jedem Schalter gehören. default: und case X: sind ähnlich spezielle Etiketten, adressierbar per switch aber nicht goto.

    – Yann Vernier

    4. Juli 2019 um 20:29 Uhr

Dies ist eigentlich die herkömmliche Verwendung des break Aussage. Wenn die break -Anweisung wurde nicht in eine verschachtelt if blockieren die for Schleife konnte immer nur einmal ausgeführt werden.

MSDN listet dies als ihre auf Beispiel für die break Aussage.

Abhinavs Benutzeravatar
Abhinav

Wie bereits erwähnt, break-Anweisung funktioniert nur mit Schalter und Schleifen. Hier ist ein weiterer Weg, um das zu erreichen, was verlangt wird. Ich reproduziere https://stackoverflow.com/a/257421/1188057, da es sonst niemand erwähnt hat. Es ist nur ein Trick mit der do-while-Schleife.

do {
  // do something
  if (error) {
    break;
  }
  // do something else
  if (error) {
    break;
  }
  // etc..
} while (0);

Obwohl ich die Verwendung von bevorzugen würde goto-Anweisung.

  • Wie bei Duffs Gerät ist es ein bisschen fraglich, ob dies elegant oder schrecklich ist. Das do { } while (0) Die Kombination wird auch oft verwendet, um Makros Funktionsaufrufen ähneln zu lassen, so dass das Hinzufügen von a ; nach ihnen wird keine zusätzliche Null-Anweisung erstellt.

    – Yann Vernier

    29. Oktober 2017 um 17:50 Uhr

  • Ich würde empfehlen, dies beim Umgang mit Wurzeln einer Funktion zu verwenden, da Sie nicht wirklich wissen, wie oft Sie eine Funktion durchlaufen müssten, um nahe bei 0 zu sein und auf die Wurzel zu stoßen, und diese Schleife kann eine optimale Schleifenzeit garantieren, um die nächste zu finden 0,000 … Annäherung.

    – Gastón Sailén

    7. August 2019 um 15:19 Uhr

Benutzeravatar von HEKTO
HEKTO

Ich denke, die Frage ist ein bisschen unscharf – sie kann beispielsweise als Frage nach Best Practices beim Programmieren von Schleifen mit interpretiert werden if Innerhalb. Also werde ich versuchen, diese Frage mit dieser speziellen Interpretation zu beantworten.

Wenn Sie haben if innerhalb einer Schleife, dann möchten Sie in den meisten Fällen wissen, wie die Schleife geendet hat – wurde sie durch die “unterbrochen”. if oder wurde es “natürlich” beendet? Ihr Beispielcode kann also folgendermaßen geändert werden:

bool intMaxFound = false;
for (size = 0; size < HAY_MAX; size++)
{
  // wait for hay until EOF
  printf("\nhaystack[%d] = ", size);
  int straw = GetInt();
  if (straw == INT_MAX)
     {intMaxFound = true; break;}

  // add hay to stack
  haystack[size] = straw;
}
if (intMaxFound)
{
  // ... broken
}
else
{
  // ... ended naturally
}

Das Problem mit diesem Code ist, dass die if Die Anweisung ist im Schleifenkörper vergraben, und es erfordert einige Mühe, sie zu finden und zu verstehen, was sie tut. Ein klarer (sogar ohne das break Anweisung) Variante wird sein:

bool intMaxFound = false;
for (size = 0; size < HAY_MAX && !intMaxFound; size++)
{
  // wait for hay until EOF
  printf("\nhaystack[%d] = ", size);
  int straw = GetInt();
  if (straw == INT_MAX)
     {intMaxFound = true; continue;}

  // add hay to stack
  haystack[size] = straw;
}
if (intMaxFound)
{
  // ... broken
}
else
{
  // ... ended naturally
}

In diesem Fall können Sie deutlich sehen (wenn Sie nur auf den “Header” der Schleife schauen), dass diese Schleife kann vorzeitig enden. Wenn der Schleifenkörper ein mehrseitiger Text ist, der von jemand anderem geschrieben wurde, dann würden Sie dem Autor dafür danken, dass er Ihre Zeit gespart hat.

AKTUALISIEREN:

Danke an SO – es hat gerade die bereits beantwortete Frage zum Absturz des AT&T-Telefonnetzes im Jahr 1990 vorgeschlagen. Es geht um eine riskante Entscheidung von C-Erstellern, ein einziges reserviertes Wort zu verwenden break um beide Schleifen zu verlassen und switch.

Jedenfalls folgt diese Interpretation nicht aus dem Beispielcode in der ursprünglichen Frage, daher lasse ich meine Antwort so, wie sie ist.

Sie könnten das if möglicherweise in foreach a for, a while oder einen Schalter wie diesen einfügen

Dann sind Break- und Continue-Anweisungen verfügbar

foreach ([1] as $i) if ($condition) { // Breakable if
    //some code
    $a = "b";
    // Le break 
    break;
    // code below will not be executed
}
for ($i=0; $i < 1 ; $i++) if ($condition) { 
    //some code
    $a = "b";
    // Le break 
    break;
    // code below will not be executed
}

switch(0){ case 0: if($condition){

   //some code
   $a = "b";
   // Le break 
   break;
   // code below will not be executed

}}



while(!$a&&$a=1) if ($condition) {

   //some code
   $a = "b";
   // Le break 
   break;
   // code below will not be executed

}

1404740cookie-check“Unterbrechung;” aus “if”-Anweisung?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy