Präprozessor: Wechsel zwischen Ganz- und Kommazahl



  • Mach mit dem typedef. Wenn das klappt, schrauben ich es sogar freiwillig um zur Präpro-Variante.


  • Mod

    silent12 schrieb:

    Würde mich SEHR über Tipps freuen

    1. Die Aufgabe hast du völlig falsch verstanden.
    2. Wie dir schon gesagt wurde, du hast keine Ahnung was der Präprozessor kann und was nicht. Das ist entscheidend für die Aufgabe. Mach dich zumindest mit den Grundlagen vertraut.
    3. Lies nach 2. die Aufgabe noch einmal, vermutlich verstehst du dann auch was gemeint ist.
    4. Und wenn du so weit bist, dass du die Aufgabe überhaupt verstanden hast, dann ist sie auch sehr leicht zu lösen, die Aufgabe selbst sagt ja schon, dass der entscheidende Teil nur eine Zeile ist.



  • Ok ich lese mir dann mal ein anderes Tutorial durch, da in meinem Tutorial nur sehr wenig Funktionen des Präprozessors erklärt werden.



  • silent12 schrieb:

    Ok ich lese mir dann mal ein anderes Tutorial durch, da in meinem Tutorial nur sehr wenig Funktionen des Präprozessors erklärt werden.

    Lies dir ein Buch durch, da gibts kostenlose online, z.B. "Thinking in C++". Die meisten Tutorials (vor allem deutschsprachige) sind die Zeit nicht (mehr) wert, die der Autor investiert hat, um sie zu tippen. Es gibt Ausnahmen, aber nur wenige. Ein weiteres Problem ist, dass viele der Tutorials veraltet sind und einen Programmierstil predigen, der längst obsolet ist.



  • Da werden nur symbolische Konstanten kurz angesprochen, die bedingte Kompilierung, wie ich Dateien einfüge und die Fehlermeldung. Ich könnte das ganze Programm natürlich auch mit Präprozessoranweisungen für die Rechnungen gestalten



  • Entwickeln Sie einen Taschenrechner, der die Eingabe zweier Zahlen erwartet und diese addieren, subtrahieren, multiplizieren und dividieren kann. Über eine einzige Präprozessor-Anweisung soll eingestellt werden können, ob nur mit Ganz- oder auch mit Kommazahlen gearbeitet werden kann.

    Machs so:

    #ifdef USE_FLOAT
    typedef NumberType float;
    #else
    typedef NumberType int;
    #endif
    

    Jetzt benutzt du in deinem ganzen Code durchgehend NumberType zum Speichern von Zahlen (also kein float/int direkt) , ein einfaches

    #define USE_FLOAT
    

    am Anfang der Datei würde dazu führen dass float benutzt wird, ansonsten eben int.



  • silent12 schrieb:

    Da werden nur symbolische Konstanten kurz angesprochen, die bedingte Kompilierung, [...]

    Mehr brauchst du auch nicht. Siehe Ethons Beispiel (das nicht ganz richtig ist, den Fehler findest du aber sicher selbst)



  • pumuckl schrieb:

    silent12 schrieb:

    Da werden nur symbolische Konstanten kurz angesprochen, die bedingte Kompilierung, [...]

    Mehr brauchst du auch nicht. Siehe Ethons Beispiel (das nicht ganz richtig ist, den Fehler findest du aber sicher selbst)

    Whoops, ich hab echt keine Ahnung wieso ich in letzter Zeit immer die Reihenfolge vertausche. oO



  • Ah jetzt habe ich es kapiert (dank euch und diesem Tutorial: http://www.cplusplus.com/doc/tutorial/preprocessor/
    Ah ok und dadurch auch gleich die Aufgabe richtig verstanden :D. Ok ich versuche dann mal alles umzuschreiben.



  • Ok hoffe ich habe die Präprozessoranweisungen so verwendet wie gedacht (es kann gut sein, dass alles noch ziemlich umständlich gemacht ist).

    Habe es jetzt mal probiert, aber habe den Fehler noch nicht gefunden 😞

    #include <iostream> 
    using namespace std;
    #define USE_FLOAT
    
    #ifdef USE_FLOAT
    typedef Numbertype float;
    #else
    typedef Numbertype int;
    #endif
    
    int main()
    { Numbertype Ergebnis;
        char Rechenart;
    Numbertype Zahl1,Zahl2;
         cout << "Was wollen sie rechnen ? MAL ? PLUS ? MINUS ? oder GETEILT ?" <<endl;
         cin >>Rechenart;
    
    cout <<"Geben sie eine Zahl ein" << endl;
    cin >> Zahl1;
    
    cout <<"Geben sie noch eine Zahl ein" << endl;
    cin >> Zahl2;
    
    #if Rechenart = PLUS
    #define PLUS ((Zahl1) + (Zahl2));
    Ergebnis = PLUS(Zahl1,Zahl2);
    
    #elif Rechenart = MAL
    #define MAL ((Zahl1) * (Zahl2));
    Ergebnis = MAL(Zahl1,Zahl2);
    
    #elif Rechenart = MINUS
    #define MINUS ((Zahl1) - (Zahl2));
    Ergebnis = MINUS (Zahl1,Zahl2);
    
    #else
    #define GETEILT ((Zahl1) / (Zahl2));
    Ergebnis = GETEILT (Zahl1,Zahl2);
    
    #endif
    
    cout <<"Ergebnis:" << Ergebnis << endl;
    
      system("Pause");
    }
    

    Grüße
    silent12



  • Der Abschnitt ab Zeile 28 ist unsinnig - du kennst die erwartete Rechenoperation erst zur Programmlaufzeit, da kannst du mit Präprozessor-Anweisungen überhaupt nichts mehr ausrichten. An der Stelle benötigst du eine normale if()-Anweisung (eventuell auch ein switch()).



  • Ok thx für den Tipp, aber das hindert das Programm doch nicht am ausführen oder? Es ist ja eig egal WIE ich es errechne.



  • silent12 schrieb:

    Ok thx für den Tipp, aber das hindert das Programm doch nicht am ausführen oder? Es ist ja eig egal WIE ich es errechne.

    Buch macht kluch.



  • Doch, das verhindert eine vernünftige Abarbeitung. Abgesehen davon, daß ich nicht sicher bin, wie der Präprozessor mit Anweisungen wie "#if Rechenart=PLUS" zurechtkommt (besonders wenn er weder "Rechenart" noch "PLUS" kennt), würde mit dieset Konstruktion maximal einen der Berechnungs-Blöcke im fertigen Programm auftauchen. Die Variable "Rechenart" wird erst als solche akzeptiert, wenn der Compiler sich um den Quelltext kümmert, den der Präprozessor fabriziert, ihren Wert kannst du erst ausnutzen, wenn das Programm fertig compiliert und gelinkt ist und irgendwer es (möglicherweise auf einem ganz anderen Rechner) ausführt.



  • Habe es jetzt mal probiert, aber habe den Fehler noch nicht gefunden

    Mein Fehler war dass ich die Syntax von typedef (mal wieder) durcheinandergebracht habe.

    Es ist

    typedef %alt% %neu%
    

    und nicht anders herum. 😉



  • @CStoll:
    Ach stimmt :D. Ich muss wohl mehr darauf achten, dass die Präprozessoranweisung VOR dem compilieren ausgeführt wird.
    @Ethon: Ok habe noch nie mit typedef gearbeitet gehabt und deshalb die Syntax auch nicht gekannt.

    Ok habe jetzt die Fehler korrigiert und das Programm wird auch ausgeführt nur die Ergebnisse stimmen nicht 😞

    #include <iostream> 
    using namespace std;
    #define USE_FLOAT
    
    #ifdef USE_FLOAT
    typedef  float Numbertype;
    #else
    typedef int Numbertype;
    #endif
    
    int main()
    { Numbertype Ergebnis;
        int Rechenart;
    Numbertype Zahl1,Zahl2;
    
         cout << "Was wollen sie rechnen ? plus(1) ? mal(2) ? minus(3) ? oder geteilt(4) ?" <<endl;
         cin >>Rechenart;
    
    cout <<"Geben sie eine Zahl ein" << endl;
    cin >> Zahl1;
    
    cout <<"Geben sie noch eine Zahl ein" << endl;
    cin >> Zahl2;
    
    if (Rechenart = 1)
    {Ergebnis = Zahl1 + Zahl2;
    }
    
    if (Rechenart = 2)
    { Ergebnis = Zahl1 * Zahl2;
    }
    
    if (Rechenart = 3)
    { Ergebnis= Zahl1 - Zahl2;
    }
    
    else
    {Ergebnis= Zahl1 / Zahl2;
    }
    
    cout <<"Ergebnis:" << Ergebnis << endl;
    
      system("Pause");
    }
    

    Was habe ich noch falsch gemacht ?



  • Du hast den Vergleich (==) mit einer Zuweisung (=) verwechselt.



  • Rechenart wird doch immer mit den Zahlwerten verglichen, aber wenn ich da statt dem "=" ein "==" einsetze funktioniert es auch nicht



  • silent12 schrieb:

    Rechenart wird doch immer mit den Zahlwerten verglichen, aber wenn ich da statt dem "=" ein "==" einsetze funktioniert es auch nicht

    Sollte es aber...



  • Nein sollte es nicht.

    Überleg dir folgendes:
    Angenommen du möchtest multiplizieren, gibst also eine 2 ein.
    Danach gibst du noch 2 Zahlen ein - soweit ist alles gut.

    Nun kommt der code mit den if-statements.
    Erste Bedingung wird zu false ausgewertet.
    Zweite Bedingung ist true (Rechenart == 2), also werden die beiden Zahlen multipliziert und das Ergebnis gespeichert.
    Dritte Bedingung wieder false, aber es gibt hier einen else-Zweig, daher wird dieser durchlaufen.
    Im Ergebnis steht nun also nicht mehr das Produkt, sondern der Quotient.

    Lösung?
    Entweder switch-case (breaks nicht vergessen), oder else if!

    P.S.: Es ist ratsam, sich mit einem Debugger vertraut zu machen - so kannst du genau nachvollziehen, welcher Ast einer Verzweigung durchlaufen wird, welche Werte die Variablen haben etc.


Anmelden zum Antworten