Ein einfacher Taschenrechner in C



  • Hallo, ich bin dabei meine ersten Programme in C zu programmieren und versuche gerade einen einfachen Taschenrechner zu programmieren, der neben den einfachen Operatoren + - * / auch die Potenzierung ^ berechnen soll. Bei der Potenzierung möchte ich nicht mit der pow-Funktion arbeiten, sondern selbst implementiern. Das Programm soll dann beendet werden, wenn der Benutzer als Operator # eingibt.

    Hier mein Quellcode:

    #include <stdio.h>
    
    main(){
           char zeichen[1];
           float gleitkommazahl1, gleitkommazahl2;
    
           while (1){
                 scanf ("%f", &gleitkommazahl1);
                 gets(zeichen);
                 scanf ("%f", &gleitkommazahl2);
           if (zeichen == '+') {
                  printf("\n\t%f\n", gleitkommazahl1 + gleitkommazahl2);
           }
           else if (zeichen == '-') {
                  printf("\n\t%f\n", gleitkommazahl1 - gleitkommazahl2);
           }
           else if (zeichen == '*') {
                  printf("\n\t%f\n", gleitkommazahl1 * gleitkommazahl2);
           }
           else if (zeichen == '/') {
                  printf("\n\t%f\n", gleitkommazahl1 / gleitkommazahl2);
           }
           else if (zeichen == '^') {
                  printf("\n\t%f\n", gleitkommazahl1 ^ gleitkommazahl2);
           }
           else if (zeichen == '#') {
                  printf("\n\tFertig\n");
                  break;
           }
           else
                  printf("\n\t Unbekannter Operator\n");
           system("PAUSE");
    }
    }
    

    Folgende Fehler zeigt der Compiler:

    Zeile 12: [Warning] comparison between pointer and integer
    Zeile 15: [Warning] comparison between pointer and integer
    Zeile 18: [Warning] comparison between pointer and integer
    Zeile 21: [Warning] comparison between pointer and integer
    Zeile 24: [Warning] comparison between pointer and integer
    Zeile 25: invalid operands to binary ^
    Zeile 27: [Warning] comparison between pointer and integer

    Zeile 25 vermute ich, dass er die Potenzierung nicht so direkt berechnen kann, aber wie soll man es sonst eingeben?
    Bei den anderen Fehlern handelt es sicherlich immerwieder um den Selben im If_else-Zweig. Aber wie ist es korrekt?



  • Gets gibt einen Nullterminierten-CString zurück, also musst du eher mit zeichen[0] arbeiten...alles ungetestet.

    EDIT:Beim Zeichenarray solltest du auch noch Platz für die binäre null lassen^^



  • auch mit zeichen [0] erscheinen die gleichen Fehler..



  • meinungsadler schrieb:

    Bei der Potenzierung möchte ich nicht mit der pow-Funktion arbeiten, sondern selbst implementiern.

    Und, wo ist deine Selbstimplementierung?
    Wenn es den Operator ^ diesbezüglich geben würde, wozu gäbe es dann pow?
    Auch die anderen Compilerwarnungen sind für dich gedacht, auch da machst du was falsch.
    Die Verwendung von gets ist Anfängerschrott.



  • Wutz schrieb:

    Und, wo ist deine Selbstimplementierung?

    Die fehlt leider. Ich müsste sicherlich nun eine Funktion, vor der Hauptfunktion, schreiben, worauf er später zugreift. Etwa so:

    potenzierung(float gleitkommazahl1, gleitkommazahl2;){
    float potenz=gleitkommazahl1 ^ gleitkommazahl2;
    }
    

    Glaube aber das funktioniert eben deshalb nicht, weil ^ gar nicht definiert ist 😃
    Wie kann man den die Potenzierung anders schreiben bzw. rechnen? Genau das ist ja meine Schwäche 😞 Das müsste doch auch ohne die POW-Funktion gehen; aber wie?

    Wutz schrieb:

    Auch die anderen Compilerwarnungen sind für dich gedacht, auch da machst du was falsch.

    Was genau. Gebe mir doch bitte einen winzigen Tipp..

    Wutz schrieb:

    Die Verwendung von gets ist Anfängerschrott.

    Ohne Fehler kann man nicht lernen. Also soll ich gets nicht verwenden, meinst du 🙂 Stattdessen eine stinknormale scanf vllt?



  • Ich habe jetzt

    gets(zeichen);
    

    durch

    scanf ("%s", &zeichen);
    

    ersetzt.

    Die Fehlermeldung sind immernoch dieselben. Was mache ich den falsch bei den If-Zweigen??



  • Alles was Eingaben ohne Längenprüfung macht ist halt extem unsafe.

    Hier so kannst du erstmal mit deinem Code weiterarbeiten:

    #include <stdio.h>
    #include <stdlib.h>
    
    main(){
           char zeichen[2];
           float gleitkommazahl1, gleitkommazahl2;
    
           while (1){
                 printf("float1=");
                 scanf ("%f", &gleitkommazahl1);
                 printf("op=");
                 scanf ("%s", zeichen);
                 printf("float2=");
                 scanf ("%f", &gleitkommazahl2);
           if (zeichen[0] == '+') {
                  printf("\n\t%f\n", gleitkommazahl1 + gleitkommazahl2);
           }
           else if (zeichen[0] == '-') {
                  printf("\n\t%f\n", gleitkommazahl1 - gleitkommazahl2);
           }
           else if (zeichen[0] == '*') {
                  printf("\n\t%f\n", gleitkommazahl1 * gleitkommazahl2);
           }
           else if (zeichen[0] == '/') {
                  printf("\n\t%f\n", gleitkommazahl1 / gleitkommazahl2);
           }
           else if (zeichen[0] == '^') {
    //              printf("\n\t%f\n", gleitkommazahl1 ^ gleitkommazahl2);
           }
           else if (zeichen[0] == '#') {
                  printf("\n\tFertig\n");
                  break;
           }
           else
                  printf("\n\t Unbekannter Operator\n");
           system("PAUSE");
    }
    }
    

    EDIT: Da war einer schneller^^



  • meinungsadler schrieb:

    auch mit zeichen [0] erscheinen die gleichen Fehler..

    Dann hast du es an der falschen Stelle eingesetzt.

    Was macht char zeichen[1]; ?
    Was ist '+'?
    Was kann das mit der Fehlermeldung [Warning] comparison between pointer and integer bei if (zeichen == '+') zu tun haben ?

    ^ ist etwas ganz anderes. ^ ist das binäre Exclusiv-Oder und demnach auch nur auf Ganzzahl möglich.

    gets ist offen für einen Bufferoverflow. Darum nimmt man fgets() mit stdin.



  • &internium
    Was ist an scanf ("%s", zeichen); besser als an gets(zeichen) ?
    Nichts!
    Denn die Länge wird auch nicht überprüft.



  • ich hab das mal ein bisschen kommentiert (bin selbst auch kein profi):

    #include <stdio.h>
    // du brauchst noch math.h, da sonst das mit dem "hoch" nicht funktioniert
    
    main() // es heißt "int main()" und NICHT "main()"
    {
           char zeichen[1]; // "char zeichen[1];" ist dasselbe wie "char zeichen;"
           float gleitkommazahl1, gleitkommazahl2;
    
           while (1){
                 scanf ("%f", &gleitkommazahl1);
                 gets(zeichen); // gets ist hier völlig fehl am platz.
                                // getchar ist hier besser
                 scanf ("%f", &gleitkommazahl2);
           if (zeichen == '+') {
                  printf("\n\t%f\n", gleitkommazahl1 + gleitkommazahl2); 
           }
           else if (zeichen == '-') {
                  printf("\n\t%f\n", gleitkommazahl1 - gleitkommazahl2);
           }
           else if (zeichen == '*') {
                  printf("\n\t%f\n", gleitkommazahl1 * gleitkommazahl2);
           }
           else if (zeichen == '/') {
                  printf("\n\t%f\n", gleitkommazahl1 / gleitkommazahl2);
           }
           else if (zeichen == '^') {
                  printf("\n\t%f\n", gleitkommazahl1 ^ gleitkommazahl2); // funktioniert nicht, da '^' in C nicht "hoch" bedeutet
                                                                         // du brauchst hier die funktion "pow()", die in math.h enthalten ist
           }
           else if (zeichen == '#') {
                  printf("\n\tFertig\n");
                  break;
           }
           else // hier besser klammern benutzen
           {
                  printf("\n\t Unbekannter Operator\n");
           }
           system("PAUSE");
           // "return 0;" fehlt
    }
    }
    

    das waren wohl die gröbsten fehler.

    komischerweise funktioniert das programm nicht richtig, auch wenn man alle fehler ausgebessert hat.

    lg



  • verbesserung schrieb:

    "char zeichen[1];" ist dasselbe wie "char zeichen;"

    Das ist ganz großer Unsinn 😮 .
    Wäre es so, hätte er nicht die Probleme.

    char zeichen[1]; ist ein Array mit einem Element und zerfällt bei Benutzung des Namens in den Pointer auf das Array.
    Darum brauchst du bei scanf und gets auch nicht das &. Und darum kannst du es auch nicht direkt mit '+' vergleichen.

    char zeichen; ist ein integraler Typ. Darum kannst du es auch mit '+' direkt Vergleichen.

    Entweder Array, dann aber immer Array. Auch beim Vergleich!
    Besser ist aber das einfach char oder besser noch int.



  • DirkB schrieb:

    &internium
    Was ist an scanf ("%s", zeichen); besser als an gets(zeichen) ?
    Nichts!
    Denn die Länge wird auch nicht überprüft.

    Ja du hast recht, ich habe es halt nur einheitlicher gemacht und es funktioniert so erstmal.



  • @dirkb
    für getchar braucht er kein array, da reicht ein zeichen.

    und so wie er das zu lösen versucht, funkioniert das nicht, da man mit dem == keine strings vergleichen kann.



  • p.s: natürlich kann er das zeichen auch mit scanf einlesen, dann braucht er halt "strcmp()" zum vergleichen.



  • DirkB schrieb:

    Was macht char zeichen[1]; ?

    Man muss immer ein Zeichen mehr beim char deklarieren, als man hat. Bei unserem Beispiel also für ein Zeichen: char zeichen[2]; ??

    DirkB schrieb:

    Was ist '+'?

    Wird diese Plus Zeichen als zwei Zeichen erkannt?

    DirkB schrieb:

    Was kann das mit der Fehlermeldung [Warning] comparison between pointer and integer bei if (zeichen == '+') zu tun haben ?

    Frei übersetzt heißt das ja: Vergleich zwischen Zeiger und ganze Zahl. Wie soll man denn durch diese Warnung auf den Fehler kommen, dass bei zeichen die [2] fehlt?

    DirkB schrieb:

    ^ ist etwas ganz anderes. ^ ist das binäre Exclusiv-Oder und demnach auch nur auf Ganzzahl möglich.

    Ok. Kann man das denn überhaupt ohne die pow-Funktion nicht machen? Gibt es eine Formel für Potenzierung, wie z.B beim Rest, wo man auch statt Modulo nur mit der Division klar kommt.??



  • verbesserung schrieb:

    @dirkb
    für getchar braucht er kein array, da reicht ein zeichen.

    und so wie er das zu lösen versucht, funkioniert das nicht, da man mit dem == keine strings vergleichen kann.

    [Loriot] Ach. [/Loriot]

    Du hast doch geschriebn: "char zeichen[1];" ist dasselbe wie "char zeichen;"
    Aber genau der Unterschied dazwischen macht die Probleme.



  • DirkB schrieb:

    verbesserung schrieb:

    @dirkb
    für getchar braucht er kein array, da reicht ein zeichen.

    und so wie er das zu lösen versucht, funkioniert das nicht, da man mit dem == keine strings vergleichen kann.

    [Loriot] Ach. [/Loriot]

    Du hast doch geschriebn: "char zeichen[1];" ist dasselbe wie "char zeichen;"
    Aber genau der Unterschied dazwischen macht die Probleme.

    da hast du micht wohl erwischt...

    warum benutzt ihr kein getchar, dann müsste es funktionieren.



  • meinungsadler schrieb:

    DirkB schrieb:

    Was macht char zeichen[1]; ?

    Man muss immer ein Zeichen mehr beim char deklarieren, als man hat. Bei unserem Beispiel also für ein Zeichen: char zeichen[2]; ??

    zeichen[1] ist ein Array mit einem Element. Das ist ziemlich Schwachsinnig. Bei deinen floats hast du das ja auch nicht gemacht.
    Arrays werden in C anders behandelt als einfache Typen.

    meinungsadler schrieb:

    DirkB schrieb:

    Was ist '+'?

    Wird diese Plus Zeichen als zwei Zeichen erkannt?

    Das ist ein Zeichen (Erkennbar an den einfachen Hochkommas) und damit ein Integer-Typ.

    meinungsadler schrieb:

    DirkB schrieb:

    Was kann das mit der Fehlermeldung [Warning] comparison between pointer and integer bei if (zeichen == '+') zu tun haben ?

    Frei übersetzt heißt das ja: Vergleich zwischen Zeiger und ganze Zahl. Wie soll man denn durch diese Warnung auf den Fehler kommen, dass bei zeichen die [2] fehlt?

    Das ist die falsche Schlussfolgerung.
    Entweder du nimmst bei Zeichen kein Array oder du vergleichst ein Element von dem Array. Z.B. zeichen[0] mit '+'

    meinungsadler schrieb:

    DirkB schrieb:

    ^ ist etwas ganz anderes. ^ ist das binäre Exclusiv-Oder und demnach auch nur auf Ganzzahl möglich.

    Ok. Kann man das denn überhaupt ohne die pow-Funktion nicht machen? Gibt es eine Formel für Potenzierung, wie z.B beim Rest, wo man auch statt Modulo nur mit der Division klar kommt.??

    Die pow-Funktion ist für die Potenzierung da. Da gibt es keine Kurzschreibweise.
    Wenn du das selber machen willst, mach eine Schleife und rechne darin mit *.
    Wird aber schwierig bei einem Fließkomme-exponenten.



  • @vergesserung:

    Es funktioniert doch, nicht auf Sicherheit gemünzt, aber das juckt einen Anfänger eh erstmal nicht, da es ums Grundverständnis geht und er einfach mal probieren will.

    So kann man den Nachwuchs auch zu PHP treiben^^



  • vergesserung schrieb:

    warum benutzt ihr kein getchar, dann müsste es funktionieren.

    Sooo einfach ist das auch wieder nicht. Das getchar würde erstmal das '\n' vom scanf einlesen.Ein scanf(%c, ) übrigens auch.

    Da muss man erstmal dein Eingabepuffer leeren.
    Wie man das machen kann steht: http://www.c-plusplus.net/forum/p1146014#1146014


Anmelden zum Antworten