C Code Korrekturlesen bitte, besonders Menüstruktur! einfacher "Taschenrechner"



  • chmbw schrieb:

    danke euch! 🙂

    ;fricky schrieb:

    naja, man könnte das programm bestimmt auf die hälfte verkürzen, aber ich weiss nicht, ob dir das helfen würde. eigentlich ist es ganz ok so (wenn's so läuft wie du willst, ich nehme an, das tut es).
    🙂

    Klar möcht ich das 😃 so kann ich mir halt ansehen, was ich wie anders schreiben könnte etc., einfach sehen wie es anders geht. Ich weiß ja genau, was passieren soll, von daher ist das mit dem Verstehen auch leichter. Wenn du die Lust dazu hättest, würde ich mich sehr darüber freuen!

    Grüße

    Nope!
    Das feine Aufdröseln ist total gut für die Übersicht, genau wie Du es sagst. In der Praxis wird man nicht die schlichte Addition auslagern und die anderen arithmetischen Operationen auch nicht. Die auszulagern ist ja auch ein wenig Quatsch. Andererseits hast Du aber die übliche menu-Schleife vereinfacht und die Eingabe(), die mit getchar() den Ärger mit dem überzähligen \n im Eingabestrom wegmacht ist Gold wert.
    Der Compiler wird selbsttätig die kleinen Funktionen zurückdröseln. Es ist hier allein die Entscheidung, ob Du selber als Leser dieses Codes mit mehr oder weniger Aufdröselung leben magst. Und wie Du in fünf Jahren den selben Code lesen magst, wenn Du Dich gar nicht mehr an die Erstellung erinnerst. Tendenz: Eher mehr aufgedröselt, aber die arithmetischen Einzelrechnungen vielleicht doch nicht auslagern. Aber Du mußt Dich in alle Richtungen austoben. Nur eigene Erfahrung bringt Dir ein Gefühl für solche Abschätzungen. Das hier war weit aufgedröselt, für mich ein wenig zu weit, aber tolower hat mir sehr gefehlt, das war immerhin ein eigenständiger Begriff, den Du nicht nur einmal oder zweimal verwendet hast und sogar schneller anders geht.
    Du solltest mal probieren, wie es sich anfühlt, wenn Du die Operationen nicht auslagerst. Ist es dann in 5 Jahren besser zu lesen? Ist die Menuschleife besser zu lesen, wenn Weiter() nicht ausgelagert ist? Ist Eingabe() gut? Ist ja alles schnell probiert oder bei völliger Eindeutigkeit sich vorgestellt. Ich denkem auf Eingabe() zu verzichten, wäre töricht.



  • Wenn man komplizierte Funktonen implementiert, z.B. Wurzelziehen, dann wäre es nur konsequent auch Addition usw. auszulagern.



  • Konsequentzierer schrieb:

    Wenn man komplizierte Funktonen implementiert, z.B. Wurzelziehen, dann wäre es nur konsequent auch Addition usw. auszulagern.

    Das ist zwar konsequentziert, aber ist es sinnvoll?

    x=y+3*4+sqrt(4);
    x=add(add(y,mul(3,4)),sqrt(4));
    

    Beim Programmieren gilt eigentlich nur "Alle Generalisierungen sind falsch.".



  • chmbw schrieb:

    so kann ich mir halt ansehen, was ich wie anders schreiben könnte etc., einfach sehen wie es anders geht.

    wenn du mal 'mal', 'geteilt' usw. einbauen willst, dann wirste feststellen, dass du an mehreren stellen basteln musst. überleg dir z.b., wie man nur durch hinzufügen einer funktion und was anhängen an ein array zusätzliche binäre operatoren (binär im sinne von 'braucht zwei operanden') einfach hinzufügen kann. als nächstes könntest du z.b. zeichenketten wie 'zahl op zahl' zerlegen, zahlen und operator erkennen und die passende rechnung ausführen. das kannste beliebig ausweiten, operatoren-rangfolge, klammern, längere ausdrücke verarbeiten, usw. damit haste einiges zu tun (falls du bock drauf hast).
    🙂



  • vielen lieben Dank! 🙂 Ich freu mich wirklich riesig hier so klasse Unterstützung zu kriegen! Ich finde die Idee mit diesem Code weiterzuarbeiten gar nicht so schlecht, einfach das Programm erweitern etc. Habe auch wieder ein paar neue Ideen was ich so machen könnte. 🙂 Herzlichen Dank!

    Grüße



  • soo, ich habe mich nochmal ans Werk gemacht und wollte jetzt erreichen, dass ich eine Funktion auswähle (addieren, subtrahieren usw.) und dann beliebig viele Zahlen eingeben kann und die Eingabe mit der Eingabe von 0 beende. Ich habe bis jetzt nur diese Programmschnipsel:

    #include <stdio.h>
    #include <stdlib.h>              
    
    int Hauptmenue();
    double Addition();
    double Eingabe();
    
    int main()
    {
        printf("\tTaschenrechner Version 4\n\n");
    
        while(Hauptmenue() != 0)
        {
          Hauptmenue();
        }
    
        printf("Auf Wiedersehen");
    
        system("PAUSE");
        return 0;
    }
    
    int Hauptmenue()
    {
        char wahl;
    
        printf("Hallo, welche Rechenoperation wollen Sie ausfuehren?\n\n");
        printf("****************************************************\n\n");
        printf("\t[a] - Addition\n");
        printf("\t[b] - Subtrakion\n");
        printf("\t[c] - Multiplikation\n");
        printf("\t[d] - Division\n");
        printf("**************************\n");
        printf("\t[x] - Beenden\n\n");
        printf("Ihre Wahl: ");
    
        scanf("%c",&wahl);
        getchar();
    
        printf("\n\nBitte Zahlen eingeben, wenn Eingabe vollendet, 0 eintippen\n\n");
    
        switch (tolower(wahl))
        {
               case 'a' : Addition();
                        break;
               case 'b' : 
                        break;
               case 'c' :
                        break;
               case 'd' :
                        break;
               case 'x' : return 0;
    
               default  : printf("Falsche Eingabe!!\n\n");
                          return 1;
        }
    
    }
    
    double Eingabe()
    {
           double zahl=0;
    
           printf("Zahl eingeben: ");
           scanf("%f",&zahl);
           getchar();
    
           printf("\nZahl = %f\n",zahl);
    
           return zahl;
    }
    
    double Addition()
    {
           double ergebnis1=0;
           double ergebnis2=0;
    
           do {
               ergebnis1 = Eingabe();
               ergebnis2 += ergebnis1;
    
               printf("Zwischenergebnis: %f\n",ergebnis2);
               }       
           while (ergebnis1 !=0);
    
           printf("\nDas Ergebnis lautet: %f\n\n",ergebnis2);
    
           return 0;
    }
    

    Allerdings scheint die Eingabe der Zahl nicht zu gelingen, er speichert sie nicht oder sowas in der Art. Erkennt jemand meinen Fehler? Vielleicht ist es aber auch einfach nur zu spät grade 😃 Kann ich das ganze so mit der do-while schleife überhaupt anstellen oder ist das wieder viel zu umständlich?! 🙂

    Grüße



  • chmbw schrieb:

    Allerdings scheint die Eingabe der Zahl nicht zu gelingen, er speichert sie nicht oder sowas in der Art

    %f ist für float. Für double musst du %lf nehmen.

    chmbw schrieb:

    Kann ich das ganze so mit der do-while schleife überhaupt anstellen oder ist das wieder viel zu umständlich?! 🙂

    Ich find das nicht umständlich. Klarer wird's halt immer, wenn die Namen der Variablen was mit iherer Funktion zu tun haben.

    while(Hauptmenue() != 0)
        {
          Hauptmenue();
        }
    

    Jetzt kannst du nur jedes zweite Mal abbrechen. Sonst wird's schon passen. Bis auf Eingabefehler natürlich, aber die sind langweilig. Andererseits bräuchtest du die nur in Eingabe() abfangen. Bei Interesse zB hier weiterlesen:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39349-and-start-is-1.html
    🙂



  • µngbd schrieb:

    Jetzt kannst du nur jedes zweite Mal abbrechen. Sonst wird's schon passen. Bis auf Eingabefehler natürlich, aber die sind langweilig. Andererseits bräuchtest du die nur in Eingabe() abfangen. Bei Interesse zB hier weiterlesen:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39349-and-start-is-1.html
    🙂

    int c; // int c, nicht char c.
    while ((c = getchar()) != EOF && c != '\n'); // kein {} block, stimmt s
    

    also damit funktionierts wunderbar! 🙂 nur irgendwie habe ich den Ausdruck noch nicht ganz verstanden:

    ich definiere mit ein INTEGER c, warum? c ist doch 99 im ASCII-Code. Der Sinn erschließt sich mir nicht. Wieso hat die while-schleife keinen Block? In ihrer Bedigung wird c solange ein character zugewiesen (aber als integer gespeichert?!) solange != EOF (EOF = End Of File, aber was bedeutet das hier genau?? Ende der Funktion?) Ich wäre sehr dankbar wenn mir das einer ein wenig weiter aufdröseln könnte 🙂 Danke im Voraus!

    Grüße



  • EOF = End of file. Das wird oft durch einen negativen Wert dargestellt, daher ist es gefährlich da einen char zu benutzen, der oft unsigned ist.



  • chmbw schrieb:

    Wieso hat die while-schleife keinen Block?

    Das sollte man sicherheitshalber so schreiben:

    while ((c = getchar()) != EOF && c != '\n')
        ;
    

    Dann kann man sich den Kommentar sparen, weil das ; ins Auge springt. Das ist eine leere Anweisung, die tut einfach nichts. Die muss dort sein, weil die nächste Anweisung (oder der nächste Block) eben zum while gehört, so ist die Syntax. Genauso solltest du sagen:

    while(Hauptmenue() != 0)
        ;
    // und weil Vergleiche auf != 0 redundant sind, sagt man oft stattdessen
    while(Hauptmenue())
        ;
    

    chmbw schrieb:

    EOF = End Of File, aber was bedeutet das hier genau?? Ende der Funktion?

    EOF heisst immer End Of File. Die Standard-Eingabe ist auch nur eine Datei. Damit fängt man den Fall ab, dass die Eingabe zu Ende ist. Das kann passieren, wenn man eine Datei als Eingabe an das Programm leitet (zB type file.txt | program auf Windows), oder wenn man explizit die Eingabe beendet, das geht auf den meisten Terminals mit Strg-D oder Strg-Z oder so.

    chmbw schrieb:

    aber als integer gespeichert?!

    Ein char ist auch nur eine Ganzzahl, aber der Wertebereich ist meistens kleiner. 'A' ist nur eine andere Weise, um 65 zu sagen (ASCII vorausgesetzt). EOF darf aber kein gültiges Zeichen sein, deshalb muss man für die Rückgabe von getchar() einen grösseren Wertebereich nehmen.
    🙂



  • EOF darf aber kein gültiges Zeichen sein, deshalb muss man für die Rückgabe von getchar() einen grösseren Wertebereich nehmen.

    Da fällt mir ein, dass fricky mal erzählt hat, dass auf 8-Bit-Dingern ein int trotzdem 16 Bit hat. Ich hab mir damals gedacht, dass 8 Bits für eine Zahl wohl doch recht wenig wären, und mir das so erklärt. Aber wenn ein char so gross wie ein int wäre, würde getchar() nicht mehr funktionieren, oder?



  • µngbd schrieb:

    Da fällt mir ein, dass fricky mal erzählt hat, dass auf 8-Bit-Dingern ein int trotzdem 16 Bit hat.

    bezogen darauf, dass ich noch nie 'nen compiler gesehen habe, der 8-bittige ints hat (wohl aber einen, wo man das einstellen konnte, default war aber auch bei dem 16-bit int). im C-std findeste etwa sowas:

    — minimum value for an object of type int
    INT_MIN -32767 // -(2^15 - 1)
    — maximum value for an object of type int
    INT_MAX +32767 // 2^15 -1
    

    und wieder mal sind die standard auswendigkenner gefragt: ist ein 8-bit int laut C-standard theoretisch möglich?
    🙂



  • zder davebardsley in http://www.linuxforums.org/forum/linux-programming-scripting/44480-sizeof-int.html bestätigt dich und der link http://en.wikipedia.org/wiki/C_variable_types_and_declarations#Size sagt auch "An int must be at least 16 bits long.".



  • Nicht wenn ich mit 8Bit ~65000 Zahl darstellen kann! Ich nehm einfach einen komprimierungsalgorithmus... 🤡



  • Genmutant schrieb:

    Nicht wenn ich mit 8Bit ~65000 Zahl darstellen kann! Ich nehm einfach einen komprimierungsalgorithmus... 🤡

    Viel Erfolg http://en.wikipedia.org/wiki/Minimum_message_length



  • Genmutant schrieb:

    Nicht wenn ich mit 8Bit ~65000 Zahl darstellen kann!

    musste passend runden, 0...256...512...768... usw., dann klappt das *fg*
    🙂



  • ;fricky schrieb:

    Genmutant schrieb:

    Nicht wenn ich mit 8Bit ~65000 Zahl darstellen kann!

    musste passend runden, 0...256...512...768... usw., dann klappt das *fg*
    🙂

    Geht sogar noch komprimierter. Sozusagen am komprimiertesten:

    int passendRunden(int x){
       if(x==0)
          return 0;
       else
          return x/2;
    }
    

    oder etwas langsamer aber nicht rekursiv:

    int passendRunden(int x){
       while(x*=3);
          x*=5;
    }
    

Anmelden zum Antworten