JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=5aa2af54eab9820794b3016bbed45790Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Funktionsdeklaration wie sprintf()

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
C++Builder
Senior JLI'ler



Anmeldedatum: 04.10.2003
Beiträge: 235

Medaillen: Keine

BeitragVerfasst am: 04.02.2004, 18:04    Titel: Funktionsdeklaration wie sprintf() Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 04.02.2004, 18:42    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Florian
Super JLI'ler


Alter: 36
Anmeldedatum: 20.06.2003
Beiträge: 302

Medaillen: Keine

BeitragVerfasst am: 07.02.2004, 21:38    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden MSN Messenger
HotAcid
Super JLI'ler


Alter: 43
Anmeldedatum: 04.08.2002
Beiträge: 372
Wohnort: Berlin
Medaillen: Keine

BeitragVerfasst am: 08.02.2004, 08:47    Titel: Antworten mit Zitat

[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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
TheMillenium
Dark JLI'ler



Anmeldedatum: 21.07.2002
Beiträge: 1427
Wohnort: World
Medaillen: Keine

BeitragVerfasst am: 08.02.2004, 11:15    Titel: Antworten mit Zitat

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...Sad
_________________
The source of all power is in its destiny...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
HotAcid
Super JLI'ler


Alter: 43
Anmeldedatum: 04.08.2002
Beiträge: 372
Wohnort: Berlin
Medaillen: Keine

BeitragVerfasst am: 08.02.2004, 11:31    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Mr.X
Junior JLI'ler



Anmeldedatum: 15.04.2003
Beiträge: 88

Medaillen: Keine

BeitragVerfasst am: 08.02.2004, 12:55    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 08.02.2004, 17:55    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Mr.X
Junior JLI'ler



Anmeldedatum: 15.04.2003
Beiträge: 88

Medaillen: Keine

BeitragVerfasst am: 08.02.2004, 20:23    Titel: Antworten mit Zitat

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??? Wink



So, hoffe das kleine Missverständnis aus der Welt geschafft zu haben Smile
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
TheMillenium
Dark JLI'ler



Anmeldedatum: 21.07.2002
Beiträge: 1427
Wohnort: World
Medaillen: Keine

BeitragVerfasst am: 08.02.2004, 20:25    Titel: Antworten mit Zitat

@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..Wink
_________________
The source of all power is in its destiny...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Mr.X
Junior JLI'ler



Anmeldedatum: 15.04.2003
Beiträge: 88

Medaillen: Keine

BeitragVerfasst am: 08.02.2004, 20:28    Titel: ... Antworten mit Zitat

Mmh, jetzt muss ich doch mal nachschaun in der MSDN^^
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Mr.X
Junior JLI'ler



Anmeldedatum: 15.04.2003
Beiträge: 88

Medaillen: Keine

BeitragVerfasst am: 08.02.2004, 20:56    Titel: Antworten mit Zitat

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..Wink


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
Benutzer-Profile anzeigen Private Nachricht senden
TheMillenium
Dark JLI'ler



Anmeldedatum: 21.07.2002
Beiträge: 1427
Wohnort: World
Medaillen: Keine

BeitragVerfasst am: 08.02.2004, 22:48    Titel: Antworten mit Zitat

sry Embarassed

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 Wink
_________________
The source of all power is in its destiny...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
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

Impressum