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 array

    wo 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: 4
    

    Mfg 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_y

    dann 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 kommt

    dann 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

    {=


Anmelden zum Antworten