if – Schleife bei der Division durch Null



  • Das Programm läuft gut kein Problem. Die if – Schleife bei der Division durch Null läuft auch und sagt sein Sprüchlein auf.
    Das einzige was mich verwundert, ist das trotzdem ein sinnloses Ergebnis angezeigt wird.
    Ich benütze den GNU GCC Compiler.
    Bitte um eine Erklärung warum ist das so und was muss ich ändern.
    Danke

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int eingabe1;
        int eingabe2;
        int ergebnis;
    
        char rechenzeichen;
        cout<<"Taschenrechner"<<endl;
        cout<<"Geben Sie die 1.Zahl ein : ";
        cin>>eingabe1;
        cout<<"Geben Sie die gewuenschte Rechenoperation an (+ - * /): ";
        cin>>rechenzeichen;
        cout<<"Geben Sie die 2.Zahl ein: ";
        cin>>eingabe2;
    
        switch(rechenzeichen)
        {
            case '+':
                ergebnis=eingabe1+eingabe2;
                break;
    
            case '-':
                ergebnis=eingabe1-eingabe2;
                break;
    
            case '*':
                ergebnis=eingabe1*eingabe2;
                break;
    
            case '/':
                if (eingabe2 ==0)
                {
                    cout <<" Division durch 0 nicht erlaubt ! ";
                }
                    else
                    {
                         ergebnis=eingabe1/eingabe2;
                    }
            break;
    
            default:
                cout<<"Ein ungueltiger Rechenoperator wurde angegeben!"<<endl;
        }
    
        cout<<"Ergebnis: "<<ergebnis<<endl;
    
        return 0;
    }
    


  • if-Schleife.

    *Edit
    Hab dein Problem verstanden. Das was hier stand passte nicht zu deiner Frage.



  • So besser?

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int eingabe1;
        int eingabe2;
        int ergebnis;
    
        char rechenzeichen;
        cout<<"Taschenrechner"<<endl;
        cout<<"Geben Sie die 1.Zahl ein : ";
        cin>>eingabe1;
        cout<<"Geben Sie die gewuenschte Rechenoperation an (+ - * /): ";
        cin>>rechenzeichen;
        cout<<"Geben Sie die 2.Zahl ein: ";
        cin>>eingabe2;
    
        switch(rechenzeichen)
        {
            case '+':
                ergebnis=eingabe1+eingabe2;
                break;
    
            case '-':
                ergebnis=eingabe1-eingabe2;
                break;
    
            case '*':
                ergebnis=eingabe1*eingabe2;
                break;
    
            case '/':
                if (eingabe2 ==0)
                {
                    cout <<" Division durch 0 nicht erlaubt ! ";
                    ergebnis = 4711; //sinnvolles ergebnis
                }
                    else
                    {
                         ergebnis=eingabe1/eingabe2;
                    }
            break;
    
            default:
                cout<<"Ein ungueltiger Rechenoperator wurde angegeben!"<<endl;
        }
    
        cout<<"Ergebnis: "<<ergebnis<<endl;
    
        return 0;
    }
    

    Oder was soll das Programm genau tun bei Division durch 0?



  • Weil du ergebnis aufrufst aber nicht initialisiert hast( bei einen Fehler ), deswegen hat deine Variable eine zufällige Zahl.

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int eingabe1 = 0;
        int eingabe2 = 0;
        int ergebnis = 0;
        bool error = false;
    
        char rechenzeichen;
        cout<<"Taschenrechner"<<endl;
        cout<<"Geben Sie die 1.Zahl ein : ";
        cin>>eingabe1;
        cout<<"Geben Sie die gewuenschte Rechenoperation an (+ - * /): ";
        cin>>rechenzeichen;
        cout<<"Geben Sie die 2.Zahl ein: ";
        cin>>eingabe2;
    
        switch(rechenzeichen)
        {
            case '+':
                ergebnis=eingabe1+eingabe2;
                break;
    
            case '-':
                ergebnis=eingabe1-eingabe2;
                break;
    
            case '*':
                ergebnis=eingabe1*eingabe2;
                break;
    
            case '/':
                if (eingabe2 == 0)
                {
                    cout << "Division durch 0 nicht erlaubt ! ";
                    error = true;
                }
                    else
                    {
                         ergebnis=eingabe1/eingabe2;
                    }
            break;
    
            default:
                cout<<"Ein ungueltiger Rechenoperator wurde angegeben!"<<endl; error=true;
        }
        if(!error)
        {
            cout<<"Ergebnis: "<<ergebnis<<endl;
        }
    
        return 0;
    }
    


  • volkard schrieb:

    // ...
    
                    cout <<" Division durch 0 nicht erlaubt ! ";
                    ergebnis = 4711; //sinnvolles ergebnis
    
    // ...
    

    Ne, 32202 ist hier natürlich das einzig sinnvolle Ergebnis!

    cppvoid schrieb:

    Weil du ergebnis aufrufst aber nicht initialisiert hast( bei einen Fehler ), deswegen hat deine Variable eine zufällige Zahl.

    Das ist nicht Der Fehler™.



  • volkard: Da hast du vollkommen recht; man sollte bis zum ende denken.

    cppvoid : bool habe ich schwer vernachlässigt, wird sich ändern.

    Danke und Schönes Wochenende



  • Kleine Randbemerkung:

    Atomare Datentypen sollten immer initialisiert werden,
    um ein deterministisches Verhalten des Programmes gewährleisten zu können.

    bool notInitialized;
    if( notInitialized ) {
      std::cout << "Sie liebt mich!" << std::endl;
    } else {
      std::cout << "Sie liebt mich nicht!" << std::endl;
    }
    

  • Mod

    Atomare Datentypen

    Der Begriff ist seit C++11 mehrdeutig geworden. Siehe <atomic> . fundamental ist besser, glaube ich.

    Und was genau ist eigentlich der Anlass zu deinem Post? In einigen Fällen sollten Variablen fundamentalen Typs nicht bei der Definition initialisiert werden (worauf du ja hinaus willst?*), weil das schon anderweitig passiert:

    int i = 0; 
    // Aha, Offenbar wird i gleich in irgendeiner Berechnung (Schleife?) verwendet und i's Wert wird vor der ersten Zuweisung benötigt.
    // […] (hier könnte etwas stehen dass die Definition von i und das folgende Statement trennt)
    std::cin >> i; // Huch? Hier wird i nochmal initialisiert, wozu also obige Initialisierung? Hab' ich glatt etwas übersehen?
    

    mMn verwirrend.

    * Wenn du darauf hinaus willst dass man Variablen irgendwie initialisieren muss: Das ist selbstverständlich. Mit völlig un-initialisierten Variablen kann man nicht viel machen. 🤡



  • jb2012 schrieb:

    Kleine Randbemerkung:

    Atomare Datentypen sollten immer initialisiert werden,
    um ein deterministisches Verhalten des Programmes gewährleisten zu können.

    bool notInitialized;
    if( notInitialized ) {
      std::cout << "Sie liebt mich!" << std::endl;
    } else {
      std::cout << "Sie liebt mich nicht!" << std::endl;
    }
    

    Aber auf keinen Fall so wie

    int main()
    {
        int eingabe1 = 0;
        int eingabe2 = 0;
        int ergebnis = 0;
    

    , weil es tatsächlich so verwirrt, wie Arcoth sagt.
    Lieber machen wie volki,

    int main()
    {
        int eingabe1 = 42;
        int eingabe2 = 4711;
        int ergebnis = 0815;//uups, geht ja gar nicht
    

    damit man gleich sieht, daß man nur die Variablen aus irgend einem Grunde nicht gerade lokal hat und sie hier nur zu früh initialisiert (nämlich ohne sinnvollen Wert). Schlechtes Buch gelesen, noch mit 25 Jahren C benutzen oder sowas. Unfug sollte auch wie Unfug aussehen.



  • Arcoth schrieb:

    Atomare Datentypen

    Der Begriff ist seit C++11 mehrdeutig geworden. Siehe <atomic> . fundamental ist besser, glaube ich.

    Vielen Dank für die Anmerkung. Ich arbeite nicht mit dem neuen Standard, daher ist mir das alles etwas neu.

    Arcoth schrieb:

    Atomare Datentypen

    Und was genau ist eigentlich der Anlass zu deinem Post? In einigen Fällen sollten Variablen fundamentalen Typs nicht bei der Definition initialisiert werden (worauf du ja hinaus willst?*), weil das schon anderweitig passiert:

    int i = 0; 
    // Aha, Offenbar wird i gleich in irgendeiner Berechnung (Schleife?) verwendet und i's Wert wird vor der ersten Zuweisung benötigt.
    // […] (hier könnte etwas stehen dass die Definition von i und das folgende Statement trennt)
    std::cin >> i; // Huch? Hier wird i nochmal initialisiert, wozu also obige Initialisierung? Hab' ich glatt etwas übersehen?
    

    mMn verwirrend.

    * Wenn du darauf hinaus willst dass man Variablen irgendwie initialisieren muss: Das ist selbstverständlich. Mit völlig un-initialisierten Variablen kann man nicht viel machen. 🤡

    Ich wollte nur zur Aussage bringen, dass es sinnvoll ist es sich gleich anzueignen fundamentale Datentypen zu initialisieren. Hier wurde ein Code vorgestellt, der Fehler wurde gefunden. Allerdings eine allgemeine Anmerkung hat mir einfach gefehlt. Ich wollte es nur vervollständigen.

    Wie die Initialisierung statt findet per

    int i = 0;
    

    oder doch wie angesprochen

    int i; 
    std::cin >> i;
    

    ist ja egal.

    Bevor ich allerdings so etwas mache, um es mit "Unfug" (was allerdings im möglichen Ergebnisraum liegt) zu initialisieren, würde ich das Pattern "Optional" (vgl. Boost http://www.boost.org/doc/libs/1_56_0/libs/optional/doc/html/index.html) vorschlagen.

    int i = 42; /* die Lsg. auf alle Fragen ;) */
    

    versus

    Optional< int > i;
    

    So hat halt jeder sein Stil 🙂

    Vielen Dank für das Feedback.

    Wünsche ein tolles Wochenende.



  • jb2012 schrieb:

    Ich wollte nur zur Aussage bringen, dass es sinnvoll ist es sich gleich anzueignen fundamentale Datentypen zu initialisieren. Hier wurde ein Code vorgestellt, der Fehler wurde gefunden. Allerdings eine allgemeine Anmerkung hat mir einfach gefehlt. Ich wollte es nur vervollständigen.

    Wie volkard, arcoth und ich dir schon gesagt haben:

    Swordfish schrieb:

    Das ist nicht Der Fehler™.

    Der gute Rat zu diesem Thema ist, wenn auch etwas subtil, auch schon gegeben worden:
    Variablen so nah wie möglich an ihrem Verwendungsort deklarieren. Dadurch ergibt sich auch auf einen Blick, ob sie bei ihrer Deklaration auch (und womit) initialisiert werden müssen.


Anmelden zum Antworten