neuer Lehrer, neues Schuljahr, neues "C++"



  • Deshalb sollte man auch lieber immer char s einlesen. Man kann ihn dank stringstreams ja immernoch in Zahlen konvertieren.
    Ob's den Aufwand wert ist, weiß ich nicht.

    Poser-Code ist so eine Sache. Die Grenzen von Posercode sind ja nicht mal richtig definiert, ist also sowieso Geschmacksache. Aber wenn man schon Posercode wie das wunderbare STL-Stück da oben benutzt (was ich übrigens auch "bewundere" 🙂 ), dann sollte man zumindest kommentieren, was er macht, bzw. in eine Inline-Funktion stopfen und ihr einen treffenden Namen geben, z.B. add_userinput() oder was weiß ich. Damit würde ich klarkommen:

    // liest Zahlen ein, summiert sie und gibt sie aus
    cout << accumulate(istream_iterator<int>(cin), istream_iterator<int>(), 0) << endl;
    

    Aber in C++ sind ja so manche Sachen kryptisch...



  • @ad acta: accumulate ist doch deutlich genug!?
    ich glaube nicht, dass man solche zeilen noch extra kommentieren sollte...
    1 blick sagt da doch alles aus:
    accumulate -> addieren
    istream_iterator -> einlesen

    ich finde solchen code übrigens viel leserlicher als das ganze "per hand" zu machen...

    bb



  • Angry Larry schrieb:

    C++Poser schrieb:

    SeppJ schrieb:

    C++Poser schrieb:

    So nicht. Keinem User kannst du ein Programm verkaufen, bei dem er die Eingabe mit Strg+Z beenden muss.

    Ähh, sämtliche Unix Kommandozeilentools?

    Na, die paar Randgruppen User machen weniger als ein Prozent aus.

    Ignoranz ist schön und gut und kann einen vorwärts bringen, aber bitte nicht so übertrieben heraus posaunen.

    C++Poser schrieb:

    Bei richtigen Programmen sollte man versuchen seinen Code möglichst klar und einfach zu formulieren und nicht so ein Poser C++ wie "std::accumulate(std::istream_iterator<int> (std::cin), std::istream_iterator<int>(), 0)" verwenden.

    Ähm, ich finde gerade solche Einzeiler besonders schön! Auch wenn das mit dem istream_iterator sicherlich Geschmacksache ist. Dann lager ich die Eingabe der Daten in eine eigene Methode/Klasse aus, die dem User bessere Möglichkeiten zur Kontrolle/Übersicht an die Hand gibt, und speicher die Daten in einem vector. Diesen Vector kann ich dann wieder an accumulate übergeben und mit nur einer Zeile die Daten entsprechend dem übergebenen BinaryOperator verwurschteln.

    Ich bin echt erstaunt, wie manche Leute sich immer aufregen, dass C++ zu wenig Funktionen bietet und man immer auf externe Libs angewiesen ist, und dann trotzdem Leute kommen und genau diese schönen Möglichkeiten noch verteufeln. Geh und spiel Java...

    Tja, muss dich enttäuschen. Ich programmier beruflich C++ und dass was bei uns am meisten von der StdLib verwendet wird sind die container der Rest ist vernachlässigbar. Vielleicht noch for_each, aber da auch mehr die boost Variante bzw. zusammen mit boost bind. Den größten Teil machen 3rd Party Libs wie z.B. QT für GUI aus. Da gibts mit QString auch nen String mit dem man seine SW einfacher auf den asiatischen Markt bring, als mit std::string. Aber vielleicht verdienst du ja dein Geld mit Kommandozeilentools mit besonders schönen Einzeilern und BinaryOperator verwurschteln.


  • Administrator

    @Aho,
    Ich empfehle dir beiden Parteien zu folgen 🙂
    Dies heisst: Verwende beide Möglichkeiten, wo es jeweils Sinn macht. Man kann in beide Richtungen übertreiben, kompletter Verzicht auf die STL oder völlig krankhafter Einsatz der STL. Wann was Sinn macht, dass ist schwer zu definieren und meistens eine recht subjektive Angelegenheit.
    Die wichtigsten Punkte zu beachten sind:
    - Du musst es lesen und verstehen können.
    - Dein Nachfolger muss es lesen und verstehen können.

    Bei deinem gezeigten Beispiel sehe ich zwei Probleme:
    1. Wie Erhard Henkes es angesprochen hat, wird die Eingabe nicht sauber überprüft. In diesem Code eine gute Fehlerprüfung für die Eingabe einzubauen, dürfte eher schwer sein.
    2. Es ist viel zu kompakt und alles in einer Zeile. Wenn man es nur schon ein wenig auseinandernehmen würde, würde dies die Lesbarkeit deutlich erhöhen:

    #include <iostream>  // cin, cout, endl
    #include <iterator>  // istream_iterator
    #include <numeric>   // accumulate
    
    int main()
    {
        int const init = 0; // Fakultativ, aber vielleicht verständlicher, als eine einfache 0 als Argument.
                            // Man erkennt, wofür der Parameter verwendet wird.
        std::istream_iterator<int> inputIterEnd;
        std::istream_iterator<int> inputIterBegin(std::cin);
    
        int total = std::accumulate(inputIterBegin, inputIterEnd, init);
        std::cout << total << std::endl;
    
        return 0;
    }
    

    @C++Poser,
    Und weil eure Firma es so macht, muss es gleich für den ganzen Markt gelten, oder wie soll man dich verstehen? 🙂

    Grüssli



  • Wenn mir einer sowas abliefert,

    int summe=0;
    
    int zahl;
    while(cin>>zahl)
       summe+=zahl;
    
    cout<<summe;
    

    wäre ich nicht wirklich sauer.



  • volkard schrieb:

    Wenn mir einer sowas abliefert,

    int summe=0;
    
    int zahl;
    while(cin>>zahl)
       summe+=zahl;
    
    cout<<summe;
    

    wäre ich nicht wirklich sauer.

    leider hat es keinerlei vorteile ggnüber der einzeiler-lösung...



  • Doch, man muss sich nicht erst ewig sich einen Einzeiler anschauen und Klammern beachten, was wo wie verschachtelt ist. Wenn der ganze Code so aussehen würde, wäre das (zumindest bei mir, aber bestimmt auch bei anderen) ein ewiges hin und her zwischen "Entziffern des Sourcecodes", "Referenz nachschlagen" und den "Kontext dieses Algos im Programm Verstehen". Die Algorithmen der STL würde ich schon nutzen, aber nicht so dicht gepackt aufeinander.



  • Dravere schrieb:

    @C++Poser,
    Und weil eure Firma es so macht, muss es gleich für den ganzen Markt gelten, oder wie soll man dich verstehen? 🙂

    Nö, aber ich denke die Anzahl der Firmen bei denen es ähnlich aussieht dürfte um einiges größer sein, als die die viel std::accumulate usw. verwenden.
    lang:c++ std::accumulate bei Google Code search bringt gerade mal 2000 Treffer.



  • C++Poser schrieb:

    Dravere schrieb:

    @C++Poser,
    Und weil eure Firma es so macht, muss es gleich für den ganzen Markt gelten, oder wie soll man dich verstehen? 🙂

    Nö, aber ich denke die Anzahl der Firmen bei denen es ähnlich aussieht dürfte um einiges größer sein, als die die viel std::accumulate usw. verwenden.
    lang:c++ std::accumulate bei Google Code search bringt gerade mal 2000 Treffer.

    <a href= schrieb:

    c++ std::accumulate">
    8.090.000 für c++ std::accumulate

    PS: 4.060.000 für c++ std::vector

    was sagt das über den gebrauch aus?


  • Administrator

    volkard schrieb:

    Wenn mir einer sowas abliefert,

    int summe=0;
    
    int zahl;
    while(cin>>zahl)
       summe+=zahl;
    
    cout<<summe;
    

    wäre ich nicht wirklich sauer.

    Hmmm, doch. Bitte geschweifte Klammern bei der While-Schleife! 😃

    C++Poser schrieb:

    Nö, aber ich denke die Anzahl der Firmen bei denen es ähnlich aussieht dürfte um einiges größer sein, als die die viel std::accumulate usw. verwenden.

    Und mit welchen Argumenten kannst du diese Aussage untermauern? Ich kann auch einfach behaupten, dass genau der umgekehrte Fall zutrifft, dass bringt uns aber nicht weiter 😉

    C++Poser schrieb:

    lang:c++ std::accumulate bei Google Code search bringt gerade mal 2000 Treffer.

    Ich hoffe mal nicht, dass du dies als ein Argument für deine Aussage siehst 🙂

    Grüssli



  • volkard schrieb:

    Wenn mir einer sowas abliefert,

    int summe=0;
    
    int zahl;
    while(cin>>zahl)
       summe+=zahl;
    
    cout<<summe;
    

    wäre ich nicht wirklich sauer.

    Mein eigentlicher Hintergedanke war der, dass es nicht unnötig Rechenleistung verschwenden soll.
    Bei einem größeren Programm ist das glaub ich vorteilhaft, wenn man Umwege und der gleichen vermeidet. So stell ich mir das vor... kann natürlich auch komplett falsch sein.

    Grüße,
    Martin



  • unskilled schrieb:

    <a href= schrieb:

    c++ std::accumulate">
    8.090.000 für c++ std::accumulate

    PS: 4.060.000 für c++ std::vector

    was sagt das über den gebrauch aus?

    😃
    Such mal richtig
    http://www.google.de/search?hl=de&q=c%2B%2B+"std%3A%3Avector"&btnG=Suche&meta=
    http://www.google.de/search?hl=de&q=c%2B%2B+"std%3A%3Aaccumulate"&btnG=Suche&meta=



  • Aho schrieb:

    volkard schrieb:

    Wenn mir einer sowas abliefert,

    int summe=0;
    
    int zahl;
    while(cin>>zahl)
       summe+=zahl;
    
    cout<<summe;
    

    wäre ich nicht wirklich sauer.

    Mein eigentlicher Hintergedanke war der, dass es nicht unnötig Rechenleistung verschwenden soll.
    Bei einem größeren Programm ist das glaub ich vorteilhaft, wenn man Umwege und der gleichen vermeidet. So stell ich mir das vor... kann natürlich auch komplett falsch sein.

    Grüße,
    Martin

    ich kann mir gerade nicht wirklich vorstellen, dass der einzeiler langsamer ist - außerdem fällt das wohl eh unter vorzeitige optimierung...



  • unskilled schrieb:

    ich kann mir gerade nicht wirklich vorstellen, dass der einzeiler langsamer ist

    Bei sowas gehe ich davon aus, daß es exakt gleich schnell is.



  • volkard schrieb:

    unskilled schrieb:

    ich kann mir gerade nicht wirklich vorstellen, dass der einzeiler langsamer ist

    Bei sowas gehe ich davon aus, daß es exakt gleich schnell is.

    wollte ich damit sagen ;P



  • Dravere schrieb:

    volkard schrieb:

    Wenn mir einer sowas abliefert,

    int summe=0;
    
    int zahl;
    while(cin>>zahl)
       summe+=zahl;
    
    cout<<summe;
    

    wäre ich nicht wirklich sauer.

    Hmmm, doch. Bitte geschweifte Klammern bei der While-Schleife! 😃

    Da geht es doch schon los. C++ verlangt keine geschweiften Klammern. Und ich verzichte häufig in solchen Situation auf diese. Die Schleife ist so wie sie ist effizient und gut lesbar. Es spricht also nichts dagegen, es so zu schreiben.

    Die std::accumulate-Funktion ist in erster Linie für Templateprogrammierung sinnvoll. In so einer Situation, wie hier gezeigt, finde ich es eher einfach akademisch interessant.

    Im übrigen kann man (und sollte) nach accumulate den Zustand von std::cin abfragen. Dann kann man erfahren, ob man bei eof angekommen ist oder die letzte Konvertierung auf ein nicht nummerischen Wert gestossen ist. Einfach std::cin.eof() abfragen. Ist das false, ist man nicht am Ende und die letzte Konvertierung ist offensichtlich schief gelaufen:

    #include <iostream>  //std::cin / std::cout / std::endl
    #include <iterator>  //std::istream_iterator
    #include <numeric>   //std::accumulate
    
    int main()
    {
        std::cout << std::accumulate(std::istream_iterator<int> (std::cin), std::istream_iterator<int>(), 0) << std::endl;
        if (!std::cin.eof())
             std::cerr << "ups - schief gelaufen" << std::endl;
    }
    

    Und gleich nochmal was ohne gescheifte Klammern 😉 .



  • Mal abgesehen von den diversen bereits genannten Probleme bzgl. Eingabefehlern etc. finde ich den Einzeiler nicht so unheimlich schlimm. Allerdings geben ich den Kritikern recht, die die Lesbarkeit nicht so umwerfend finden. Ein oder zwei wohlplazierte Zeilenumbrüche können da Wunder wirken:

    #include <iostream>  //std::cin / std::cout / std::endl
    #include <iterator>  //std::istream_iterator
    #include <numeric>   //std::accumulate
    
    int main()
    {
        std::cout << std::accumulate(std::istream_iterator<int>(std::cin),
                                     std::istream_iterator<int>(), 
                                     0) 
                  << std::endl;
    }
    

    Machts in meinen Augen genügendlesbar - ws natürlich auch wieder Geschmackssache ist...



  • pumuckl schrieb:

    Machts in meinen Augen genügendlesbar - ws natürlich auch wieder Geschmackssache ist...

    Wo ist denn da der Unterschied?

    Wenn man diese Zeilenübrüche macht, dann nur um ausreichend zu kommentieren.

    #include <iostream>  //std::cin / std::cout / std::endl
    #include <iterator>  //std::istream_iterator
    #include <numeric>   //std::accumulate
    
    int main()
    {
        std::cout << std::accumulate(std::istream_iterator<int>(std::cin),  // wichtiger Kommentar
                                     std::istream_iterator<int>(),          // wichtiger Kommentar
                                     0)                                     // wichtiger Kommentar
                  << std::endl;
    }
    

    Besonders der zweite Parameter (Off-the-end iterator) bedarf meiner Ansicht nach eines Kommentars, da er nicht unbedingt selbstsprechend ist, wenn man es so noch nicht gesehen hat.



  • Mitleid schrieb:

    Besonders der zweite Parameter (Off-the-end iterator) bedarf meiner Ansicht nach eines Kommentars, da er nicht unbedingt selbstsprechend ist, wenn man es so noch nicht gesehen hat.

    Ne, doku lesen.

    Man kommentiert keine standard funktionen, das ist ja wahnsinn...



  • Shade Of Mine schrieb:

    Man kommentiert keine standard funktionen, das ist ja wahnsinn...

    Welchem Pamphlet ist das nun wieder entsprungen?

    Wenn es nicht intuitiv ist schreibt man den Kommentar dazu, auch wenn es irgendwo in der Doku stehen würde.


Anmelden zum Antworten