Benötige Hilfe - Wert wird nicht gespeichert.



  • Hi Leute habe eine Kurze Frage,
    habe ein Programm geschrieben, das eine einfache Kontoführung darstellt.
    Leider komme ich nicht auf die Idee, wie ich den eingegeben Wert speichern kann.
    Sprich ich möchte 100 EUR einzahlen und danach mir den Kontostand anzeigen lassen, gibt er mir als Kontostand 0 aus.

    Wollte eine Lösung ohne Array haben.

    Schonmal besten Dank im vorraus
    Gruß Niklas T.

    Hier der Code:

    #include <stdio.h> 
    #include <stdlib.h>
    
    // Funktion zum Einzahlen auf das Konto 
    void einzahlen(float betrag_einzahlen, float guthaben) 
    { 
        printf("\n\n Bitte geben Sie den gewuenschten Betrag ein, den Sie einzahlen moechten:"); 
        scanf("%f", &betrag_einzahlen); 
        guthaben = +betrag_einzahlen;
        printf(" Neuer Kontostand : %.2f Euro\n", guthaben); 
        return betrag_einzahlen;
    } 
    
    // Funktion zum Auszahlen vom Konto 
    void auszahlen(float betrag_auszahlen, float guthaben) { 
        printf("\n\n Bitte geben Sie den gewuenschten Betrag ein, den Sie abheben moechten:"); 
        scanf("%f", &betrag_auszahlen); 
        guthaben = -betrag_auszahlen; 
        if(guthaben < -2500) { 
            printf("\n (!)Ihr Konto ist nicht ausreichend gedeckt!\a"); 
        } 
        else { 
            printf("Neuer Kontostand: %.2f Euro\n", guthaben); 
        } 
        return auszahlen;
    } 
    // Funktion zum Abrufen des Kontostands 
    void kontostand(float guthaben) { 
        printf("\n\n Kontostand: %.f Euro\n", guthaben); 
    } 
    
    int main() { 
    
        char wiederholen; 
        float guthaben=0; 
        float betrag_einzahlen=0; 
        float betrag_auszahlen=0; 
        int auswahl; 
    
        do { 
        puts("Was moechten Sie tun?"); 
        puts("1 - Geld einzahlen"); 
        puts("2 - Geld auszahlen"); 
        puts("3 - Kontostand abfragen"); 
        puts("4 - Verlassen"); 
        printf("\n Waehlen Sie bitte eine Option zwischen 1-4: "); 
    
        do { 
            scanf("%i", &auswahl); 
    
            switch(auswahl) { 
            case 1: einzahlen(betrag_einzahlen, guthaben); 
                    break; 
            case 2: auszahlen(betrag_auszahlen, guthaben); 
                    break; 
            case 3: kontostand(guthaben); 
                    break; 
            case 4: printf("\n\n > Verlassen mit <ENTER>\n"); 
                    _getch(); 
                    return 0; 
                    break; 
            default:printf("\n (!) Bitte zwischen 1 - 4 waehlen: \a"); 
            } 
        } while(auswahl != 1 && auswahl != 2 && auswahl != 3 && auswahl != 4); 
        // Wird wiederholt bis 1-4 eingegeben wird 
        printf("\n ______________________________\n"); 
        printf("\n Bearbeitung fortsetzen? <j/n>"); 
        wiederholen=_getch(); 
        printf("\n ______________________________\n"); 
        }while (wiederholen=='j' || wiederholen=='J'); 
    
        return 0; 
    }
    


  • Beachte die Warnungen des Compilers.
    Behandele Warnungen wie Fehler.
    Behebe deren Ursache.
    Stell den Warnlevel sehr hoch ein.

    Werte (oder Variablen), die an eine Funktion als Parameter übergeben werden, sind in der Funktion lokal.
    Eine Änderung an deren Wert wirkt sich nicht auf die rufende Funktion aus.

    Ein return betrag_einzahlen; hat auch nur einen Effekt, wenn die Funktion mit Rückgabewert definiert ist und dieser Rückgabewert auch etwas zugewiesen wird.



  • guthaben = +betrag_einzahlen;
    

    Muss heißen:

    guthaben += betrag_einzahlen;
    
    guthaben = -betrag_auszahlen;
    

    Hier genauso.
    Gleiches gilt für OneNoob2Another

    while(auswahl != 1 && auswahl != 2 && auswahl != 3 && auswahl != 4);
    

    Das kannst du schreiben als:

    while (auswahl < 1 || auswahl > 4);
    


  • Hi,

    du solltest dich nochmal mit den Begriffen "call by value" und "call by reference" auseinander setzen.

    Bei deiner Funktion "einzahlen"/"auszahlen" übergibst du die Variable "guthaben" aus deiner main-Funktion als "value", d.h. diese Variable wird kopiert und die Funktion arbeitet dann auf der Kopie der Variable "guthaben" und verändert NICHT deine "guthaben" Variable aus der main-Funktion.

    Eine Lösung wäre da halt "call by reference" zu nutzen.

    void einzahlen(float betrag_einzahlen, float *guthaben)
    {
        printf("\n\n Bitte geben Sie den gewuenschten Betrag ein, den Sie einzahlen moechten:");
        scanf("%f", &betrag_einzahlen);
        *guthaben = +betrag_einzahlen;
        printf(" Neuer Kontostand : %.2f Euro\n", *guthaben);
        return betrag_einzahlen; // wieso machst du hier ein return von dem Betrag?
    }                            // Laut Funktionssignatur hat diese Funktion keine
                                 // Rückgabe (void)
    
    // Funktion zum Auszahlen vom Konto
    void auszahlen(float betrag_auszahlen, float *guthaben) {
        printf("\n\n Bitte geben Sie den gewuenschten Betrag ein, den Sie abheben moechten:");
        scanf("%f", &betrag_auszahlen);
        *guthaben = -betrag_auszahlen;    // hier ziehst du im übrgen den Betrag
                                          // schon vom guthaben ab, ohne vorher
                                          // geprüft zu haben, ob das Konto gedeckt
                                          // ist.
        if(*guthaben < -2500) {
            printf("\n (!)Ihr Konto ist nicht ausreichend gedeckt!\a");
        }
        else {
            printf("Neuer Kontostand: %.2f Euro\n", *guthaben);
        }
        return auszahlen;  // hier das gleiche ... void als Rückgabewert in der 
                           // Funktionssignatur ... wenn also nur ein ganz normales
                           // return;
                           // welches man bei void-Funktionen natürlich auch einfach
                           // weg lassen könnte
    } 
    
    // Bei dem Aufruf deiner Funktionen in der main-Funktion musst du demnach also
    // Zeiger übergeben:
    
    main()
    {
      // ...
            case 1: einzahlen(betrag_einzahlen, &guthaben);  // man beachte das &
                    break;
            case 2: auszahlen(betrag_auszahlen, &guthaben);  // man beachte das &
                    break; 
      // ...
    }
    


  • DirkB schrieb:

    Beachte die Warnungen des Compilers.
    Behandele Warnungen wie Fehler.
    Behebe deren Ursache.
    Stell den Warnlevel sehr hoch ein.

    Werte (oder Variablen), die an eine Funktion als Parameter übergeben werden, sind in der Funktion lokal.
    Eine Änderung an deren Wert wirkt sich nicht auf die rufende Funktion aus.

    Ein return betrag_einzahlen; hat auch nur einen Effekt, wenn die Funktion mit Rückgabewert definiert ist und dieser Rückgabewert auch etwas zugewiesen wird.

    Danke für die Antwort Dirk,
    nur kapiere ich jetzt nicht wie ich das dann machen kann, das der Betrag in guthaben gespeichert wird. kannst du mir eventuell genauer erklären oder meinen code an der gewissen Stelle bearbeiten ?



  • Hi One Noob,

    danke für die schnelle Antwort,
    habe es nun hinbekommen.

    Kanst du mir nur eventuell nochmal erklären, warum in den Funktionen ein * vor guthaben geschrieben werden muss ?

    OneNoob2Another schrieb:

    Hi,

    du solltest dich nochmal mit den Begriffen "call by value" und "call by reference" auseinander setzen.

    Bei deiner Funktion "einzahlen"/"auszahlen" übergibst du die Variable "guthaben" aus deiner main-Funktion als "value", d.h. diese Variable wird kopiert und die Funktion arbeitet dann auf der Kopie der Variable "guthaben" und verändert NICHT deine "guthaben" Variable aus der main-Funktion.

    Eine Lösung wäre da halt "call by reference" zu nutzen.

    void einzahlen(float betrag_einzahlen, float *guthaben)
    {
        printf("\n\n Bitte geben Sie den gewuenschten Betrag ein, den Sie einzahlen moechten:");
        scanf("%f", &betrag_einzahlen);
        *guthaben = +betrag_einzahlen;
        printf(" Neuer Kontostand : %.2f Euro\n", *guthaben);
        return betrag_einzahlen; // wieso machst du hier ein return von dem Betrag?
    }                            // Laut Funktionssignatur hat diese Funktion keine
                                 // Rückgabe (void)
    
    // Funktion zum Auszahlen vom Konto
    void auszahlen(float betrag_auszahlen, float *guthaben) {
        printf("\n\n Bitte geben Sie den gewuenschten Betrag ein, den Sie abheben moechten:");
        scanf("%f", &betrag_auszahlen);
        *guthaben = -betrag_auszahlen;    // hier ziehst du im übrgen den Betrag
                                          // schon vom guthaben ab, ohne vorher
                                          // geprüft zu haben, ob das Konto gedeckt
                                          // ist.
        if(*guthaben < -2500) {
            printf("\n (!)Ihr Konto ist nicht ausreichend gedeckt!\a");
        }
        else {
            printf("Neuer Kontostand: %.2f Euro\n", *guthaben);
        }
        return auszahlen;  // hier das gleiche ... void als Rückgabewert in der 
                           // Funktionssignatur ... wenn also nur ein ganz normales
                           // return;
                           // welches man bei void-Funktionen natürlich auch einfach
                           // weg lassen könnte
    } 
    
    // Bei dem Aufruf deiner Funktionen in der main-Funktion musst du demnach also
    // Zeiger übergeben:
    
    main()
    {
      // ...
            case 1: einzahlen(betrag_einzahlen, &guthaben);  // man beachte das &
                    break;
            case 2: auszahlen(betrag_auszahlen, &guthaben);  // man beachte das &
                    break; 
      // ...
    }
    


  • DeKlu schrieb:

    nur wenn ich dort ein & einfüge, sprich &guthaben); // man beachte das &

    gibt der compiler mir ein Fehler aus:

    In function 'main':
    [Error] incompatible type for argument 2 of 'einzahlen'
    [Note] expected 'float' but argument is of type 'float *'
    [Error] incompatible type for argument 2 of 'auszahlen'
    [Note] expected 'float' but argument is of type 'float *'
    recipe for target 'main.o' failed

    Du musst auch den Parameter der Funktion ändern.



  • DeKlu schrieb:

    Hi One Noob,

    danke für die schnelle Antwort,
    habe es nun hinbekommen.

    Kanst du mir nur eventuell nochmal erklären, warum in den Funktionen ein * vor guthaben geschrieben werden muss ?

    http://lmgtfy.com/?q="call+by+value"+und+"call+by+reference"

    oder kurz ...
    du übergibst dann in deiner Funktion keine float Variable mehr, sondern einen Zeiger auf eine float Variable!
    Wenn du Zeiger noch nicht kennst, dann lies erstmal in Ruhe dein Buch weiter (falls du mit einem Buch arbeitest, was man nur empfehlen kann. Einfach mal in die FAQ schauen, welche Bücher empfohlen werden, falls du noch keins hast und dir noch eins kaufen/ausleihen willst).



  • OK super!

    Besten Dank für die super schnelle Hilfe,

    nun funktioniert mein Programm wie ich es mir vorgestellt habe...

    OneNoob2Another schrieb:

    DeKlu schrieb:

    Hi One Noob,

    danke für die schnelle Antwort,
    habe es nun hinbekommen.

    Kanst du mir nur eventuell nochmal erklären, warum in den Funktionen ein * vor guthaben geschrieben werden muss ?

    http://lmgtfy.com/?q="call+by+value"+und+"call+by+reference"

    oder kurz ...
    du übergibst dann in deiner Funktion keine float Variable mehr, sondern einen Zeiger auf eine float Variable!
    Wenn du Zeiger noch nicht kennst, dann lies erstmal in Ruhe dein Buch weiter (falls du mit einem Buch arbeitest, was man nur empfehlen kann. Einfach mal in die FAQ schauen, welche Bücher empfohlen werden, falls du noch keins hast und dir noch eins kaufen/ausleihen willst).


Anmelden zum Antworten