Ich versteh diesen Code nicht



  • Weiß wer was dieser code macht?

    double fnord(double v){
    	int c=getchar();
    	if(c>='0'&&c<='9')return fnord(v*10+(c-'0'));
    	ungetc(c,stdin);
    	return v;
    }
    

    Auf jeden fall wird ein wert von der standardeingabe eingelesen. Aber da fängt das problem schon an bei mir. Was bedeutet denn

    c>='0'&&c<='9'
    

    Also wofür sind denn die ''? Ich hätte jetzt gedacht wenn der eingegebene wert größer gleich 0 und kleiner gleich 9 ist, dann ist die bedingung erfüllt, aber dann könnte man doch auch

    c>=0&&c<=9
    

    schreiben.

    Und dann bei dem

    return fnord(v*10+(c-'0'))
    

    weiß ich auch nicht was denn jetzt das v sein soll. Und augenscheinlich ist '0' != 0, denn c-0 hätte ja keinen effekt. Vermutlich ist mit '0' dann 48 gemeint (ascii)? Und wenn z.b. c='3' ist (was dann wohl 51 ist), dann wird halt 51-48 gerechnet, was dann ja gleich 3 ist. Aber davor steht ja noch v*10, aber woher soll ich wissen was v ist.

    Und ungetc weiß ich auch nicht was das ist.

    Kann das jemand verständlich erklären (bin ein totaler noob, wenn geht kein fachchinesisch? thx.



  • In ' faßt man Zeichen ein. Z.B. 'A' oder '@' oder Ziffern wie '1'.

    Das ZEichen für 1 hat (in den allermeisten Fällen) nicht den Wert 1 sondern ist codiert.
    Häufig wird ASCII genommen.

    Es wird also überprüft, ob das Zeichen, das eingelesen wird, eine Ziffer ist.

    Da die Zeichen für die Ziffern aufeinanderfolgen, ergibt das c-'0' den Wert für die Ziffer.
    '1'-'0' ist 1; '9'-'0' ist 9.
    Dioe Funktion wird rekursiv aufgerufen.

    ungetc stellt das Zeichen wieder in den Eingabestrom zurück, damit eine andere Funktion dieses wieder einlesen kann.

    Angenommen, die Funktion wird mit v=0 aufgerufen und du gibst eine '1' ein.
    Dann ruft sich die Funktion mit 010+1 = 1 selber wieder auf. (das gibt eine neue Instanz)
    In der neuen Instanz gibst du dann eine '8' ein.
    Dann ruft sich die Funktion mit 1
    10+8 = 18 selber wieder auf. (das gibt eine neue Instanz)
    Dann gibst du ein 'A' ein. Das 'A' wird zurückgestellt und die Funktion verlassen.
    In der übergeordneten Instanz steht vor dem Aufruf auch ein return, so dass immer der letzte Wert zurückgegeben wird.

    Als Ergebnis kommt dann 18 raus.

    NAch den fetten Wörtern kannst du googeln.



  • Ok, aber wozu ist die funktion dann gut? hat die irgendeinen sinnvollen nutzen?

    Und wenn in der bedingung c>='0' und c<='9' nicht an sich der wert 0 bis 9 gemeint ist, dann muss das was eingelesen wird, ja doch zwischen 48 und 57 liegen damit die bedingung erfüllt wird (weil ja ints eingelesen werden und keine chars, und der int wert von 0 ist ja vllt 48 anhand der ascii tabelle).

    und was ich irgendwie auch komisch finde ist, dass die funktion ja offentsichtlich ein double als argument haben will. Aber in der zeile mit
    fnord(v*10+(c-'0')
    ist zwar v ein double wert wenn man mit 0.0 z.b. anfängt, aber dann wird ja darauf ja ein int wert addiert? Denn wenn ich z.b. eine 50 eingebe als c, wird ja 50-48=2 gerechnet (bzw. '2'-'0'=2). Ich weiß nicht ob das ein problem ist, aber irgendwie funktioniert das programm bei mir sowieso nicht so richtig, wenn ich es so aufschreibe

    #include<stdio.h>
    double fnord(double v){
    	int c=getchar();
    	if(c>='0'&&c<='9')return fnord(v*10+(c-'0'));
    	ungetc(c,stdin);
    	return v;
    }
    
    int main(){
    	double n=0.0;
    	fnord(n);
    	printf("Nach Anwendung durch fnord: %f",fnord(n));
    	return 0;
    }
    

    und ich versteh ohnehin nicht den sinn von dem ding...



  • da kümmert sich der compiler drum. wenn du z.b. schreibst

    int x=5;
    double y=12.345;
    
    y=y+x;
    

    dann erkennt der compiler das, wandelt x in double um (sogenannter impliziter typecast), rechnet das aus und du erhälst als (richtiges) ergebnis 17.345.

    wofür deine Funktion gut ist: keine ahnung. du drückst eine taste und wenn es eine der zifferntasten 0 - 9 ist, führt sie eine rechnung durch, ansonsten gibt sie das bisherige ergebnis zurück.



  • kenplan schrieb:

    (weil ja ints eingelesen werden und keine chars,

    Wie kommst du zu der Annahme?
    Die Funktion heißt getchar . Sie gibt zwar ein int zurück, was nichts macht, da int eine Obermenge von char ist.

    kenplan schrieb:

    aber irgendwie funktioniert das programm bei mir sowieso nicht so richtig, wenn ich es so aufschreibe

    Du rufst die Funktion ja auch zweimal auf.

    int main(){
        double n=0.0;   
        fnord(n); //hier wertest du den Rückgabewert nicht aus
        printf("Nach Anwendung durch fnord: %f",fnord(n));
        return 0;
    }
    

    Du kannst auch

    int main(){
        double n=0.0; 
        double e;  
        e = fnord(n);
        printf("Nach Anwendung durch fnord: %f",e);
        return 0;
    }
    

    Nach dem Aufruf von fnord steht ein Zeichen im Eingabestrom, mit dem fnord nichts anfangen kann.
    Darum funktioniert der direkte Aufruf hintereinander nicht.


Anmelden zum Antworten