Mein Informatiklehrer sagt, dass



  • war schrieb:

    doch klar, dass C++ler auf break und continue stehen, weil C++ zu kompiliziertem Denken verleitet.

    Klar, da C++ ja auch mit Abstand die einzige Sprache ist, die break und continue unterstützt.



  • was der lehrer sagt, entspringt der dogmengruppe "strukturiertes programmieren". und ist für c++ nicht mehr aktuell. durch RAII und durch effiziente funktionsaufrufe hat sich das gravierend geändert.

    return ist gut. continue ist auch gut. break ist nicht so gut. goto ist noch schlechter. künstliche variablen, um break zu sparen, sind noch schlechter.

    aber wenn dein lehrer break nicht mag, dann nimmst du einfach in der schule künstliche variablen, ganz, wie es damals in pascal üblich war.



  • Hi,

    ich muss gestehen, dass bei mir Alarmglocken angehen, wenn ich in fremdem Code break (außer beim "Standard-switch") und continue finde.
    Die schrillen aber nicht "Achtung! Schlechter Code!", sondern "Achtung! Musst Du Dir seeeeehr genau ansehen!".

    Egal, ob es schlecht programmiert ist oder einfach die beste Lösung für eine komplizierte Aufgabe ist (beides schon gesehen): Es ist "immer" komplizierter als Code, der (auf elegante und übersichtliche Weise) ohne auskommt.
    Deshalb denke ich auch jedesmal 10mal darüber nach, bevor ich ein break oder ein continue verwende.

    BTW: Kann es im vorliegenden Fall nicht einfach sein, dass man die gegebene Aufgabe tatsächlich ohne break/continue besser/sauberer hätte lösen können?
    Oder dass der Threadersteller sehr gerne/permanent und ständig mit break/continue arbeitet? (Ich kenne durchaus solche "über-Schleifenbedingungen-mache-ich-mir-später-irgendwo-im-Schleifenkorpus-Gedanken"-Programmierer)
    Natürlich "sind die Pauschalisierungen immer falsch" 😉 ... aber bisweilen sind sie lediglich überspitzte Formulierungen als Gedächtnisstütze oder Motivation zum Umdenken.
    Kann natürlich auch alles ganz anders sein ....

    Gruß,

    Simon2.



  • Ich würde den Lehrer nicht so vorschnell verurteilen.
    Generell gibt es keine bösen Konstrukte, aber es ist vertretbar, wenn Lehrer so etwas vor den Schülern behaupten.
    Und wenn ein Lehrer behauptet, dass break schlechter Stil ist um die Schüler dazu zu bringen break zu vermeiden finde ich das nicht unbedingt verkehrt, auch wenn ich zu der Fraktion gehöre, die break schreibt, bevor sie ein Flag für den Fall einsetzt.
    unüberlegte breaks sind auf jedenfall unschön, wenn es ohne workarrounds wie flags auch ohne break geht ist das im Normalfall auch schöner.

    Außerdem sei froh, dass dein Lehrer den Begriff Stil überhaupt kennt.



  • An alle Gegner von break: wie wollt ihr denn folgendes Problem sinnvoll lösen?

    unsigned int a, b;
    cin>>a;
    cin>>b;
    //a und b sind zwei Zahlen, zwischen denen die erste Primzahl ermittelt werden soll
    for( ; a!=b; ++a)
    {
        if( is_prim(a) ) break;
    }
    

    Sollte man dann lieber a=b setzen, wenn a eine primzahl ist? Dann hat man aber den Wert von a für weitere Berechnungen verändert. Oder die Schleife einfach weiterlaufen lassen und falls is_prim einmal wahr war, nicht wieder auf primzahlen prüfen? Dann wird Rechenzeit vergeudet. Oder eine weitere Variable in die Bedingung des SChleifenkopfes einbauen? Das verkompliziert den ganzen Code doch nur...



  • also wenn man deinen Code nur leicht modifizieren würde, dann so

    for(; a!=b && !is_prim(a); ++a);
    


  • unsigned int a, b;
    cin>>a;
    cin>>b;
    //a und b sind zwei Zahlen, zwischen denen die erste Primzahl ermittelt werden 
    int fp=findFirstPrimeBetween(a,b);
    
    int findFirstPrimeBetween(int min,int max)
    {
       for(int i=min;i!=max;++i)
          if(is_prim(i))
            return i;
       return 0;
    }
    

    das meinte ich oben mit "return ist besser als break".



  • sdhfhj schrieb:

    ...Gegner von break...

    Habe ich in diesem Thread noch keinen gesehen.
    Vielleicht solltest Du die Frage da stellen, wo Du welche findest.

    Persönlich finde ich Deinen Code wirklich ein gutes Beispiel für überflüssiges break: Es gibt eine klare, eindeutige und leicht zu formulierende Abbruchbedingung für die Schleife (sogar in Abhängigkeit von der "Laufvariablen") ... wofür der liebe Gott einen eigenen Platz im for- oder im while-statement geschaffen hat. 😉

    Gruß,

    Simon2.



  • OK, nehmen wir ein gestelltes Schul-Beispiel:

    #include <iostream>
    using namespace std;
    
    int main()
    {
      for(int i=0; i <= 100; ++i)
      {
        if(i%2)
          continue;
        else
          cout << i << ' ';
      }
    
      cout << endl << endl;
    
      for(int i=0; i <= 100; ++i)
      {
        if(i%2)
          cout << i << ' ';
        else
          continue;
      } 
    }
    

    Wie müsste das alles optimal ohne continue aussehen? ... und was ist dann der konkrete Vorteil? 🙂



  • Schlechtes Beispiel. Wenn du continue einfach weglässt, ist das Ergebnis noch das Selbe 😃

    #include <iostream> 
    using namespace std; 
    
    int main() 
    { 
      for(int i=0; i <= 100; ++i) 
      { 
        if(!(i%2)) //einfach den ! operator verwenden
          //continue; 
        //else 
          cout << i << ' '; 
      } 
    
      cout << endl << endl; 
    
      for(int i=0; i <= 100; ++i) 
      { 
        if(i%2) 
          cout << i << ' '; 
        //else 
          //continue; 
      } 
    }
    


  • Erhard Henkes schrieb:

    OK, nehmen wir ein gestelltes Schul-Beispiel:

    #include <iostream>
    using namespace std;
    
    int main()
    {
      for(int i=0; i <= 100; ++i)
      {
        if(i%2)
          continue;
        else
          cout << i << ' ';
      }
    
      cout << endl << endl;
    
      for(int i=0; i <= 100; ++i)
      {
        if(i%2)
          cout << i << ' ';
        else
          continue;
      } 
    }
    

    Wie müsste das alles optimal ohne continue aussehen? ... und was ist dann der konkrete Vorteil? 🙂

    Äh, wenn ich über die geraden Zahlen iterieren will schreib ich

    for(int i=0; i<=100; i+=2)
    {
    }
    

    und bei ungeraden halt

    for(int i=1; i<=100; i+=2)
    

    Dass das geschickter ist brauchen wir wohl nicht wirklich zu diskutieren, oder? Das ist imo ein typischer Fall von dem von Simon2 erwähnten "über die genaue Bedingung mach ich mir später noch Gedanken".



  • Erhard Henkes schrieb:

    OK, nehmen wir ein gestelltes Schul-Beispiel:

    for(int i=0; i <= 100; ++i)
      {
        if(i%2)
          continue;
        else
          cout << i << ' ';
      }
    

    Wie müsste das alles optimal ohne continue aussehen? ... und was ist dann der konkrete Vorteil? 🙂

    Naja, was ist Dir lieber?

    for(int i=0; i <= 100; ++i)
      {
        if(istTeilbar(i,2))
          continue;
        else
          cout << i << ' ';
      }
    

    oder

    for(int i=0; i <= 100; ++i)
      {
        if(not istTeilbar(i,2))
          cout << i << ' ';
      }
    


  • Hi,

    also ich bin skeptisch, dass es ein "gutes Beispiel" für break/continue in Schleifen gibt, das gleichzeitig auch "klein" ist.
    Da, wo ich wirklich die beiden wirklich gewinnbringend (oder "kleinstes Übel" 😉 ) gesehen habe, waren es immer sehr kompliziert verschachtelte Schleifen/Bedingungen, bei denen nur in ganz seltenen Spezialfällen größere Blöcke übersprungen werden sollten.
    Eben Dinge, die sich nicht so einfach in einen if- oder else-Zweig packen lassen...

    Gruß,

    Simon2.



  • seien wir froh, dass überhaupt noch c++ irgendwo unterrichtet wird, die tendenz ist eine andere...



  • Ich stelle hier fest, das mehrheitlich dem Lehrer zugestimmt wird!

    Meine pers. Erfahrung ist die, das ich außer in switch-case fast nie break einsetze, wenn dann nur, weil ich mir nicht viel Gedanken für eine Alternative gemacht habe! continue habe ich glaube ich in meinem Leben nur einmal benutzt... zum Ausprobieren. 😃



  • Also meiner Ansicht nach hat der Lehrer im Prinzip recht. Häufig deuten break oder continue auf schlechten Code hin. Aus pädagogischer Sicht ist ein solcher Hinweis daher angebracht.

    Es gibt dennoch Situationen, in denen diese Konstrukte sinnvoll sind.

    Ein sehr einfaches Beispiel wäre:

    int z;
    while (true)  // ist das unsauber?
    {
      std::cout << "Bitte geben Sie eine Zahl zwischen 1 und 10 ein:";
      std::cin >> z;
      if (z >= 1 && z <= 10)
        break;
    
      std::cout << "Die Zahl " << z << " ist nicht zwischen 1 und 10.\n";
    }
    

    Ohne break hätte man ein Problem. Da müsste man die Bedingung 2 mal prüfen, was unschön ist:

    int z;
    do
    {
      std::cout << "Bitte geben Sie eine Zahl zwischen 1 und 10 ein:";
      std::cin >> z;
      if (z < 1 || z > 10)
        std::cout << "Die Zahl " << z << " ist nicht zwischen 1 und 10.\n";
    
    } while (z < 1 || z > 10); // 2. Prüfung
    

  • Administrator

    @tntnet,

    char const* const message = "Bitte geben Sie eine Zahl zwischen 1 und 10 ein:";
    std::cout << message;
    
    int z = 0;
    
    while(!(std::cin >> z) || z < 1 || z > 10)
    {
      std::cout << "Die Zahl " << z << " ist nicht zwischen 1 und 10.\n";
      std::cout << message;
    
      std::cin.clear();
      std::cin.ignore(std::cin.rdbuf()->in_avail());
    }
    

    Man kann sehr vieles umformen. Ich persönlich brauche continue fast nie, break ein wenig öfter, aber meistens schreibe ich Schleifen ohne break und continue .

    break und continue allerdings einfach zu verfluchen und verbieten, wie es ca. der Lehrer gemacht hat, würde ich nicht. Zum Teil gibt es Schleifen, wenn man dort kein break einführen würde, dann würde die Schleifen-Bedingung viel zu komplex und unübersichtlich werden oder die Schleife weisst dann x-fache if -Verschachtelungen auf. Es gilt halt wie für alle Sprachmittel: "Überlege bevor du sie verwendest".

    Grüssli



  • Ich stelle fest, dass Gegner von break und continue in diesem Thread keine Argumente bringen, sondern nur von ihrem ästetischen Empfinden berichten und/oder behaupten, es gäbe immer eine elegantere Schleifenvariante, die ohne break und continue auskommt. Letzteres ist natürlich schwer zu beweisen -- gerade auch weil Dijkstra und Knuth sich mit dem Thema auseinander gesetzt haben und zu dem Schluss gekommen sind, dass man mit goto s -- damals gabs noch kein break und continue -- in manchen Fällen Code-Duplikationen und "Sonderbedingungen" reduzieren kann. Ich denke, heutzutage bekommt man Dijkstras und Knuths Beispiele auch elegant ohne goto hin, wenn man break , continue und return benutzen darf.

    Gruß,
    SP



  • int z;
    std::cout << "Bitte geben Sie eine Zahl zwischen 1 und 10 ein:";
    std::cin >> z;
    while (z < 1 || z > 10) {
      std::cout << "Die Zahl " << z << " ist nicht zwischen 1 und 10.\nBitte geben Sie eine Zahl zwischen 1 und 10 ein:";
      std::cin >> z;
    }
    

    Ginge auch - da hätte man allerdings Ausgabe/Eingabe doppelt. Andererseits ist hier eine klare "Fehlerfallbehandlung" separat gekapselt, was IMHO auch Vorteile hat.

    Gruß,

    Simon2.



  • Um ehrlich zu sein, das würde ich so schreiben:

    int z;
    for (;;) {
      std::cout << "Bitte geben Sie eine Zahl zwischen 1 und 10 ein:";
      std::cin >> z;
      if (1 <= z && z <= 10) break;
      std::cout << "Die Zahl " << z << " ist nicht zwischen 1 und 10.\n";
    }
    

    Das ist ein typischer Kandidat für die "and-a-half"-Schleifen, bei denen die Abbruchbedingung weder am Anfang noch am Ende steht.

    Gruß,
    SP


Anmelden zum Antworten