Zum Inhalt springen

Welcher Wert gibt %d aus?


Crash2001

Empfohlene Beiträge

Ich will jetzt nicht drauf schwören, ob zusammengesetzte Strings zum Standard gehören, aber eigentlich sollte dieser Funktionsaufruf bis auf die fehlden Klammer legal sein: immerhin ist der erste Parameter von printf() ja ein `const char*', der lediglich aus mehreren `const char*'s zusammengesetzt ist.

Genauso wie folgendes Code-Fragment:

const char * const myStr = "Bugs " "Bunny";

printf("%s\n", myStr);

Soweit ich weiss haben die gcc-Bauer mal ein Statement über zusammengesetzte Strings abgeben (leider kann ich es nicht mehr finden).

Jedenfalls scheint sich gcc (2.95.2) im ANSI-Modus nicht darüber zu beschweren.

Link zu diesem Kommentar
Auf anderen Seiten teilen

<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR>Original erstellt von Shadax:

<STRONG>Ich will jetzt nicht drauf schwören, ob zusammengesetzte Strings zum Standard gehören, aber eigentlich sollte dieser Funktionsaufruf bis auf die fehlden Klammer legal sein: immerhin ist der erste Parameter von printf() ja ein `const char*', der lediglich aus mehreren `const char*'s zusammengesetzt ist.

Genauso wie folgendes Code-Fragment:

const char * const myStr = "Bugs " "Bunny";

printf("%s\n", myStr);

Soweit ich weiss haben die gcc-Bauer mal ein Statement über zusammengesetzte Strings abgeben (leider kann ich es nicht mehr finden).

Jedenfalls scheint sich gcc (2.95.2) im ANSI-Modus nicht darüber zu beschweren.</STRONG>

Link zu diesem Kommentar
Auf anderen Seiten teilen

@crash2001

OK, printf nimmt als Parameter genau einen const char*. Dieser enthält u.U. bestimmte Zeichenfolgen, die veranlassen, daß die Werte weiterer Variablen oder Konstanten an der entsprechenden Stelle in den String eingefügt werden.

Alle Parameter werden durch Kommata getrennt. Die speziellen Formatzeichenfolgen werden immer durch ein '%' eingeleitet. Dabei korrespondieren diese mit den entsprechenden Variablen, das erste %x mit der ersten Variable usw.

'%d' bedeutet, daß hier der wert einer ganzzahligen Variable/Konstante eingefügt werden soll.

Ellipsenfunktionen haben nun die Eigenschaft, daß die Parameter als variable Liste vorliegen, wenn du jetzt versuchst, auf mehr Adressen zuzugreifen, al du in der Liste repräsentiert hast, wird dein Programm *irgendwo* lesen. Das dabei *irgendetwas* herauskommt, liegt auft der Hand, denn *irgendwo* muß ja nicht zwingend der Inhalt einer ganzzahligen Variablen stehen. Beim lesen gibt's übrigens noch nicht soviel Theater wie beim Schreiben, gelle :-)

Klar soweit?

Dein Aufruf müßte also so lauten:


printf("J hat den Dezimal-Wert %d \nI hat den Dezimal-Wert %d \n", j, i);

Für andere Datentypen gibt es noch eine ganze Anzahl weiterer Zeichenfolgen, man kann Anzahl der Nachkommastellen, Exponentialdarstellung uvm. veranlassen.

auch @hasi:

Manpage kommt demnächst. Hoffentlich hilfts schon mal ein Stück.

Der Käptn

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi

@captain...

Also ich versteh das Posting von MadMatrix so, dass man die zusätzlich nur angeben muss, wenn man die entweder mehrmals anzeigen lassen will oder in ner anderen Reihenfolge als die vom Stack geholt wird angezeigt werde sollen.

Ansonsten braucht man die so wie ich das sehe nicht.

Tja, da kannst du sogar noch was von nem Newbie im Programmieren, wie ich es einer bin, was lernen. ;)

MfG Crash2001 :)

<FONT COLOR="#a62a2a" SIZE="1">[ 29. August 2001 14:22: Beitrag 1 mal editiert, zuletzt von Crash2001 ]</font>

Link zu diesem Kommentar
Auf anderen Seiten teilen

@crash2001

<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR>Also ich versteh das Posting von MadMatrix so, dass man die zusätzlich nur angeben muss, wenn man die entweder mehrmals anzeigen lassen will oder in ner anderen Reihenfolge als die vom Stack geholt wird angezeigt werde sollen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallöschen,

um hier noch ein kleines Mißverständnis aufzulösen.

natürlich findet die Funktion die Rücksprungadresse auch wenn die Anzahl der Parameter nicht mit denen im Formatstring übereinstimmt.

Sie liegt nämlich ganz oben auf dem Stack.

Zuerst werden die Parameter auf den Stack gelegt und dann die Funktion aufgerufen( und damit auch die Rücksprungadresse als letztes auf den Stack gelegt ).

Andersrum wärs ja auch ein bisschen komisch.

Zuerst die Funktion aufrufen und dann, quasi im Losfahren, die Parameter reinwerfen.

Und auch die Bereinigung des Stacks ist kein Problem, da bei der C-Aufrufkonvention anders als z.B. bei Pascal ( und hier gibt es glaub ich auch keine Funktionen mit variabler Parameterliste ) der Aufrufende den Stack bereinigt und hier weiss der Compiler genau wieviel Daten er auf denselben gelegt.

