|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
C++Builder Senior JLI'ler
Anmeldedatum: 04.10.2003 Beiträge: 235
Medaillen: Keine
|
Verfasst am: 04.02.2004, 18:04 Titel: Funktionsdeklaration wie sprintf() |
|
|
hi leuts,
ich hab in meinen Projekten haufenweise Fehler drinne und will um die Fehler zu begrenzen und zu wissen was überhaupt der Fehler ist ne Protokoll Klasse schreiben die mit ner Funktion add() was ans Ende der Protokolldatei anhängt. Das ist an sich nicht nicht schwer und funktioniert auch schon.
Doch wenn jetzt eine Variable einen Wert hat der nicht zulässig ist möchte ich das protokollieren und den fehlerhaften Wert mit angegeben. Deswegen will ich der add-Funktion das übergeben wie bei sprintf(), sodass ich nicht erst sprintf() aufrufen muss und ne string-Variable deklarieren muss.
Aber wie deklariert man so eine Funktion die eine unbestimmte Menge an Parametern hat?? |
|
Nach oben |
|
|
Fallen JLI MVP
Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 04.02.2004, 18:42 Titel: |
|
|
Hier ein Beispiel aus der MSDN:
Code: | int average( int first, ... )
{
int count = 0, sum = 0, i = first;
va_list marker;
va_start( marker, first );
while( i != -1 )
{
sum += i;
count++;
i = va_arg( marker, int);
}
va_end( marker );
return( sum ? (sum / count) : 0 );
} |
Damit wird der Durchschnitt von einigen Zahlen berechnet.
(zu finden unter Suche: va_list) _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
|
Florian Super JLI'ler
Alter: 36 Anmeldedatum: 20.06.2003 Beiträge: 302
Medaillen: Keine
|
Verfasst am: 07.02.2004, 21:38 Titel: |
|
|
hallo ich wollte das auch mal probieren aber ich kann mit dem Beispiel leider nichts anfangen vieleicht hat jemand ein leichteres beispiel mit
Deutsch kommentare
Danke im Voraus |
|
Nach oben |
|
|
HotAcid Super JLI'ler
Alter: 43 Anmeldedatum: 04.08.2002 Beiträge: 372 Wohnort: Berlin Medaillen: Keine
|
Verfasst am: 08.02.2004, 08:47 Titel: |
|
|
[quote="FallenAngel84"]Hier ein Beispiel aus der MSDN:
Code: |
return( sum ? (sum / count) : 0 );
|
[quote]
Ich empfehel, stattdessen
Code: |
return( count ? (sum / count) : 0 );
|
zu benutzen, da doch geprüft werden soll, ob durch 0 geteilt wird...
@Florian:
wo ist denn dein Problem mit dem Beispiel? einfacher geht es eigentlich nicht mehr wirklich...
mit (int first,...) gibst du an, dass du eine variable Zahl Argumente hast. mit einer va_list kannst du durch die Argumente laufen. Bekommst du -1 als Argument, ist die Liste zuende.
viele Grüße
Felix _________________ StGB §§ 328 Abs. 2 Pkt 3:
Mit Freiheitsstrafe bis zu fünf Jahren oder mit Geldstrafe wird bestraft, wer eine nukleare Explosion verursacht. |
|
Nach oben |
|
|
TheMillenium Dark JLI'ler
Anmeldedatum: 21.07.2002 Beiträge: 1427 Wohnort: World Medaillen: Keine
|
Verfasst am: 08.02.2004, 11:15 Titel: |
|
|
ich frag mich auch, ob es noch ein besseres Beispiel gibt. Denn ich finde es doof, dass man dann der Funktion nicht -1 übergeben kann, weil dann alle Argumente nach -1 nicht mehr beachtet werden... _________________ The source of all power is in its destiny... |
|
Nach oben |
|
|
HotAcid Super JLI'ler
Alter: 43 Anmeldedatum: 04.08.2002 Beiträge: 372 Wohnort: Berlin Medaillen: Keine
|
Verfasst am: 08.02.2004, 11:31 Titel: |
|
|
das stimmt natürlich, das ist schon etwas ungünstig. Man könnte natürlich als Parameter "unsigned int" benutzen...
viele Grüße
Felix _________________ StGB §§ 328 Abs. 2 Pkt 3:
Mit Freiheitsstrafe bis zu fünf Jahren oder mit Geldstrafe wird bestraft, wer eine nukleare Explosion verursacht. |
|
Nach oben |
|
|
Mr.X Junior JLI'ler
Anmeldedatum: 15.04.2003 Beiträge: 88
Medaillen: Keine
|
Verfasst am: 08.02.2004, 12:55 Titel: |
|
|
Das Beispiel aus der MSDN ist ungünstig gewählt, eben weil da ein bestimmter Wert eines Parameters als Abbruchbedingung genommen wird.
Man sollte seiner Funktion immer als ersten Parameter übergeben, wieviele Argumente/Parameter folgen. Bei den ganzen printf()-Funktionen ist es auch so, nur indirekt.
Mal nen etwas anderes Beispiel:
Code: |
double mittel(int anzahl, ...)
{
double summe = 0;
va_list ap;
va_start(ap, anzahl);
for(int loop=1;loop<=anzahl;loop++) summe += va_arg(ap,int);
va_end(ap);
return summe/anzahl;
} |
@C++Builder
Mal nen kleiner Denkanstoss zu den printf()-Funktionen:
Diese bekommen immer einen Pointer auf einen String übergeben! (-->const char* szString)
Durch diesen erhälst Du indirekt die Anzahl Argumente, welche diesem Pointer in der Parameterliste folgen.
Du brauchst eine Schleife!
Und zwar musst Du durch diesen String durchlaufen und "%"-Zeichen suchen. Folgt z.B. ein "d" auf solch ein "%", dann bedeutet das schonmal ein zusätzlicher Parameter, um genau zu sein, ein Integer-Wert als nächster Parameter. Auf diesen kannst Du zugreifen durch va_arg(ap, int). Hätte anstelle des "d" ein "s" gestanden, wäre der entsprechende Parameter natürlich so zu interpretieren va_arg(ap, char*), da es sich hier um einen weiteren String(=Pointer auf char-Array) handelt.
Und so weiter. Alle Arten von Feldzeichen-Typen "%x" findest Du in der MSDN.
Wenn Du am Ende des Strings (=erster Parameter) angekommen bist, sowie alle bis dahin aufgetretenen "%x" behandelt hast, dann weisst Du, das keine Parameter mehr folgen.
P.S. Um Die hilfreichen Makros va_arg, va_start, va_end und die Struktur va_list nutzen zu können, musst Du natürlich noch <stdarg.h> inkludieren. |
|
Nach oben |
|
|
Fallen JLI MVP
Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 08.02.2004, 17:55 Titel: |
|
|
Tjo was soll ich sagen er wollte wissen wie man das macht und ich habe ein konkretes und ausreichendes Beispiel gepostet, was ihr damit anfangt ist mir ehrlich gesagt egal :/
@HotAcid: ehrlich gesagt habe ich mir da auch ein wenig gedanken gemacht, aber was solls. _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
|
Mr.X Junior JLI'ler
Anmeldedatum: 15.04.2003 Beiträge: 88
Medaillen: Keine
|
Verfasst am: 08.02.2004, 20:23 Titel: |
|
|
FallenAngel84 hat Folgendes geschrieben: | Tjo was soll ich sagen er wollte wissen wie man das macht und ich habe ein konkretes und ausreichendes Beispiel gepostet, was ihr damit anfangt ist mir ehrlich gesagt egal :/... |
Ich glaube Du hast meinen Satz mit dem "...das Beispiel aus der MSDN ist ungünstig gewählt..." missverstanden.
Meine Aussage bezog sich nicht darauf, das Du dieses Beispiel hier gepostet hast, sondern das dieses Beispiel im MSDN ungünstig gewählt wurde.
Also die Leute, welche diesen Artikel im MSDN verfasst haben, bewahren mit Ihrem Beispiel nich gänzlich vor Fehlern.
Denn:
Was ist, wenn man die Beispiel-Funktion nutzt, ohne irgendeinen Parameter = -1 zu übergeben???
So, hoffe das kleine Missverständnis aus der Welt geschafft zu haben |
|
Nach oben |
|
|
TheMillenium Dark JLI'ler
Anmeldedatum: 21.07.2002 Beiträge: 1427 Wohnort: World Medaillen: Keine
|
Verfasst am: 08.02.2004, 20:25 Titel: |
|
|
@Mr.X:
Ich glaube du hast das falsch verstandne. Man muss nicht dem letzten Parameter -1 übergeben, sondern die Funktion weißt der Variablen -1 zu, wenn es keine Parameter mehr gibt.. _________________ The source of all power is in its destiny... |
|
Nach oben |
|
|
Mr.X Junior JLI'ler
Anmeldedatum: 15.04.2003 Beiträge: 88
Medaillen: Keine
|
Verfasst am: 08.02.2004, 20:28 Titel: ... |
|
|
Mmh, jetzt muss ich doch mal nachschaun in der MSDN^^ |
|
Nach oben |
|
|
Mr.X Junior JLI'ler
Anmeldedatum: 15.04.2003 Beiträge: 88
Medaillen: Keine
|
Verfasst am: 08.02.2004, 20:56 Titel: |
|
|
TheMillenium hat Folgendes geschrieben: | @Mr.X:
Ich glaube du hast das falsch verstandne. Man muss nicht dem letzten Parameter -1 übergeben, sondern die Funktion weißt der Variablen -1 zu, wenn es keine Parameter mehr gibt.. |
so, hab jetzt einfach mal das Beispiel aus der MSDN hergenommen und ausprobiert!
Ergebnis:
Code: |
#include <stdio.h>
#include <stdarg.h>
int average( int first, ... )
{
int count = 0, sum = 0, i = first;
va_list marker;
va_start( marker, first );
while( i != -1 )
{
sum += i;
count++;
i = va_arg( marker, int);
}
va_end( marker );
return( sum ? (sum / count) : 0 );
}
int main()
{
printf("%d",average(3,3,3,3,6,6,6,-1));
return 0;
}; |
Ausgabe: 4
Jetzt die Funktion folgendermaßen aufgerufen:
Code: |
printf("%d",average(3,3,3,3,-1,6,6,6,-1));
|
Ausgabe: 3
Is ja auch klar, da nun schon eine -1 eher kommt!
ABER:
folgender Aufruf ohne Parameter = -1:
Code: |
printf("%d",average(3,3,3,3,6,6,6));
|
Ausgabe: 23790282
Eindeutig wird keine -1 zugewiesen, wenn keine Parameter mehr folgen!
Und um genau zu sein^^,
va_arg ist keine Funktion, die irgendeinen Wert zuweist, sondern ein Makro, welches den Pointer weiterschiebt und referenziert, um an den Wert (also den nächsten Parameter) zu kommen.
Wenn denn nun keine -1 als Parameter übergeben wird, so liesst die average-Funktion munter weiter im Speicher aufgrund der while-Schleife. Das einzigste was mich nur noch wundert ist, warum das Programm in diesem Falle keinen Laufzeitfehler verursacht.
(Anscheinend muss vor dem Funktionsaufruf irgendwann einmal eine -1 auf dem Stack landen, ist aber nur eine Vermutung. Auf jeden Fall wird die while-Schleife abgebrochen, bevor der "marker" seinen Gültigkeitsbereich verlässt, was ja den Laufzeitfehler sonst verursachen würde)
[Edit]
Nachtrag:
In der MSDN steht außerdem explizit zum MSDN-Beispiel: "...(-1 is used as terminator)..."
[/Edit] |
|
Nach oben |
|
|
TheMillenium Dark JLI'ler
Anmeldedatum: 21.07.2002 Beiträge: 1427 Wohnort: World Medaillen: Keine
|
Verfasst am: 08.02.2004, 22:48 Titel: |
|
|
sry
hab das MSDN Beispiel auch gar nicht (gelesen)...hab aber eine Idee um das Problem lösen zu können..muss nur ausprobieren ob das funktioniert dann sag ich bescheid _________________ The source of all power is in its destiny... |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|