Totaler Anfänger mit wenig Ahnung^^



  • Konrad Rudolph schrieb:

    NewProggie schrieb:

    Fakt ist aber IMHO, dass es manchmal einfach sauberer ist ein goto zu benutzen, vor allem, wenn es um so simple Sachen wie Zahlen sortieren geht.

    Das ist schlichtweg falsch. Und selbst wenn es richtig wäre, müsste diese Behauptung immernoch bewiesen werden.

    Das goto in dem Beispiel ist grauselig, jawoll, weil es die "goldene goto Regel" verletzt: "springe immer nur nach links und nach unten". Die 2. wichtige Regel, "springe niemals über initialisierungen", erzwingt VC ja soweit ich mich erinnere.

    Wenn man es so einsetzt sehe ich kein grosses Problem, und es kann wunder an Übersichtlichkeit tun, wenn man aus irgendeinem Grund keine Exceptions verwendet, aber trotzdem brav error-handling & cleanup Code schreibt. Ein "finally" statement würde hier helfen, gibts aber leider auch nicht. Böh 😞

    Mit Exceptions hab' ich goto kaum mehr verwendet, aber selbst dann noch ab und zu, wenn ich aus verschachtelten Schleifen "braken" möchte, und ohne goto ne zusätzliche Variable bräuchte. State ist eben ein notwendiges Übel, und ich will nicht noch mehr State haben als ich muss, dann lieber goto 🙂
    Wenn es in C++ ein "break N" statement (bzw. "named loops" und ein "named break" statement) gäbe, könnte ich bei Exception-freiem Code ganz darauf verzichten.

    goto ist IMHO sehr "C++ig", wenn man weiss was man tut soll mans nehmen, sonst sollte man lieber gleich die Finger von C++ lassen.



  • hustbaer schrieb:

    Ein "finally" statement würde hier helfen, gibts aber leider auch nicht. Böh 😞

    Braucht man doch auch nicht. Müll wird am Ende eines Blocks doch sowieso weggeräumt, auch wenn's Fehler gab -- solange der Fehler nur irgendwann gefangen wird:

    struct Foo { ~Foo() { cout << "~Foo" << endl; } };
    
    int main()
    {
        try {
            Foo x;
            throw "abcdefg";
        }
        catch (...) { cout << "catch" << endl; }
        cout << "Left block" << endl;
    }
    

    Ausgabe:

    ~Foo
    catch
    Left block
    

    D.h. 'finally' wird durch die Kapselung von Ressourcen in Klassen ersetzt. RAII ist IMHO einfach mächtiger. Und zwar so mächtig, dass Microsoft in .NET über den "disposable pattern" eine abgespeckte Version von RAII eingeführt hat und dafür sowohl in VB als auch in C# sogar syntaktischen Zucker für eingeführt hat, den 'Using'-Block, der mir in seiner Benutzung doch seehr C++-ig anmutet. 😉



  • egon2 schrieb:

    Ein goto ist z.B gut, um aus einer inneren Schleife bei mehrfach verschachtelten Schleifen voll auszusteigen - also wo break es nicht schaffen kann - auch die äusseren Schleifen zu beenden....

    Auch wenn es ebenfalls "suboptimal" wäre, würde ich bei sowas (wenn es wirklich nicht anders geht) immer noch lieber exceptions werfen...
    Und Makros sind eine echte Pest. 😃
    Wie hieß es so schön: "...nur wenn man den Rücken an der Wand hat ... und ein Messer am Hals.... ein sehr, sehr scharfes Messer !"

    Ist "finally" nicht nur eine Krücke, die man braucht, weil man in Java keine Destruktoren hat ?

    Gruß,

    Simon2.



  • Ist ja schon lustig. Da fragt Antikoerper um Hilfe für ein einfaches Programm und dann wird ein goto-Thread draus. Für das vom OP skizzierte Problem gibt es auch eine Lösung ohne goto:

    #include <iostream>
    #include <iterator>     // istream_iterator
    #include <algorithm>    // max_element
    
    int main()
    {
        using namespace std;
        cout << "Bitte einige Zahlen eingeben. Dies Programm bestimmt die groesste. \nBeenden Sie die Eingabe mit einem 'q' ..." << endl;
        istream_iterator< double > i = max_element( istream_iterator< double >( cin ), istream_iterator< double >() );
        if( i != istream_iterator< double >() )
            cout << "Die groesste Zahl Ihrer Eingabe ist: " << *i << endl;
        return 0;
    }
    

    Gruß Werner :xmas2:



  • @Werner: Das sieht ja ganz nett aus, aber ob das funktioniert? Istream-Iteratoren sind reine Input-Iteratoren und da ist nicht garantiert, daß verschiedene Kopien sich unabhängig voneinander bewegen können (und häufig werden sie auch so implementiert, daß sie sich nur ihren Stream merken und in op* den nächsten Wert vom Stream lesen). max_element benötigt mindestens einen Forward-Iterator.

    Eine Lösung ohne Iteratoren:

    int max_val,val;
    while(cin>>val)
      if(val>max_val) max_val=val;
    cout<<"größter Wert war:"<<max_val<<endl;
    

    Zur goto-Diskussion: Ja, goto sollte man kennen. Aber bevor man es einsetzt, sollte man überprüfen, ob man Alternativen hat (und Exceptions sind imho genauso ungeeignet für "reguläre" Programmabläufe).



  • CStoll schrieb:

    Aber bevor man es einsetzt, sollte man überprüfen, ob man Alternativen hat (und Exceptions sind imho genauso ungeeignet für "reguläre" Programmabläufe).

    Was spricht denn jetzt bitte gegen Ausnahmen? Und wieso "genauso" ungeeignet? 'goto' ist deswegen ungeeignet, weil es nicht strukturgebunden ist und somit die Programmstruktur zerstört, das ist bei Ausnahmen nicht der Fall.
    Und wieso "bevor man sie einsetzt"? Welches Einsatzgebiet (außer eventuell dem Verlassen verschachtelter Schleifen) hat 'goto' denn?



  • CStoll schrieb:

    @Werner: Das sieht ja ganz nett aus, aber ob das funktioniert? Istream-Iteratoren sind reine Input-Iteratoren und da ist nicht garantiert, daß verschiedene Kopien sich unabhängig voneinander bewegen können (und häufig werden sie auch so implementiert, daß sie sich nur ihren Stream merken und in op* den nächsten Wert vom Stream lesen). max_element benötigt mindestens einen Forward-Iterator.

    Ah! Schade; Du hast Recht. In diesem Sinne ist es kein korrektes C++. Es ist wohl dieser Passus aus dem Standard für Input-Iteratoren:

    r: input-iterator
    ++r - post: any copies of the previous value of r are no longer
    required either to be dereferenceable or to be in the domain

    der es unmöglich macht ihn für max_element zu benutzen.

    ... das ist jetzt endgültig kein Anfänger-Thread mehr 😉

    Gruß Werner



  • Konrad Rudolph schrieb:

    Was spricht denn jetzt bitte gegen Ausnahmen? Und wieso "genauso" ungeeignet? 'goto' ist deswegen ungeeignet, weil es nicht strukturgebunden ist und somit die Programmstruktur zerstört, das ist bei Ausnahmen nicht der Fall.

    Ausnahmen sind (in meinen Augen) Fehlersituationen, die nicht sofort verarbeitet werden können. Das normale Ende einer Schleife ist aber kein Fehler, sondern eher eine erwartete (und erwünschte) Situation.

    Und wieso "bevor man sie einsetzt"? Welches Einsatzgebiet (außer eventuell dem Verlassen verschachtelter Schleifen) hat 'goto' denn?

    Wenn ein Programmierer zu sehr an goto hängt - überall (theoretisch könntest du die Programmstruktur in den Wind schießen und von Schleifen bis hin zu Funktionsaufrufen fast alles durch goto ausdrücken - das gibt wunderbaren Spagetti-Code, der mit etwas Glück sogar das macht, was du von ihm erwartest :D). Und selbst bei verschachtelten Schleifen würde ich wohl am ehesten ein bool-Flag setzen, das auf allen Zwischenstufen abgefragt wird (oder den ganzen Block als Funktion schreiben und per return verlassen).



  • CStoll schrieb:

    (theoretisch könntest du die Programmstruktur in den Wind schießen und von Schleifen bis hin zu Funktionsaufrufen fast alles durch goto ausdrücken

    Ja, diese Erkenntnis ist, da (bedingtes) 'goto' Turing-vollständig ist, aber trivial. Mit der gleichen Argumentation kann man statt in C++ auch in Brainfuck schreiben. Worauf ich hinaus will ist, dass es kein Argument für die Verwendung von 'goto' gibt weil das einzige Argument genauso für jede andere Schleifenstruktur gilt: Die Turing-Vollständigkeit. Wenn jemand behauptet, für 'goto' gebe es sinnvolle Verwendungen, dann hat er diese Tatsache nicht verstanden.



  • Danke erstmals für eure Antworten.

    Ich muss ein paar Leuten zustimmen, ich verstehe von Funktionen genau so viel wie ein Krokodil fliegen kann^^ Ich bin euch sehr dankbar, das ich mir den Quelltext geschrieben habt, na ja würd ich mich jetzt bei euch für den Aufwand bedanken, würdet ihr mich auslachen, da ihr sowas im Blindflug macht, na ja, danke für den Quelltext, wie ich sehe ist dieses Forum zu geil, da kann man sicher einiges lernen. Also, danke nochmals.

    MFG Antikoerper.K


Anmelden zum Antworten