Wie gesagt bei Pascal wird der Stack vom aufgerufenden Program bereinigt und dafür gibsts dann parametrisierte Return - Assemblerbefehle.

Vorteil dabei: Es wird etwas kleinere Programme erzeugt ( Man hat halt normalerweise mehr Funktionsaufrufe als Funktionen im Program).

Hoagi

:eek: :eek: :cool: :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich finde diese Methode wie der printf arbeitet irgendwie nicht gut. Änderungen von Meldungen und Texte könnten vielleicht ein Umdrehen von Ausgabewerten benötigen und dann müßte doch tatsächlich der ganze Mist neu kompiliert werden. Bei OCI gabs das Data-Binding. Da konnte ich einfach eine Variable mit einem Inhalt im Ausgabe oder Select-String verbinden. Das war was sinnvolles und praktisches. Gibt es für print-Ausgaben nicht auch sowas - oder müßte man sich das selber zusammenschustern?

Link zu diesem Kommentar
Auf anderen Seiten teilen

<BLOCKQUOTE><font size="1" face="Verdana, Arial, Helvetica, sans-serif">Zitat:</font><HR>Original erstellt von hoagi:

<STRONG>Hallöschen,

um hier noch ein kleines Mißverständnis aufzulösen.

natürlich findet die Funktion die Rücksprungadresse auch wenn die Anzahl der Parameter nicht mit denen im Formatstring übereinstimmt.

Sie liegt nämlich ganz oben auf dem Stack.

Zuerst werden die Parameter auf den Stack gelegt und dann die Funktion aufgerufen( und damit auch die Rücksprungadresse als letztes auf den Stack gelegt ).

</STRONG>

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi Maddin,

also prinipiell kann man den Stackpointer boshafterweise so verbiegen, daß die Rücksprungadresse nicht mehr passt, nur ist dies beim normalen Umgang mit zu übergebenden Parametern und lokalen Adressen nicht möglich.

Diese werden nämlich mit stacküblichen Befehlen vom Stack geholt sondern über normale Speicherzugriffsbefehle

z.B.: mov ax,[esp+10] ausgelesen.

Der normale Vorgang ist

aufrufendes Programm:

push parameter1

push parameter2

...

push parametern

call funktion

auferufendes Programm:

Sichern des Stackpointers

Platz schaffen für lokale Variablen

(sub esp,'Anzahl der für lokale benötigten Bytes )

Irgendwas Tun

Sowohl Lokale Variblen werden als Speicher relativ zum Stackpointer angesprochen( nix push und nix pop )

Rücklesen des Stackpointers

return

aufrufendes Programm nach Funktionsaufruf:

add,esp+'Anzahl Bytes die vorher übergeben worden sind'

Der letzte Teil Unterscheidet sich nun bei C und Pascal.

add,esp+'Anzahl Bytes die vorher übergeben worden sind'

Fällt weg,

dafür sieht Returnbefehl so aus:

return 'Anzahl der übergenden Bytes'

Aber du siehst ohne Bosshaft zu sein( oder Stack irgendwie zum überlaufen zu bringen ) bestehen eigentlich wenig Chancen, daß die aufgerufende Funktion die Rücksprungadresse verpasst.

Oder hab ich dich irgendwie falsch verstanden.

Hoagi

;););)

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Hasi:

// Übliches Linux-ist-ganz-toll-Gefasel...

Die gibt es, unterwww.linuxdoc.org/. Interessant ist die Serie 3 der manpages, die sich, auch unter dem Namen Linux Programmer Manual, auf die Funktionen der C-Library bezieht.

Ich benutze auch viel MSVC, das hat als IDE schon viele nette Seiten. Ich reiße mich bestimmt nicht darum, jedes makefile von Hand zu schreiben :)

Das MSDN mach halt auf mich oft den Eindruck von Flickwerk, und da bin ich froh, auch noch auf andere Quellen zuzugreifen zu können. Leider gibts fürs win32 API und für die MFC keine manpages, deswegen muß ich doch oft reinschauen :)

Dr Käptn

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi Leuts,

zum Problem einer Funktion mit variabler Parameterliste hab ich nochmal ein bisschen nachgelesen.

int printf(const char*, ...);

ist ja eine solche. C sieht zur Bearbeitung solcher Funktionen ein Makro namens

ag_list

vor sowie eine Lesefunktion, die das jeweils naechste Listenelement liefert. Jedoch wird das Ende nicht erkannt!

Eine gaengige Loesung dieses Problems ist, dass der Programmierer solche Funktionen deshalb mit einer Paramerliste aufruft, die als letztes Argument einen Wert hat, der das Ende signalisiert.

Bei printf() ist es anders: Die Anzahl der Zugriffe wird anhand der Anzahl der Prozentzeichen erkannt. Ist diese groesser als die Zahl der Argumente, so wird ein Zugriff auf etwas erzeugt, das nicht definiert ist.

M. a. W., man erzeugt undefined behaviour (mal wieder). Da wir nichts weiter ueber die Implementierung von va_list wissen, ist auch die Annahme, was auf dem Stack passiert, nur eine Vermutung.

Erinnern wir uns: undefined behavior == alles kann passieren.

Uli

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...