Unterprogramme - Rechner



  • Hallo Leute,

    bin noch recht neu im Bereich C++ und auch hier im Forum, ich möchte folgende aufgabe lösen:

    1.1 Nach einer Eingabehilfe soll am Beginn der nächsten Zeile eine 0 (Null) ausgegeben werden.
    1.2 Anschließend sollen paarweise Operator und Operand mit abschließendem <ret> eingelesen werden und
    das Ergebnis berechnet und am Beginn der nächsten Zeile ausgegeben werden. (siehe Beispiel unten)
    1.3 Eingabe und Berechnung sollen solange wiederholt werden, bis als Operator ein e eingegeben wird;
    anschließend soll das Programm ohne weitere Aktivitäten (also auch ohne weitere Eingabe) terminieren.
    1.4 Gültige Operatoren sind +, -, * und /. Bei Division durch Null soll eine Fehlermeldung ausgegeben
    und das Programm mit dem letzten Wert fortgesetzt werden.
    Bei Eingabe von c (für clear) soll das Ergebnis auf 0 zurückgesetzt und ausgegeben werden.
    Achtung: die clear-Operation enthält keinen Operanden, also keine weitere Eingabe.
    1.5 Bei Eingabe ungültiger Operatoren soll eine Fehlermeldung ausgegeben und das Programm mit dem
    letzten Wert fortgesetzt werden.
    Beachten Sie, daß bei Eingabe eines falschen Operators nach der Fehlerausgabe das "alte" Ergebnis
    ausgegeben werden muß und daß der auf den falschen Operator (siehe unten 😵 folgende Operand
    (siehe unten: 3) gegebenenfalls auch als Operator eingelesen wird.

    Natürlich bin ich mir bewusst das hier keiner eine lösung postet und das soll auch niemand 😃 mich würde nur interessieren wie ihr sowas grob angehen würdet.

    thema bei uns sind unterprogramme und das semester läuft nen knappen monat, sind grad durch for schleifen und sowas durch und nun das. bis gestern war ich noch recht up2date aber ich hab keine idee wie ich das überhaupt angehen soll. eine grobe map mit ein paar schlagwörtern würde mir da sehr helfen.



  • 1. Hilfetext ausgeben.
    2. Variable anlegen, in der die Zahl gespeichert werden soll und auf 0 setzen.
    3. in einer Schleife jeweils
    - den aktuellen Wert ausgeben,
    - die Eingabe abfragen,
    - in Operator & Operand zerlegen
    - und dann in einer switch()-Abfrage je nach Operator die passende Operation anwenden (bei Division vorher auf 0 prüfen) bzw. Fehler ausgeben bzw. Wert auf null zurücksetzen bzw. Programm beenden.


  • Mod

    Pseudocode für ein Programm ohne templates:

    ergebnis=0;
    do
    {
     lese eingabe;
     switch(eingabe)
     {
       case '+': plusfunktion; break;
       case '-': minusfunktion; break;
       ...
       case 'c': ergebnis=0; break;
       default: fehlermeldung;
     }
     zeige ergebnis; 
    }while (eingabe != 'e')
    
    void plusfunktion
    {
     lese operand;
     addiere operand zu ergebnis;
    }
    


  • Also folgendes läuft bestens, aber ich weiss nicht obs im sinne des erfinders ist wenn das thema wirklich unterprogramme ist.. vorallem is da kein <ret> (was auch immer das sein soll!? return?!) drin..

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    	bool done = false;	
    	double result = 0;	
    
    	Schleife1:
    	while(!done)
    	{
    		cout << "=> " << result << endl;
    
    		enum {start, add, sub, mult, div, sign, intp, dot, fractp, quit, end, replay} state = start;
    
    		bool negsign = false;
    
    		enum {addop, subop, multop, divop, quitop} op;
    
    		double value = 0;
    
    		double fractweight;
    
    		while(state != end)
    		{
    
    			const char ch = cin.get();
    
    			switch(state)
    			{
    			    case start:
    				switch(ch)
    				{
    				    case '+':	state = add;	break;
    				    case '-':	state = sub;	break;
    				    case '*':	state = mult;	break;
    				    case '/':	state = div;	break;
    				    case 'q':	state = quit;	break;
    					case 'c':	state = replay;	break;
    				}
    				break;
    			    case add:
    			    case sub:
    			    case mult:
    			    case div:
    				switch(ch)
    				{
    				    case '-':	state = sign;	break;
    				    case '.':	state = dot;	break;
    				    case '0':
    				    case '1':
    				    case '2':
    				    case '3':
    				    case '4':
    				    case '5':
    				    case '6':
    				    case '7':
    				    case '8':
    				    case '9':	state = intp;	break;
    				}
    				break;
    			    case sign:
    				switch(ch)
    				{
    				    case '.':	state = dot;	break;
    				    case '0':
    				    case '1':
    				    case '2':
    				    case '3':
    				    case '4':
    				    case '5':
    				    case '6':
    				    case '7':
    				    case '8':
    				    case '9':	state = intp;	break;
    				}
    				break;
    			    case intp:
    				switch(ch)
    				{
    				    case '.':	state = dot;	break;
    				    case '0':
    				    case '1':
    				    case '2':
    				    case '3':
    				    case '4':
    				    case '5':
    				    case '6':
    				    case '7':
    				    case '8':
    				    case '9':	state = intp;	break;
    				    case '\n':	state = end;	break;
    				}
    				break;
    			    case dot:
    				switch(ch)
    				{
    				    case '0':
    				    case '1':
    				    case '2':
    				    case '3':
    				    case '4':
    				    case '5':
    				    case '6':
    				    case '7':
    				    case '8':
    				    case '9':	state = fractp; break;
    				}
    				break;
    			    case fractp:
    				switch(ch)
    				{
    				    case '0':
    				    case '1':
    				    case '2':
    				    case '3':
    				    case '4':
    				    case '5':
    				    case '6':
    				    case '7':
    				    case '8':
    				    case '9':	state = fractp; break;
    				    case '\n':	state = end;	break;
    				}
    				break;
    			    case quit:
    				switch(ch)
    				{
    				    case '\n':	state = end;	break;
    				}
    				break;
    			    case end:
    				break;
    			}
    
    			switch(state)
    			{
    			    case start:
    				break;
    			    case add:
    				op = addop;
    				break;
    			    case sub:
    				op = subop;
    				break;
    			    case mult:
    				op = multop;
    				break;
    			    case div:
    				op = divop;
    				break;
    			    case sign:
    				negsign = true;
    				break;
    			    case intp:
    				value = 10*value + (ch - '0');
    				break;
    			    case dot:
    				fractweight = 0.1;
    				break;
    			    case fractp:
    				value += fractweight*(ch - '0');
    				fractweight /= 10;
    				break;
    			    case quit:
    				done = true;
    				break;
    				case replay:
    				result = result*0;
    				goto Schleife1;
    				break;
    			    case end:
    				if(negsign)
    					value = -value;
    				switch(op)
    				{
    				    case addop:  result += value; break;
    				    case subop:  result -= value; break;
    				    case multop: result *= value; break;
    				    case divop:  result /= value; break;
    				    case quitop: break;
    				}
    				break;
    			}
    		}
    	}
    
    	cout << "Programm beendet." << endl;
    }
    


  • also das konzept ist unterprogramme und <ret> wobei ich ka hab was <ret> sein soll?



  • - in Operator & Operand zerlegen << wie mach ich das am besten

    er soll ja quasi

    +7 eingeben

    und nicht erst "+" und dann "7"

    so ist es gedacht:

    0
    0 +7
    7 *2
    14 /7
    2 -1
    1

    etc



  • #include <iostream>
    using namespace std;
    
    int rechentyp()
    {
    	double ergebnis = 0;
    	char eingabe;
    	do
    	{
    		cout << ergebnis;
    		cin >> eingabe;
    
    		switch(eingabe)
    		{
    		case '+': plus; break;
    		case '-': minus; break;
    		case '/': durch; break;
    		case '*': mal; break;
    		case 'c': ergebnis=0; break;
    		default: cout << "falsche eingabe"; break;
    		}
    		cout << ergebnis;
    	}while(eingabe!=e);
    }
    
    void plus()
    {
    	double zahl;
    	cin >> zahl;
    	ergebnis+=zahl;
    }
    
    void minus()
    {
    	double zahl;
    	cin >> zahl;
    	ergebnis-=zahl;
    }
    
    void durch()
    {
    	double zahl;
    	cin >> zahl;
    	ergebnis/=zahl;
    }
    
    void mal()
    {
    	double zahl;
    	cin >> zahl;
    	ergebnis*=zahl;
    }
    

    aber wie ihr sicher seht funktioniert das nicht 😃



  • sezai11 schrieb:

    aber wie ihr sicher seht funktioniert das nicht 😃

    Sehen wir nicht sofort, von daher wäre es fürs nächste Mal gut, wenn du die Fehlermeldung angeben könntest. Aber sehr gut, dass du [cpp]-Tags verwendet hast! 🙂

    Zu deinem Problem: Du verwendest Variablen, die nicht im Scope (Gültigkeits- und Sichtbarkeitsbereich) der Funktion sind. Benutze Parameter (evtl. Rückgabetyp), um mit der Aussenwelt zu kommunizieren. Hier mit einer Referenz:

    void plus(double& ergebnis)
    {
        double zahl;
        cin >> zahl;
        ergebnis+=zahl;
    }
    

    Beim Aufruf musst du dann das entsprechende Argument übergeben. Zum Beispiel so:

    int main()
    {
        double resultat = 0.0;
        plus(resultat);
        std::cout << resultat << std::endl;
    }
    

    Allerdings sind das wirklich Grundlagen. Funktionen sind etwas vom Elementarsten in C++, ohne sie kannst du keine sinnvollen Programme schreiben. Du solltest dir deshalb die Zeit nehmen, um ein gutes C++-Buch zu studieren, z.B. den C++-Primer. Ohne vollständige Theorie wirst du dauernd Wissenslücken haben, auch ein Forum hilft da nur bedingt. Glaub mir, das ist gut investierte Zeit. 😉


  • Mod

    Beschäftige dich mal mit Variablen, Sichtbarkeit und Funktionsaufrufen, dann sollte dir dein Fehler klar werden. Also genau das, was du bei dieser Aufgabe lernen sollst.



  • ja wie gesagt bin student im ersten semester und wir fangen grad erst an hatten vll 5 vorlesungen und hello world ist noch garnicht lang her. 😃

    ich habe jetzt einen anderen weg eingeschlagen, einen den ich zu 100% verstehe naja zu 99% sonst würd ich hier jetzt nicht schauen..

    #include <iostream>
    using namespace std;
    
    int main()
    {
        double zahl1;
    	double ergebnis = 0;
        char rechenzeichen; 
    	enum {start,end} state=start;
    
        cin >> rechenzeichen >> zahl1;
    
    	while(state!=end)
    	{
    	switch(rechenzeichen)
    		{                             
            case '+': ergebnis += zahl1; break;       
            case '-': ergebnis -= zahl1; break;       
            case '*': ergebnis *= zahl1; break;       
            case '/': ergebnis /= zahl1; break;
    		case 'e': ergebnis = 0; break;
    		case 'q': state=end;
            default: cout << "unbekanntes Rechenzeichen...\n"; return 1;
    		}
    	cout << "-> " << ergebnis;break;
    	}
    
    }
    

    das programm funktioniert, allerdings wird es nach der ersten eigabe berechnet und beendet, sprich es ist nur einmal möglich +1 oder *4 einzugeben dann ist schluss, wie mach ichs so das ich danach wieder etwas eingeben kann?

    @seppJ du hast recht und das werde ich auch sofort tun, denn dieser weg hier oben ist anscheinend nicht der "verlangte" allerdings juckt mich das grad 😃 kennt ihr sicher 🙂

    und @ nexus

    danke für die ansätze



  • Du hast ein 'break' zuviel -)

    Am besten immer den Debugger nehmen und dann Zeile für Zeile durchsteppen, damit kann man die meisten Programmierfehler finden.



  • ja aber wenn ich das letzte break wegnehm, führt er automatisch immer wieder die selbe funktion aus

    geb ich +5 ein

    0 5 10 15 20... bis xxxxxxxxxxxx...


  • Mod

    sezai11 schrieb:

    ja aber wenn ich das letzte break wegnehm, führt er automatisch immer wieder die selbe funktion aus

    geb ich +5 ein

    0 5 10 15 20... bis xxxxxxxxxxxx...

    Das liegt daran, dass bei dir die Eingabe außerhalb der Schleife erfolgt.



  • #include<iostream>
        using namespace std;
    
        double mul(int);
        double divi(int);
    	double add(int);
    	double sub(int);
    	int ergebnis=0;
    
        int main()
        {
            cout << "Bitte geben Sie die Rechnung ein:\n";
            char zeichen;
    		double	zahl;
    		bool eingabe=true;
    		while(eingabe)
    		{
    		cin >> zeichen >> zahl;
    		switch(zeichen)
    		{                             
    			case '+': add(ergebnis,zahl); break;       
    			case '-': sub(ergebnis,zahl); break;       
    			case '*': mul(ergebnis,zahl); break;       
    			case '/': divi(ergebnis,zahl); break;
    			case 'e': ergebnis*0; break;
    			case 'q': eingabe=false;
    			default: cout << "unbekanntes Rechenzeichen...\n"; return 0;
    		}
    		cout << "-> " << ergebnis;
    		}
        }
    
        double add(int a) //Definition einer Funktion
        {
          return a + ergebnis;
        }
    
    	double sub(int c) //Definition einer Funktion
        {
          return ergebnis-c;
        }
    
    	double mul(int e) //Definition einer Funktion
        {
          return e * ergebnis;
        }
    
    	double divi(int g) //Definition einer Funktion
        {
          return ergebnis / g;
        }
    

    so bin ich die sache nun angegangen allerdings funktioniert nun garnichtsmehr 😞


  • Mod

    sezai11 schrieb:

    so bin ich die sache nun angegangen allerdings funktioniert nun garnichtsmehr 😞

    das liegt daran, dass du nichts mit deinen Returnwerten machst. Entweder übergibst du das aktuelle Ergebnis per Referenz oder du musst das Ergebnis der Rechnung der Variable zahl zuweisen.



  • double mul(int);
    double divi(int);
    double add(int);
    double sub(int);
    int ergebnis=0;
    
    case '+': add(ergebnis,zahl); break;       
                case '-': sub(ergebnis,zahl); break;       
                case '*': mul(ergebnis,zahl); break;       
                case '/': divi(ergebnis,zahl); break;
    
    char zeichen;
            double    zahl;
            bool eingabe=true;
            while(eingabe)
            {
            cin >> zeichen >> zahl;
    

    davon passt rein gar nix zusammen...

    welchen teil davon verstehst du denn nicht?
    du musst jz auch gar nicht so tun, als ob du alle 3 bergeifen würdest, sonst würdest du es nicht so chaotisch anstellen ;o)

    bb



  • hmm ich versuche dir einfach mal zu erklären was ich mit den dingen vorhatte 😃

    unskilled schrieb:

    double mul(int); 
    double divi(int);
    double add(int);
    double sub(int);
    int ergebnis=0;
    
    // hier wollte ich halt variablen aufstellen, die von jedem der programme abgerufen werden können
    
    case '+': add(ergebnis,zahl); break;       
                case '-': sub(ergebnis,zahl); break;       
                case '*': mul(ergebnis,zahl); break;       
                case '/': divi(ergebnis,zahl); break;
    
    // hier sollte er das unterprogramm add.. auführen mit den werten ergebnis und zahl bzw den variablen
    
    char zeichen;
            double    zahl;
            bool eingabe=true;
            while(eingabe)
            {
            cin >> zeichen >> zahl;
    
    //ja und zu guter letzt wollte ich hier das man das zeichen und die zahl eingibt, die while schleife soll solang laufen bis eingabe false gesetzt wird
    

    davon passt rein gar nix zusammen...

    welchen teil davon verstehst du denn nicht?
    du musst jz auch gar nicht so tun, als ob du alle 3 bergeifen würdest, sonst würdest du es nicht so chaotisch anstellen ;o)

    bb



  • double add(int);
    add(ergebnis,zahl);
    

    du siehst aber, dass das hier vorn und hinten nicht stimmt?!

    bb



  • double add(double, double);
    add(double ergebnis, double zahl);
    

    ?!



  • #include<iostream>
        using namespace std;
    
        int mul(int, int);
        int divi(int, int);
    	int add(int, int);
    	int sub(int, int);
    	int zahl;
    	int ergebnis=0;
    
        int main()
        {
            cout << "Bitte geben Sie die Rechnung ein:\n";
            char zeichen;
    		bool eingabe=true;
    		while(eingabe)
    		{
    		cin >> zeichen >> zahl;
    		switch(zeichen)
    		{                             
    			case '+': add(ergebnis,zahl); break;       
    			case '-': sub(ergebnis,zahl); break;       
    			case '*': mul(ergebnis,zahl); break;       
    			case '/': divi(ergebnis,zahl); break;
    			case 'e': ergebnis*0; break;
    			case 'q': eingabe=false;
    			default: cout << "unbekanntes Rechenzeichen...\n"; return 0;
    		}
    		cout << "-> " << ergebnis;
    		}
        }
    
        int add(int, int) //Definition einer Funktion
        {
          return zahl + ergebnis;
        }
    
    	int sub(int, int) //Definition einer Funktion
        {
          return ergebnis-zahl;
        }
    
    	int mul(int, int) //Definition einer Funktion
        {
          return zahl * ergebnis;
        }
    
    	int divi(int, int) //Definition einer Funktion
        {
          return ergebnis / zahl;
        }
    

    so das programm startet, erhällt also keine "fehler" mehr zumindest für c++, allerdings macht er nicht das was er soll, wenn ich +5 eingebe, sagt er =0 :S


Log in to reply