[Novize] Warum stört ( ) bei dieser/m varg funktion/makro ?
-
Hey Leute,
Habe aus meinem Lehrbuch ein Beispiel für eine Funktion mit variabel vielen Argumenten abgeschrieben - und dann ausgeführt.
So sieht die Funktion aus wie im Buch:
double average(double v1, double v2,...) { va_list parg; double sum = v1 + v2; double value = 0; int count = 2; va_start(parg,v2); while((value = va_arg(parg, double)) != 0.0) { sum += value; count++; } va_end(parg); return sum/count; }
Das Ganze funktioniert bisweilen nur mit den mind. 2 Argumenten welche die Parameter v1 und v2 angeben - sobald ich einen dritten anfüge "average(x1,x2,x3)"
Dann wirds leider nichts - fehlerhaftes Ergebnis - bin Ganz zufällig auf die Lösung gestoßen welche folgende wäre:while(value = va_arg(parg, double) != 0.0)
Hier habe ich die Klammern um das Assignment weggelassen. Laut Buch funktioniert es auch mit - ich persönlich hätte es auch mit geschrieben. Inwiefern kann das Ganze nen Fehler bewirken? So gesehen mit oder ohne Klammern ist der Ablauf / Reihenfolge doch die Selbe.
Benutze GNU Gcc Compiler falls das an dem liegen sollte.
gruß Charlie
-
Ich bemerke gerade auch so kommen falsche Ergebnisse heraus - also egal wie ich es drehe
- daher lasse ich es mal bei dem Buch Beispiel und frage plump mal wo denn hier der FEhler nun liegt - habe den Quelltext mehrmals auf Tippfehler geprüft - nichts...
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdbool.h> #include <stdarg.h> double average(double v1, double v2,...); int main(void) { double x1 = 50; double x2 = 100; double x3 = 10; double x4 = 20; double x5 = 134; double result = 0; result = average(x1,x2,x3); printf("The average is = %.2lf", result); return 0; } double average(double v1, double v2,...) { va_list parg; double sum = v1 + v2; double value = 0; int count = 2; va_start(parg,v2); while((value = va_arg(parg, double)) != 0.0) { sum += value; count++; } va_end(parg); return sum/count; }
Hier nochmal das Komplette
-
Ich denke der Witz an der Sache ist, und da musst Du noch mal in Dein Buch schauen: das letzte Argument muss 0.0 sein.
Sonst wird das mit der Laufbedingung zuverlässig nie klappen.Also z.B.:
result = average(x1,x2,x3, 0.0);
-
würde "va_arg(parg, double)" nicht nach abfrage der ersten variable nicht auf die nächste zeigen - und falls da keine vorhanden ist 0 zurückgeben? somit wäre Value doch 0.0 ?
Er liest ja auch 0.0 im endeffekt sonst würde die while schleife ja zu keinem Ende kommen.
Aber Recht hast du - ich sehe gerade bei der implementierung in ein Programm wird als letztes Argument 0.0 gepasst - Hätte ich mal nicht auf eigene Faust versucht das Teil in ein Programm einzubinden
-
Falke88 schrieb:
würde "va_arg(parg, double)" nicht nach abfrage der ersten variable nicht auf die nächste zeigen - und falls da keine vorhanden ist 0 zurückgeben? somit wäre Value doch 0.0 ?
Er liest ja auch 0.0 im endeffekt sonst würde die while schleife ja zu keinem Ende kommen.
Ja, aber wo und wann?
Wenn da kein Argument mehr ist, oder das Argument nicht vom versprochenen Typ ist, ist das Verhalten (grundsätzlich) undefiniert:
ISO/IEC 9899:1999 schrieb:
If there is no actual next argument, or if type is not compatible with the type of the actual next argument (as promoted according
to the default argument promotions), the behavior is undefined,[...]
-
Falke88 schrieb:
würde "va_arg(parg, double)" nicht nach abfrage der ersten variable nicht auf die nächste zeigen - und falls da keine vorhanden ist 0 zurückgeben?
Nein, weil technisch gesehen immer eine nächste vorhanden ist (bis die Grenze des Speicherraumes erreicht ist jedenfalls). C weiss nicht, wieviele Argumente Du übergeben hast.
-
was ist denn das fuer ein buch?!
average(0,1,2) ist also 0... total daemliche funktion.
-
Absynth die Ohren schrieb:
was ist denn das fuer ein buch?!
average(0,1,2) ist also 0... total daemliche funktion.
Unterschätzen die Macht von
average()
Du tust.
-
Das Buch, aus dem die Funktion stammt, scheint meinem google-fu nach "Beginning C: From Novice to Professional" zu sein. Der Autor macht das in dem Buch prinzipiell auch richtig -- in seinem Beispielprogramm enden alle Parameterlisten mit 0.0, und er weist ausdrücklich darauf hin, dass die Funktion annimmt, dass alle Parameter ungleich Null sind und Null als Terminator erforderlich ist.
Natürlich ist Absynths Einwand korrekt, aber es geht ihm da auch weniger darum, eine allgemeine Durchschnittsfunktion zu entwickeln, als zu zeigen, wie Ellipsen funktionieren.