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



  • Aho schrieb:

    Also nun zu meiner Frage:

    #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; 
    }
    

    Und wie wird eigentlich "richtig", also im Programmierer-Alltag gearbeitet?

    So nicht. Keinem User kannst du ein Programm verkaufen, bei dem er die Eingabe mit Strg+Z beenden muss. Aber dass man namespaces wie std:: verwendet ist normal. 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. Ansonsten http://www.c-plusplus.net/forum/viewtopic-var-t-is-245729-and-start-is-0-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-.html


  • Mod

    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?



  • SeppJ schrieb:

    Ähh, sämtliche Unix Kommandozeilentools?

    Abgesehen davon, dass in diesem Fall jede "Nicht-Int-Eingabe" auch zum Ende führt.



  • 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.



  • 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...



  • Angry Larry schrieb:

    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...

    Davon, daß man in Template-Meta-Code Primzahlen berechnen kann, wird kein einziger Buchstabe auf dem Bildschirm rot. C++ hat keine threads, kein Netzwerk, keine Farben, ungefähr nichts. Und ich finde diese Einzeiler sind übertrieben und wirklich häßlich.



  • Aho schrieb:

    Das diese Zeilen Zahlen zusammenzählen können, kann ich einfach nicht erkennen.

    Och, daran gewöhnt man sich recht schnell.

    Wie soll man den nun programmieren, um darauf aufbauen zu können?

    So nicht.

    Und wie wird eigentlich "richtig", also im Programmierer-Alltag gearbeitet?

    Auch so. Keiner wird Dich zwingen, Poser-Code zu schreiben, aber lesen wirst Du ihn immer wieder. Und die Poser machen das nicht böswillig. Die glauben echt daran, daß das vernünftig sei. Und sie sagen, daß jeder, der anderere Meinung ist, das einfach nicht versteht und seine Meinung auf purer Unwissenheit begründet.
    Vor ein paar Jahren war's in der C-Gemeinde genauso, wer da nicht flüssig Sachen wie while(*dst++=*src++) geschrieben und gelesen hat, galt als doof. Es hat viele Jahre gebraucht, bis erste Zaghafte Versuche gemacht werden durften, bewußt lesbaren Code zu schreiben.



  • 123
    123
    a
    246

    Sonderlich elegant ist das für den User sicher nicht. Er weiß nicht, was das Programm macht und bricht nur zufällig mit einer Nichtzahl ab.

    Bei der Eingabe einer Float-Zahl wird es ganz düster:

    1.23
    1

    So liest sich das Programm zumindest kompakter:

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

    Es gibt drei Dinge, auf die ich zunächst achten würde:

    1. Usability: Das Programm ist für den User da. Der soll es intuitiv verstehen. Fehler und Zeitverluste sollen vermieden werden.

    2. Lesbarkeit des Programms: Es gibt immer einen Nachfolger/Kollegen, der daran weiter arbeiten soll.

    3. Grenzverletzungen abfangen:

    1000000000000000000
    0

    🙄

    ... und schon liegt der hübsche Käfer komplett auf dem Rücken. 😉



  • Erhard Henkes schrieb:

    Bei der Eingabe einer Float-Zahl wird es ganz düster:

    1.23
    1

    Das wird aber auch bei einer selber geschriebenen Methode zum Enlesen nicht besser, wenn Integer erwartet wird und deshalb auch cin.operator>> auf nen integer losgelassen wird.



  • Das wird aber auch bei einer selber geschriebenen Methode zum Enlesen nicht besser, wenn Integer erwartet wird und deshalb auch cin.operator>> auf nen integer losgelassen wird.

    Richtig. Daher muss das Programm diesbezüglich eben entsprechend prüfen / agieren.



  • 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


Anmelden zum Antworten