ich versteh das nicht [Petzold]
-
mahlzeit
in dieser funktion MessageBoxPrintf aus dem buch von petzold S 42 - werden die pixelmasse geholt und ausgegeben
das in csScreen und cyScreen dann die maße stehen ist mir schon klar, nur durch die anweisung
_vsntprintf_s( szBuffer, sizeof( szBuffer ) / sizeof( TCHAR ), szFormat, pArgList );
wird aus "Ihr Desktop hat eine Hoehe von %i und eine Breite von %i Pixeln" ein neuer satz mit den maßen, ich versteh aber nicht wie die zahlen an der position von %i kommen
#include "windows.h" #include "tchar.h" #include "stdio.h" int CDECL MessageBoxPrintf( TCHAR * szCaption, TCHAR * szFormat, ... ) { TCHAR szBuffer[1024]; va_list pArgList; va_start( pArgList, szFormat ); _vsntprintf_s( szBuffer, sizeof( szBuffer ) / sizeof( TCHAR ), szFormat, pArgList ); va_end( pArgList ); return MessageBox( NULL, szBuffer, szCaption, 0 ); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow ) { int cxScreen, cyScreen; cxScreen = GetSystemMetrics( SM_CXSCREEN ); cyScreen = GetSystemMetrics( SM_CYSCREEN ); MessageBoxPrintf( TEXT( "PixelMasse" ), TEXT( "Ihr Desktop hat eine Hoehe von %i und eine Breite von %i Pixeln" ), cxScreen, cyScreen ); return 0; }kann mir das jemand bitte erklaeren ? ich hab auch mit dem debugger alles durchgeschaut, nur in der main und in cyScreen sowie cxScreen sind die masse enthalten bis die printf anweisung abgearbeitet wird
im buch steht das ich das so unbeachtet lassen soll - also diese funktion, aber ich moechte das verstehen
was mir auch neu ist ist das man "..." als argumente machen kann ? in MessageBoxPrintf werden die masse am ende uebergeben aber in der funktion wird nur ... angenommen - wenn ich dort int x und int y mach geht das auch aber aendert nichts daran das die zahlen korrekt nach %i kommen -
vielen dank
-
Das ist eher eine Frage zu Standard C.
Das mit der Ellipse (...) bedeutet, dass die Funktion unbekannt viele Parameter übernimmt.
Im Falle von der print Funktion ist es dann so, dass im ersten Parameter ein String übergeben wird, der dann in der Funktion untersucht wird.
Buchstabe für Buchstabe wird angeschaut, und wenn die Funktion beispielsweise auf ein %d trifft, dann weiß sie, dass sie sich den nächsten Parameter vom 'Stapel' ziehen soll und damit das %d ersetzen soll, wobei es als Ganzahl gedeutet werden soll.Sieh mal rechts oben in der Ecke da. Da hast du Tutorials zu C und C++.
Die meisten deutschen sind nicht so der Bringer, aber zum Beispiel die beiden
"Thinking in C++" E-Bücher sind sehr empfehlenswert.
Auch als Nachschlagewerk.
-
hmm
diese ueberlegung macht die sache schon logischer
_vsntprintf_s untersucht den string nach sonderzeichen - stoesst auf %i {i fuer int} und nimmt dann ne zahl vom stack - und dann die naechste usw - wenn noch ein %i auftauchen wuerd waer ein fehler dann denk ich
was ich aber nicht versteh
TCHAR szBuffer[1024]; <-- das ist im prinzip das ziel des neuen strings
va_list pArgList; <-- was passiert hier - beinhaltet pArgsList automatishc alles was uebergeben wurde ?
und va_list ist ein typedef fuer "char *" also ein zeiger auf ein char arraywo ist der stack - ist pArgsList der stack ? wenn ja wie kommen die werte dort hinein ? entsteht das automatisch bei der ueberhabe der argumente an die funktion ?
so siehts bestimmt aus
_vsntprintf_s( szBuffer, sizeof( szBuffer ) / sizeof( TCHAR ), szFormat, pArgList );
_vsntprintf_s( "", 1024, "Ihr Desktop hat eine Hoehe von %i und eine Breite von %i Pixeln", (stack - X - Y) );so wuerde das alles auch sinn ergeben, aber wie gesagt, wie kommen die werte auf dem stack, und ist va_list die deklaration des stacks ?
edit: im buch steht das bei va_start die adresse des ueber dem szFormat auf dem stack liegt
nur wie kommen die werte da auf den stack darueber ?
-
Mr Evil schrieb:
hmm
diese ueberlegung macht die sache schon logischer
_vsntprintf_s untersucht den string nach sonderzeichen - stoesst auf %i {i fuer int} und nimmt dann ne zahl vom stack - und dann die naechste usw - wenn noch ein %i auftauchen wuerd waer ein fehler dann denk ich
Ganz so ist es nicht. Jedes %i steht für einen Integer. Das heißt, wenn du 5mal %i schreiben würdest, müsstest du auch 5 Integer angeben. Besipiel an sprintf (vom Prinzip her das gleiche):
sprintf (AusgabeBuffer, "Zahl1: %i; Zahl2: %i; Zahl3: %i; Zahl4: %i", zahl1, zahl2, zahl3, zahl4);Wenn jetzt zahl1 eins und zahl2 zwei und zahl3 drei und zahl4 vier wäre, dann würde AusgabeBuffer folgendes enthalten:
Zahl1: 1; Zahl2: 2; Zahl3: 3; Zahl4: 4Mfg Ominion
-
aaaaaaah cih glaub ich habs
beim uebergeben werden die werte uebergeben und auch die zeilen, das sieht im speicher dann uebereinander so aus
zeile_a
zeile_b
zahl_x
zahl_ydann wird mit va_list ein stack pArgList erstellt
und bei va_start( pArgList, zeile_b ); wird gesagt, "packe alles auf dem stack was nach zeile_b kommtdann liegt das auf dem stack pArgList
die funktion _vsntprintf_s ueberprueft dann zeile_b nach sonderzeichen und ersetzt diese mit dem inhalt vom stack, welches bekanntlich beim holen {pop} immer entfernt wird, dh erst zahl_x zugeweisen und weg vom stack dann zahl_y geholt und der stack ist leer
{=