Gibt es eine Programmiersprache mit einem besseren Ansatz für Break-Anweisungen von switch?

Lesezeit: 6 Minuten

Benutzer-Avatar
m_vitaly

Es ist die gleiche Syntax in viel zu vielen Sprachen:

switch (someValue) {

  case OPTION_ONE:
  case OPTION_LIKE_ONE:
  case OPTION_ONE_SIMILAR:
    doSomeStuff1();
    break; // EXIT the switch

  case OPTION_TWO_WITH_PRE_ACTION:
    doPreActionStuff2();
    // the default is to CONTINUE to next case

  case OPTION_TWO:
    doSomeStuff2();
    break; // EXIT the switch

  case OPTION_THREE:
    doSomeStuff3();
    break; // EXIT the switch

}

Nun, alles, was Sie wissen break Erklärungen sind erforderlich, weil die switch wird zum nächsten fortgesetzt case Wenn break Aussage fehlt. Wir haben ein Beispiel dafür mit OPTION_LIKE_ONE, OPTION_ONE_SIMILAR und OPTION_TWO_WITH_PRE_ACTION. Das Problem ist, dass wir dieses „Zum nächsten Fall springen“ nur sehr, sehr, sehr selten brauchen. Und sehr oft setzen wir am Ende eine Pause case.

Es ist sehr leicht für einen Anfänger, es zu vergessen. Und einer meiner C-Lehrer hat es uns sogar erklärt, als wäre es ein Fehler in der C-Sprache (ich will nicht darüber reden 🙂

Ich möchte fragen, ob es andere Sprachen gibt, die ich nicht kenne (oder vergessen habe), die switch/case wie folgt handhaben:

switch (someValue) {

  case OPTION_ONE:  continue; // CONTINUE to next case
  case OPTION_LIKE_ONE:  continue; // CONTINUE to next case
  case OPTION_ONE_SIMILAR:
    doSomeStuff1();
    // the default is to EXIT the switch

  case OPTION_TWO_WITH_PRE_ACTION:
    doPreActionStuff2();
    continue; // CONTINUE to next case

  case OPTION_TWO:
    doSomeStuff2();
    // the default is to EXIT the switch

  case OPTION_THREE:
    doSomeStuff3();
    // the default is to EXIT the switch

}

Die zweite Frage: Gibt es eine historische Bedeutung dafür, warum wir den aktuellen Break-Ansatz in C haben? Vielleicht weiter zum nächsten Fall wurde viel öfter verwendet als wir es heutzutage verwenden?

  • Nicht etwas, worüber ich mich freuen kann, da ich es sehr selten benutze. In dem Projekt, an dem ich arbeite, switch wird in 46 Quelldateien zweimal verwendet.

    anon

    10. Juni 2010 um 13:21 Uhr


  • Jede Sprache hat Konstruktionen, die zu Problemen führen können, wenn man nicht darauf achtet, was man schreibt. Daher verwende ich immer PC-Lint, da es diese Art von Problemen sehr leicht findet.

    – Patrick

    10. Juni 2010 um 13:24 Uhr

  • Ja, es ist ein historisches Relikt, das jetzt eine Fehlfunktion ist. Es war eine Do not Repeat Yourself-Syntax, als Funktionsaufrufe sehr teuer waren und die Ausführung jeder zusätzlichen Maschinenanweisung 2 Tage dauerte (okay, PDP-11s waren nicht so langsam, aber wenn Ihr Mobiltelefon so langsam wäre, würden Sie es erschießen) .

    – msw

    10. Juni 2010 um 13:25 Uhr

  • @Neil: Aber nur, weil es offensichtlich in der Sprache, die Sie verwenden, scheiße ist. Andererseits ist in Sprachen wie Haskell oder Scala „switch“ (naja, eigentlich case pattern matching) ein so mächtiges Konstrukt, dass es ständig verwendet wird.

    – Konrad Rudolf

    10. Juni 2010 um 14:07 Uhr

  • @msw: Ohne Beweis behaupte ich, dass dies wahrscheinlich das Ergebnis der direkten Übersetzung der Sprungtabellen-Flusskontrolle ist, die dann in der Assembler-Programmierung in strukturierte Sprachen üblich ist.

    – dmckee — Ex-Moderator-Kätzchen

    10. Juni 2010 um 14:08 Uhr

Benutzer-Avatar
jweyrich

Aus Dies Artikel, kann ich einige Sprachen aufzählen, die keine erfordern break-ähnliche Aussage:

  1. Ada (kein Durchfall)
  2. Eiffel (kein Fallthrough)
  3. Pascal (kein Durchfall)
  4. Gehen – fallthrough
  5. Perl- continue
  6. Ruby (kein Fallthrough)
  7. VB, VBA, VBS, VB.NET (kein Fallthrough)
  8. Fortsetzung von jemand anderem…

Deine zweite Frage ist ziemlich interessant. Angenommen nur C, Ich glaube Diese Entscheidung hält die Sprache kohäsiv. Seit break ist ein springenmuss explizit geschrieben werden.

  • Ich glaube, der historische Grund ist, dass es zusammen mit den meisten anderen Syntaxen von C von BCPL geerbt wurde.

    – Benutzer207421

    12. Juni 2010 um 2:07 Uhr

Ich denke, dass der Scala-Musterabgleich in diesen Fällen eine enorme Verbesserung darstellt. 🙂

object MatchTest2 extends Application {
  def matchTest(x: Any): Any = x match {
    case 1 => "one"
    case "two" => 2
    case y: Int => "scala.Int"
  }
  println(matchTest("two"))
}

Beispiel von scala-lang.org

  • Scala hat jedoch keine Fall-Through-Anweisung

    – m_vitaly

    10. Juni 2010 um 13:36 Uhr

  • Ja, absolut richtig, aber vielleicht liegt es daran, dass es keines erfordert :). Scala ist eine funktionale und OO-Sprache, etwas, das C nicht ist, vielleicht fehlt deshalb ein Fall-Through. Ich bin sowieso kein Scala-Experte.

    – Marcote

    10. Juni 2010 um 13:44 Uhr

  • @Vitaly, Sie können das Fallthrough-Verhalten (irgendwie) in Scala wie folgt erreichen: paste.pocoo.org/show/223917

    – fehlender Faktor

    10. Juni 2010 um 13:48 Uhr

  • @Rahul ja, aber Sie können functionCall() nicht schreiben und dann durchfallen

    – m_vitaly

    10. Juni 2010 um 13:59 Uhr

  • dasselbe für Haskell, PLT-Schema usw.

    – Claudius

    10. Juni 2010 um 20:27 Uhr

