Stilfrage zu meinem Code



  • C++ Spaghettis

    Ja, ist es. Bitte akzeptiere, dass du kein perfektes C++ von Anfang an schreibst. Komm wieder, wenn du ein echtes Problem hast.

    Eine Differenz-Funktion ist übrigens einfach so zu implementieren

    Funktioniert nicht mit unsigned.



  • - wenn du als Anwender eine 0 eingibst, wird smallest und biggest zurückgesetzt
    - ich dachte, du sollst immer nur einen Wert einlesen?
    - bei deiner Funktion biggest_smallest ist es ausreichend, num[i] zu übergeben, statt den ganzen Vector und den Index
    - der Einsatz eines Vectors ist nur dann sinnvoll, wenn du mehrere Werte speichern willst, du aber vorher nicht weißt, wie viele. Ein Vector ist dynamisch, das heißt, man kann leicht Einträge hinzufügen mit vector.push_back(), für Dinge fester Größe gibt es Arrays, bei nur zwei Variablen kannst du auch gleich beide einzeln definieren.

    Hier mein Vorschlag, den Teil mit (fast) gleich habe ich weggelassen:

    #include <iostream>
    
    using namespace std;
    
    void addValue(double &smallest, double &biggest, double input, int count);
    int main ()
    {
        int count = 0;
    	double smallest, biggest, input;
        while (true)
        {
            count++;
    		cout << "Zahl eingeben: ";
    		cin >> input;
    		addValue(smallest, biggest, input, count);
    		cout << "  kleinste Zahl: " << smallest << endl;
    		cout << "  groesste Zahl: " << biggest << endl;
    	}
        system("pause");
        return 0;
    }
    
    void addValue(double &smallest, double &biggest, double input, int count)
    {
    	if(count == 1)
    	{
    		smallest = input;
    		biggest = input;
    	}
    	if(smallest > input)
    		smallest = input;
    	if(biggest < input)
    		biggest = input;
    }
    


  • @ *
    Dank dir. Templates waren allerdings noch nicht dran.
    Was hättest du denn zum Einlesen von zwei Variablen implementiert? Mir ist jetzt nichts anderes eingefallen, was man in der Reihenfolge beschreiben könnte.

    @Knivil
    Das erwarte ich auch nicht. Ich hätte nur gern gewusst, was ich falsch machen, da ich meine Fehler nicht von Kapitel zu Kapitel weiterschleppen möchte.
    Etwas ähnliches hat mir mein Musiklehrer früher auch gesagt.
    "Beim Klavierspielen darfst du dir eine falsche Fingerhaltung gar nicht erst angewöhnen. Ansonsten bekommst du sie nur schwer wieder weg."

    Leider gibt es zu den wenigsten Aufgaben in diesem Buch eine Lösung. Und gerade zu dieser Aufgabe gibt es keine.

    Wo ist denn nach deiner Meinung der Spaggethicode?
    Zu viele if else? Unlogische Unterteilung in Funktionen?
    Oder hätte ich sogar eine der Schleifen sparen können?



  • Zu viele if else? Unlogische Unterteilung in Funktionen?
    Oder hätte ich sogar eine der Schleifen sparen können?

    Ja, ja, ja ... und mehr. Ich glaube auch, dass du die Aufgabe missverstanden hast. Btw. Programmieren ist nicht wie Klavierspielen.


  • Mod

    knivil schrieb:

    Btw. Programmieren ist nicht wie Klavierspielen.

    c.rackwitz schrieb:

    Wenn du selber Code schreibst, musst du ihn auch verstehen. Code ist kein Haufen von wahllos zusammengeschmissenen Buchstaben und Zeichen, Code ist Logik pur. Du musst genau wissen, warum du wo und welches Zeichen setzt.

    Nur um das spezifische Beispiel mal nicht unkritisiert zu lasse: Inwiefern nicht? Denkst du etwa, ein Komponist schmeißt wahllos Noten und Pausen in einen Topf?

    von zwei Variablen implementiert?

    Von zwei? Das war doch die vorige Aufgabe.

    @eulerscheZahl: Falsch implementiert. Es soll ausgeben, ob der letzte Wert ... .



  • @Eulaschezahl

    Danke!
    Das sieht auf jeden Fall schon einmal sauberer als meine Version aus.
    Stimmt, ich sollte immer nur eine Zahl einlesen. Allerdings pro Schleifendurchlauf, was ich ja auch gemacht habe. Wie ich das verstanden habe, solltes nur nicht aufeinmal sein.

    Bei deinem Programm gibt es nur ein kleines Problem.
    Wenn die Schleife jetzt durchgelaufen ist und input nicht kleiner als smallest oder größer als biggest war, wird kein Text ausgegeben.
    Daher habe ich einen Vector genommen, von dem man die Zahlen nach jedem Durchlauf verwenden kann.

    Das mit der Variable Counter finde ich gut. Da die Zahl nicht wieder 1 sein wird, werden smallest und biggest auch nur einmal initialisiert.

    @Knivil
    Gerade die if else Sache macht mir Probleme. Da steig ich noch nicht so durch, wie man sowas vermeiden kann.
    Das mit der Aufgabenstellung kann durchaus sein, da manchmal nicht klar ersichtlich ist, ob man eine Funktion hinzufügen oder ersetzen soll.



  • @*

    Ja, da hab ich mich wohl etwas ungenau ausgedrückt.
    Die Aufgabenstellung war ja, dass pro Durchlauf nur eine eingelesen werden soll. Das es insgesamt nur eine sein darf, wurde nicht gesagt.
    Denn wenn es nur eine insgesamt sein darf, kann ich ja nicht sagen, ob die letzten beiden gleich oder ungleich waren

    Mit den letzten beiden meine ich nicht smallest und biggest. Die sollen ja nur sagen, welche die bisher größte und kleinste Zahl war..



    • schrieb:

    Wieso erstellst du einen vector mit fester Größe für zwei Variablen? Das muss doch schöner gehen. Eine Differenz-Funktion ist übrigens einfach so zu implementieren:

    template<typename T>
    T difference( T a, T b )
    {
        return std::abs(a - b);
    }
    

    (Ein Bilderbuchbeispiel für ein Funktionstemplate)

    Da fehlt was. 😉

    class foo_type{};
    foo_type operator-(foo_type, foo_type)
    {
      return foo_type();
    }
    
    foo_type abs(foo_type)
    {
      return foo_type();
    }
    
    foo_type a,b;
    foo_type c = difference(a,b);
    

    http://ideone.com/4lQxRT


  • Mod

    Das habe ich natürlich für Fließkommazahlen geschrieben.

    Und ich habe nicht vor, ADL oder Unterstützung für vorzeichenlose Skalare zu ergänzen, um den TE nicht zu verwirren.



    • schrieb:

    knivil schrieb:

    Btw. Programmieren ist nicht wie Klavierspielen.

    c.rackwitz schrieb:

    Wenn du selber Code schreibst, musst du ihn auch verstehen. Code ist kein Haufen von wahllos zusammengeschmissenen Buchstaben und Zeichen, Code ist Logik pur. Du musst genau wissen, warum du wo und welches Zeichen setzt.

    Nur um das spezifische Beispiel mal nicht unkritisiert zu lasse: Inwiefern nicht? Denkst du etwa, ein Komponist schmeißt wahllos Noten und Pausen in einen Topf?

    Nicht völlig wahllos, nein.

    Hat aber auch niemand behauptet. "Völlig wahllos zusammenschmeissen" ist nicht die Negation von "ganz genau wissen warum man wo was wie macht". Und "ganz genau wissen warum man wo was wie macht" kann ein Komponist nicht immer, denn sonst könnte er nie was neues komponieren. So könnte man nichtmal nen erfolgreichen Remix von irgendwas basteln.

    Du scheinst recht gerne Aussagen falsch verstehen zu wollen. Bloss peinlich wenn du beim Kritisieren dann dumme Fehler machst.



  • Sone schrieb:

    Wieso erstellst du einen vector mit fester Größe für zwei Variablen? Das muss doch schöner gehen. Eine Differenz-Funktion ist übrigens einfach so zu implementieren:

    template<typename T>
    T difference( T a, T b )
    {
        return std::abs(a - b);
    }
    

    (Ein Bilderbuchbeispiel für ein Funktionstemplate)

    Aber ganz schlechter Stil. Was Du implememntiert hast, wäre wohl absulute_difference, wobei man als Anwender wohl lieber abs(a-b) schreibt, also absolute_difference(a,b). difference(a,b) muss a-b sein,


  • Mod

    Aber ganz schlechter Stil.

    Das ist der bequemlichkeit wegen kurz gehalten. Der TE hat ebenfalls Differenz geschrieben, ich habe nur sein Wort genommen und übersetzt.

    Daher habe ich einen Vector genommen, von dem man die Zahlen nach jedem Durchlauf verwenden kann.

    Das ist überflüssig. Ein vector ist ein dynamisches Array. 💡
    Edit: Nun gut, du kennst ja nichts anderes...


  • Mod

    Trifft es nicht schon dieses simple Programm:

    #include <iostream>
    
    int main()
    {
    	double min;
    	std::cin >> min;
    	double max = min;
    
    	for( double current; std::cin >> current; )
    		if( current > max )
    		{
    			max = current;
    			std::cout << "Groesster bisher eingegebener Wert!\n";
    		}
    		else if( current < min )
    		{
    			min = current;
    			std::cout << "Kleinster bisher eingegebener Wert!\n";
    		}
    }
    

    Du hast ja in deinem Anfangsposting Code gepostet, der offensichtlich noch mehr macht - war das Teil der Aufgabenstellung?



    • schrieb:
    for( double current; std::cin >> current; )
    

    👎
    Das entwertet die Stärke des for-Schlüsselworts für die Verbesserung der Lesbarkeit typischer for-Schleifen.


  • Mod

    Bei mir hat es nicht mal für einen müden Schmunzler gereicht. Dagegen war der heilige Grahl in der Bluse definitiv ein Brüller.

    Ernst kannst du das wohl kaum meinen.



    • schrieb:

    Ernst kannst du das wohl kaum meinen.

    Doch.


  • Mod

    volkard schrieb:

    • schrieb:

    Ernst kannst du das wohl kaum meinen.

    Doch.

    🙂
    Gut. Ich sehe ja, dass du (aus gutem Grund) die for-Schleife tatsächlich nur als Zähl-Schleife nutzt. Alles andere wäre das Zusammenpressen mehrerer Zeilen auf Eine durch den Missbrauch der for-Schleife.

    Also

    double current;
    while( std::cin >> current )
    

    Ich sah nun die obige Schleife als sehr gut lesbar an. Na gut, wenn du so konsequent in deinen Prinzipien bist - ich versuche die for-Schleife nicht zu missbrauchen, und habe fast nirgends eine stehen (weil ich keine Zählschleifen habe) . Aber das sah ich als absolut in Ordnung an.



    • schrieb:

    ich versuche die for-Schleife nicht zu missbrauchen, und habe fast nirgends eine stehen (weil ich keine Zählschleifen habe)

    Ist beides veraltet. Heutzutage schreibt man

    for (int i : range(0, 10))
      // mach was mit i
    

    und

    for (double d : istream_range<double>(std::cin))
      // mach was mit d
    

    Die Helferklassen zu schreiben ist trivial.



  • c++11kiddy schrieb:

    • schrieb:

    ich versuche die for-Schleife nicht zu missbrauchen, und habe fast nirgends eine stehen (weil ich keine Zählschleifen habe)

    Ist beides veraltet. Heutzutage schreibt man

    for (int i : range(0, 10))
      // mach was mit i
    

    Hab damit keine supi Erfahrungen gemacht, weil sie ruck zuck eklig werden, wenn die Schleifen nicht ganz so einfach sind.


  • Mod

    Beides völliger Unsinn.
    (Und mit Unsinn beziehe ich mich auf die Lesbarkeit, die sich dadurch kein Stück verbessert hat)

    Edit: Ich mache erstmal noch keine Aussagen bezüglich Performance...


Anmelden zum Antworten