Stack-Rechner nach dem Beispiel eines HP15C



  • hallo,
    ich bin neu hier im Forum!

    ich hab die Aufgabe bekommen einen Stack-Rechner nach dem Beispiel des HP15C zu programmieren.
    ich habe auch schon soweit programmiert, dass er die Grundrechenarten rechnet. Aller dings bin ich mir nicht sicher ob es ausreichen ist.

    Es wäre nett wenn ihr mir eure Meinung bzw. Vorschläge zu Verbesserung postet.

    vielen dank schon mal im voraus!

    hier ist der code

    struct lk{
        double data;
        lk *next;
    };
    
    lk *anker = 0; // Globaler Ankerpunkt
    
    void push(double data){
       // lk* node = (lk*)malloc(sizeof(lk));
       lk* node = new lk;
       node -> data = data;
       node -> next = anker;
       anker = node;
    }
    
    double pop(){
        double inhalt=0;
        if(anker){
            lk *old = anker;
            anker = anker -> next;
            inhalt = old -> data;
            delete old;
        }
        return inhalt;
    }
    
    void add(int n){
        for(int i=1;i<n;i++)
        push(pop()+pop());
    }
    
    void sub(int n){
        for(int i=1;i<n;i++)
        push(-(pop()-pop()));
    }
    
    void mul(int n){
        for(int i=1;i<n;i++)
        push(pop()*pop());
    }
    
    void div(int n){
        //for(int i=1;i<n;i++)
        push((1/pop())*pop());
    }
    
    int main(int argc, char *argv[]){
        bool x=true;
        int n=0;
        char z;
        double wert;
        //cout << "HP15C Rechner" << endl;
        printf("HP15C Rechner\n\n");
    
        do{
             //cin >> wert;
             scanf("%lf%c",&wert,&z);
             push(wert);
             n++;
             if (wert!=0){
                 //cin >> z;
                 //scanf("%c",&z);
                 if(z!=','){
                     switch (z) {
                         case '+': add(n);
                                   wert=pop();
                                   cout << wert << "," << endl; 
                                   push(wert);
                                   n=1;
                                   break;
                         case '-': sub(n);
                                   wert=pop();
                                   cout << wert << "," << endl;
                                   push(wert);
                                   n=1;
                                   break;
                         case '*': mul(n);
                                   wert=pop();
                                   cout << wert << "," << endl;
                                   push(wert);
                                   n=1;
                                   break;
                         case '/': div(n);
                                   wert=pop();
                                   cout << wert << "," << endl;
                                   push(wert);
                                   n=1;
                                   break;
                         case '=': cout << pop();
                                   //break;
                         default:  x=false;
                                   break;
                     }
                 }else;
             }
             else {
                 x=false;
             }
        }while(x);
    
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    zum Programm ich trenne die einzelnen eingaben mit einem Komma



  • Schade das keiner antwortet 😞



  • Erstmal, vermische bitte nicht C und C++. Dem Anschein nach, bist du eher auf C Seite, denn du programmierst prozedural. Nutze doch eine Klasse, wofür ist C++ objekt orientierent. Jedoch benutzt du dann wieder in der push_back() Funktion new, was aber C++ ist. Die push() Funktion ist in Ordnung, allerdings hab ich was an der pop() Funktion auszusetzen. Eine pop Funktion soll eig. nur ein Element herausnehmen aus der Liste und es dann löschen, da soll nichts zurückgegeben werden. Du benutzt eine Verkettete Liste, also solltest du die Funktionen push_back, pop_back usw. benennen, ansonsten könnte man denken das die Funktionen überladen sind und man z.B. push(element, stelle) machen könnte, womit das Element an eine bestimmte Stelle geschoben wird. Wenn ich ehrlich bin, ich blicke nicht ganz so durch deinen Code durch. Du pushst in der do-while Schleife den Wert in der Variable wert, in einem Case setzt du du die Variable wert dann auf den Wert was pop() zurückgibt, was in meinen Augen gleich bleibt und pusht es dann wieder zurück. Sieht also so aus ?

    Double Wert1 wird gepusht -> Double Wert1 in der Liste -> Pop Double Wert1 -> Double Wert1 wird gepusht -> Double Wert1 in der Liste

    Entweder nutze ich deinen Rechner falsch, oder er funktioniert nicht. Nachdem ich mich etwas in deine do Schleife eingelesen hab, habe ich deinen Rechner so genutzt:

    HP15C Rechner

    Eingabe: 12+
    Ausgabe: 12,
    Eingabe: 5=
    Ausgabe: 5

    Nach meinen Rechenkünsten sollte das 17 ergeben 😃 .
    Wenn ich jedoch statt dem = dann nochmal ein + schreibe, kommt das richtige raus.

    Also ich würde dir raten das alles in eine Klasse zu packen und alles in C++ zu machen.
    Habe ich irgendwas falsch bemänngelt, entschuldige ich mich, es ist schon 1 Uhr nachts und ich bin ein bisschen zu sehr müde 😛

    mfg



  • FreakY<3Cpp schrieb:

    Also ich würde dir raten das alles in eine Klasse zu packen

    Warum?

    FreakY<3Cpp schrieb:

    und alles in C++ zu machen.

    Es ist schon C++. Oder hatte dein C++ Compiler ernsthafte Schwierigkeiten damit?



  • C++Fan 2009 schrieb:

    FreakY<3Cpp schrieb:

    Also ich würde dir raten das alles in eine Klasse zu packen

    Warum?

    FreakY<3Cpp schrieb:

    und alles in C++ zu machen.

    Es ist schon C++. Oder hatte dein C++ Compiler ernsthafte Schwierigkeiten damit?

    oje.



  • Also um hier etwas klar zu stellen: C++ hat keinen Classen Zwang! Einige Sachen sind sogar prodezual sinnvoller und übersichtlicher. Immer Klassen zu verwenden macht den Code auch nicht besser!

    @Topic:

    HP15C Rechner

    3+
    3,
    13+
    16,
    16-
    -0,

    vielleich twäre es logischer wenn man die Operatoren vor dem Wert eingeben könnte! also +3 statt 3+ usw...

    @Freaky<3Cpp: Wie wärs wenn du dir mal Java anschaust? 😉



  • FreakY<3Cpp schrieb:

    Entweder nutze ich deinen Rechner falsch, oder er funktioniert nicht. Nachdem ich mich etwas in deine do Schleife eingelesen hab, habe ich deinen Rechner so genutzt:

    HP15C Rechner

    Eingabe: 12+
    Ausgabe: 12,
    Eingabe: 5=
    Ausgabe: 5

    Nach meinen Rechenkünsten sollte das 17 ergeben 😃 .

    sollte so gehen, wenn ich den rechner nicht ganz falsch einschätze:

    Eingabe: 12
    Eingabe: 5
    Eingabe: +
    Ausgabe: 17
    Eingabe: 3
    Eingabe: *
    Ausgabe: 51
    
    Eingabe: 2
    Eingabe: 3
    Eingabe: 5
    Eingabe: *
    Eingabe: +
    Ausgabe: 30
    
    Eingabe: 2
    Eingabe: 3
    Eingabe: 5
    Eingabe: +
    Eingabe: *
    Ausgabe: 16
    


  • C-Fan 2009 schrieb:

    Es ist schon C++. Oder hatte dein C++ Compiler ernsthafte Schwierigkeiten damit?

    Was außer das cout ist an dem Code bitte C++? (Das hat jetzt nicht mit Klassen oder nicht-Klassen zu tun, sondern am Programmierstil als solchen).

    Davon abgesehen würde ich hier tatsächlich eine Klasse verwenden.



  • oooooooooooooooooooooooo schrieb:

    Also um hier etwas klar zu stellen: C++ hat keinen Classen Zwang! Einige Sachen sind sogar prodezual sinnvoller und übersichtlicher. Immer Klassen zu verwenden macht den Code auch nicht besser!

    Mein Reden. In C++ hat man viele Freiheiten und viele Möglichkeiten, das Beste daraus zu machen. Klassen sind nicht immer das Sinnvollste.

    asc schrieb:

    C-Fan 2009 schrieb:

    Es ist schon C++. Oder hatte dein C++ Compiler ernsthafte Schwierigkeiten damit?

    Was außer das cout ist an dem Code bitte C++?

    Alles.

    asc schrieb:

    Davon abgesehen würde ich hier tatsächlich eine Klasse verwenden.

    Schau Dir Java an. Das wäre das Richtige für Dich.



  • push(-(pop()-pop()));
    

    ist falsch.
    da dürfen nicht zwei - sein. 8-5 ist ja nicht gleich -8-5

    push((1/pop())*pop());
    

    ist falsch wegen fehlernder sequence points.
    richtig ist wohl

    double a=pop();
    double b=pop();
    return a/b;
    

    und was soll überhaupt immer das

    for(int i=1;i<n;i++)
    

    ? das paßt da irgendwie gar nicht hin.



  • C-Fan 2009 schrieb:

    asc schrieb:

    Was außer das cout ist an dem Code bitte C++?

    Alles.

    printf und scanf gehören aus Kompatibilitätsgründen zu C++, sind in C++ aber nicht unbedingt der präferierte Stil. Zudem sind Klassen zwar nicht nötig, doch üblicherweise würde man in Situationen wie dieser mit Klassen hantieren.

    C-Fan 2009 schrieb:

    Schau Dir Java an. Das wäre das Richtige für Dich.

    Reden wir mal darüber, wenn du schon 10+ Jahre im C++ Umfeld gearbeitet hast. Deinen Verhalten nach traue ich dir das nur im C-Umfeld (wenn überhaupt) zu.

    cu André



  • C++Fan 2009 schrieb:

    asc schrieb:

    Davon abgesehen würde ich hier tatsächlich eine Klasse verwenden.

    Schau Dir Java an. Das wäre das Richtige für Dich.

    ja, der gedanke kam mir auch.

    noch ist der code gut nachvollziehbar und gut wartbar. vielleicht ist jetzt die gelegenheit, ihn korrekt und hübsch zu machen. danach kann man ihn immernoch in eine klasse stopfen. 😃
    die verwendung einer standard-stack-klasse könnte man antizipieren.



  • asc schrieb:

    printf und scanf gehören aus Kompatibilitätsgründen zu C++, sind in C++ aber nicht unbedingt der präferierte Stil.

    Es geht nicht um Stil. Der Fragesteller möchte sein Programm zum Laufen kriegen. Über seinen Stil herumzunörgeln hilft ihm nicht weiter.

    asc schrieb:

    üblicherweise würde man in Situationen wie dieser mit Klassen hantieren.

    Üblicherweise würdest Du daraus eine Klasse machen. Wie ich bereits sagte: beschäftige Dich lieber mit Java.



  • C-Fan 2009 schrieb:

    Wie ich bereits sagte: beschäftige Dich lieber mit Java.

    Tut mir leid, aber ich verdiene seit längeren mit C++ und nicht mit Java mein Geld (Und würde ohnehin C# Java vorziehen).



  • C++Fan 2009 schrieb:

    Es geht nicht um Stil. Der Fragesteller möchte sein Programm zum Laufen kriegen. Über seinen Stil herumzunörgeln hilft ihm nicht weiter.

    Was hilfts wenn er sein Programm jetzt zum Laufen bringt, es aber wegen schlechtem Stil so labil ist dass bei irgendeiner Änderung alles zusammenbricht und er in einem unwartbaren Codewrack steckt?



  • asc schrieb:

    C-Fan 2009 schrieb:

    Wie ich bereits sagte: beschäftige Dich lieber mit Java.

    Tut mir leid, aber ich verdiene seit längeren mit C++ und nicht mit Java mein Geld (Und würde ohnehin C# Java vorziehen).

    Und deswegen bist du erhaben von jeder Kritik? 🙄



  • pumuckl schrieb:

    C++Fan 2009 schrieb:

    Es geht nicht um Stil. Der Fragesteller möchte sein Programm zum Laufen kriegen. Über seinen Stil herumzunörgeln hilft ihm nicht weiter.

    Was hilfts wenn er sein Programm jetzt zum Laufen bringt, es aber wegen schlechtem Stil so labil ist dass bei irgendeiner Änderung alles zusammenbricht und er in einem unwartbaren Codewrack steckt?

    IN DIESEM FALL würde ein Klasse lediglich 3 Zeilen mehr Code bringen. Für DIESES Programm ist es einfach nur unnötig! Und die Behauptung Prodzedual -> "codewrack" ist absurd! 🙄
    Vergesst das Topic nicht :p



  • asc schrieb:

    (Und würde ohnehin C# Java vorziehen).

    Kennt C# keine freien Funktionen, oder woher kommt dein Irrglaube aus jeder Kleinigkeit Klassen machen zu müssen?

    pumuckl schrieb:

    Was hilfts wenn er sein Programm jetzt zum Laufen bringt, es aber wegen schlechtem Stil so labil ist dass bei irgendeiner Änderung alles zusammenbricht und er in einem unwartbaren Codewrack steckt?

    Ich finde seinen Stil nicht schlecht. Für ein Programm dieser Größe und geringen Kompexität ist er angemessen.



  • C++Fan 2009 schrieb:

    Für ein Programm dieser Größe und geringen Kompexität ist er angemessen.

    Das ist das Problem an der Sache. Der Stil ist schlecht skalierbar. Und sich für Programme verschiedener Größe verschiedene Stile anzugewöhnen ist nicht nur unnötig sondern auch potentiell gefährlich da man die Stile dann schnell mal vermischt. Außerdem weiß man selten von vornherein wie groß das Programm dann wirklich wird.



  • C-Fan 2009 schrieb:

    asc schrieb:

    (Und würde ohnehin C# Java vorziehen).

    Kennt C# keine freien Funktionen, oder woher kommt dein Irrglaube aus jeder Kleinigkeit Klassen machen zu müssen?

    Oh, glaube bloss nicht das ich zwangsweise überall Klassen verwende. Aber wenn einige Funktionen auf den gleichen Datenbestand arbeiten, schreit dies förmlich nach einer Klasse.

    Wobei ich durchaus Funktionen mit Klassen kombiniere sofern dies sinnvoll ist (Siehe hierzu auch die Scott-Meyers Bücher).

    Ein Stack, ist wohl mit die klassischste aller Anwendungsbeispiele einer Klasse.

    C-Fan 2009 schrieb:

    Ich finde seinen Stil nicht schlecht. Für ein Programm dieser Größe und geringen Kompexität ist er angemessen.

    Ich sehe auf Anhieb einiges an unnötigen Codeduplikaten und unnötiger Komplexität.

    cu André


Anmelden zum Antworten