Und VB .NET handhabt es etwas mehr so, wie Sie es erwarten.

Select Case i
    Case 1 to 3
        DoStuff(i)
    Case 4,5,6
        DoStuffDifferently(i)
    Case Is >= 7
        DoStuffDifferentlyRedux(i)
    Case Else
        DoStuffNegativeNumberOrZero(i)
End Select

Es gibt überhaupt kein Durchfallen, ohne möglicherweise ein Goto zu verwenden

  • VB6 und seine Vorgänger waren genauso.

    – Chris K

    10. Juni 2010 um 13:56 Uhr

Hier ist die Antwort:
http://en.wikipedia.org/wiki/Switch_statement

Es heißt Fall-Through-Anweisung (continue im Beispiel) und es existiert in den folgenden Sprachen:
Los, Perl, C#

In C# wird es ohne nicht kompiliert break oder goto case Anweisung (außer wenn es keine Voraktion gibt).

PASCAL hat kein Fall-Through

Benutzer-Avatar
Goyuix

Ich denke, die Antwort auf Ihre Frage, warum dies so ist, konzentriert sich auf zwei Verhaltensweisen, die beide mit dem generierten Assemblercode aus der C-Quelle zu tun haben.

Die erste besteht darin, dass beim Assemblieren die aktuelle Anweisung ausgeführt wird, und es sei denn, es gibt eine Sprung- oder eine andere Flusssteuerungsanweisung, wird die Anweisung an der nächsten Adresse ausgeführt. Das Durchführen einer naiven Kompilierung der switch-Anweisung zur Assembly würde Code generieren, der einfach mit der Ausführung der ersten Anweisung beginnen würde, um zu sehen, ob es eine übereinstimmende Bedingung gibt …

Der zweite verwandte Grund ist die Vorstellung von a Verzweigungstabelle oder Sprungliste. Grundsätzlich kann der Compiler das, was er über Ihren Wert weiß, nehmen und für dasselbe einen äußerst effizienten Maschinencode erstellen. Nehmen Sie zum Beispiel eine einfache Funktion wie atoi, die eine Zeichenfolgendarstellung einer Zahl konvertiert und sie in ganzzahliger Form zurückgibt. Wenn Sie die Dinge so vereinfachen, dass nur eine einzelne Ziffer unterstützt wird, könnten Sie einen ähnlichen Code wie diesen schreiben:

int atoi(char c) {
  switch (c) {
    case '0': return 0;
    case '1': return 1;
    // ....
  }
}

Der naive Compiler würde das vielleicht einfach in eine Reihe von Wenn/Dann-Blöcken umwandeln, was bedeutet, dass eine beträchtliche Menge an CPU-Zyklen für die Zahl 9 benötigt würde, während 0 fast sofort zurückkehrt. Unter Verwendung einer Verzweigungstabelle könnte der Compiler einige ausgeben [psuedo] Assembly, die sofort zur richtigen Rückgabeklausel “springen” würde:

0x1000 # stick value of c in a register
0x1004 # jump to address c + calculated offset
# example '0' would be 0x30, the offset in for this sample
# would always be 0x0FD8... thus 0x30 + 0x0FD8 = 0x1008
0x1008 # return 0 

Entschuldigung: Meine Assembler- und C-Kenntnisse sind ziemlich eingerostet. Ich hoffe, das trägt zur Klärung der Dinge bei. 0x

Benutzer-Avatar
ASalazar

Hey, vergiss COBOLs EVALUATE nicht:

EVALUATE MENU-INPUT
    WHEN "0" PERFORM INIT-PROC
    WHEN "1" THRU "9" PERFORM PROCESS-PROC
    WHEN "R" PERFORM READ-PARMS
    WHEN "X" PERFORM CLEANUP-PROC 
    WHEN OTHER PERFORM ERROR-PROC
END-EVALUATE.

  • Nun, COBOL leistet auf jeden Fall LEISTUNG.

    – Yishai

    10. Juni 2010 um 16:16 Uhr

1216710cookie-checkGibt es eine Programmiersprache mit einem besseren Ansatz für Break-Anweisungen von switch?

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

Privacy policy