Frage von uehcsxam, 56

Programmiersprache C - Verständnisproblem, Wer kann helfen?

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

Was tut diese Funktion, kann mir das jemand bitte umgangssprachlich erklären?

Danke im voraus!

Antwort
von TeeTier, 45

Der Name der Funktion deutet nicht gerade auf einen Anfänger hin, aber die Implementierung enthält mehrere dummen Fehler, was ein merkwürdiger Widerspruch ist. Naja egal ...

Im Großen und Ganzen soll die Funktion eine Dezimalzahl von der Eingabe einlesen, und das Ergebnis als Gleitpunktzahl zurück liefern.

Erstmal formatieren wir die Funktion vernünftig, und schreiben Zeilennummern vor die wesentlichen Zeilen:

1: double fnord (double v) {
2: int c = getchar();

3: if (c >= '0' && c <= '9') {
4: return fnord (v * 10 + (c = '0'));
}

6: ungetc(c, stdin);

7: return v;
}

Diese Funktion wird zum Beispiel wie folgt aufgerufen:

double d = fnord(0.0);

Dann gibt es zwei Möglichkeiten: A) wir tippen eine Zahl zwischen 0 und 9 ein, oder B) ein anderes Zeichen (ein Buchstabe, ein Zeilenende, oder irgendeine andere Nicht-Zahl).

Verhalten bei A: Wir geben z. B. eine '3' ein, welche in Zeile 2 eingelesen wird. Die Überprüfung in Zeile 3 ergibt "true", so dass der Zweig in Zeile 4 genommen wird. Zeile 4 multipliziert erst v mit 10, was bei unserem obigen Test 0.0 ergibt, da wir ja 0.0 als Startwert definiert haben. Danach wird der Variable, die das eben eingelesene Zeichen (also die "3") enthält auf das Zeichenliteral '0' gesetzt, und zur vorher erhaltenen Zahl 0.0 addiert. Der ASCII-Wert von '0' ist 48 dezimal (bzw. 0x30 hex), sodass als Endergebnis 68.0 zurück geliefert wird.

Aber das ist offensichtlich ein Fehler und korrekt wäre einfach nur die Addition von (c - '0') um die Zahl 3 als Integer zu erhalten, aber egal ...

Danach wird fnord() erneut rekursiv mit dem neuen Wert aufgerufen, (was hier zwar 48.0 ist, im korrekten Fall aber 3.0 sein sollte). Geben wir nun ein weiteres Zeichen ein, wird das ganze so oft widerholt, bis wir auf ein Nicht-Zeichen stoßen (zum Beispiel ein Zeilenende) ... siehe nächsten Punkt B!

Verhalten bei B: Wir geben ein ungültiges Zeichen ein, z. B. 'a' ein, oder erreichen das Ende der Zeile, was zum Überspringen des if-Zweiges führt, da die Bedingung "false" liefert. Das ungültige - eben eingelesene Zeichen - wird zurück in die Standardeingabe geschoben (sodass beim nächsten Leseaufruf eben wieder genau dieses Zeichen zurück geliefert wird), und unser Argument v (nach dem vorigen Durchgang A also 48.0, bzw. im fehlerfreien Fall 3.0) wird in unveränderter Form zurück geliefert.

Anmerkung: Im if-Zweig wird der Variable "c", wie bereits erwähnt, das Zeichenliteral '0' zugewiesen, was überhaupt keinen Sinn ergibt, und einem Profi so nicht unterlaufen würde, zumal so ziemlich jeder Compiler und jede IDE davor warnen würden.

Fazit: Die Funktion heißt "fnord", was ein beliebtes Wort oder auch ein running Gag unter IT-lastigen Beiträgen, Blogs oder allgemein unter Hackern ist (google mal nach der genauen Bedeutung!), allerdings deutet die Ausführung der Programmierung auf einen Anfänger hin:

- die Funktion erfordert zum korrekten Funktionieren immer einen Startwert 0.0

- die Funktion arbeitet durchweg mit double, obwohl ein int mit einem einzigen abschließenden Cast hier effizienter wäre

- der Variablen c wird ein Wert zugewiesen, obwohl sie danach nicht mehr benötigt wird (siehe nächster Kritikpunkt)

- der vorige Punkt mit der Zuweisung ist offensichtlich ein Fehler, da die Funktion so nicht korrekt arbeiten wird. Es ist definitiv eine Subtraktion und keine Zuweisung gemeint.

- die Funktion ist abhängig vom verwendeten Zeichensatz der Plattform, und nicht portabel

- es wird nicht auf Fehler überprüft, die im Falle von Pipes sehr wahrscheinlich auftreten werden.

- eine Überprüfung auf Überläufe findet nicht statt

- vor meiner Umformatierung enthielt der if-Zweig keine Klammerung ... kann man zwar machen, ist aber kein guter Stil.

Also dann ... deine Funktion liest eine Dezimalzahl von der Standardeingabe ein, und liefert diese als Gleitpunktwert. Ein vernünftiger Startwert von 0.0 wird vorausgesetzt. Alles in anderem aber erstens schlechter Stil, und fehlerhaft.

Wo hast du diese Funktion denn her? :)

Naja, schönen Abend noch! :)

Antwort
von spriday, 56

Sie gibt 2 Variablen wieder.

Kommentar von uehcsxam ,

Das ist mir bekannt, ich würde gerne wissen was mithilfe der einzelnen Zeilen passiert, also was sie bewirken.

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten