Forum: Mikrocontroller und Digitale Elektronik Printf


von Matze M. (eli2006)


Lesenswert?

Hallo

Ich habe ein Problem mit der Funktion printf.
Ich möchte ein char auf dem Terminal ausgeben
z.B. so:

char tmp=0x0c;
printf("%02X",tmp);

Die Ausgabe auf dem Terminal sieht jetzt so aus:

 0c12

Kann mir vielleicht jemand sagen, warum sich die Zahl 12 dahinter
einschleicht. Normalerweise müsste doch auf dem Terminal nur 0c
erscheinen.
Habe einen µC At89s8252 und den Keil Compiler .

Danke im Voraus

von Jens Gerdes (Gast)


Lesenswert?

Probiere mal printf("%02x",(int)temp);

von Matze M. (eli2006)


Lesenswert?

Super
Danke Jens
es Funktioniert Danke!

Kurz noch. An was liegt das?

von Jens Gerdes (Gast)


Lesenswert?

Kann ich nicht genau sagen, das liegt wohl an der Parameterübergabe für
printf. Bei anderen Compilern/Bibliotheken ist das nicht unbedingt
erforderlich. Ich konnte auch im Keil Handbuch keinen Hinweis finden.

von Andreas Bombe (Gast)


Lesenswert?

Das liegt daran, dass %x bei printf per default erstmal unsigned int
ist.  Bei Parameterübergabe über Stack holt sich printf also wie
instruiert ein int vom Stack, formatiert es und gibt es aus.  Wenn du
nun nur ein char übergibst, liest printf eben trotzdem ein int und
damit noch ein weiteres Byte (bei 16 Bit int) vom Stack und gibt diesen
Wert aus.

Datenbreite kannst du printf mitteilen, für char:
printf("%02hhX", tmp);

Das ist zumindest in ISO C99 (hh = char, h = short, l = long).  Im
Zweifelsfall gilt natürlich die Doku der lib, die dein printf zur
Verfügung stellt.

von Rolf Magnus (Gast)


Lesenswert?

Sieht nach einem Bug (oder Feature?) des Compilers aus. Nach C-Norm ist
der Cast nicht notwendig, da bei Übergabe variabler Argumentlisten char
vor der Übergabe automatisch in int konvertiert werden müßte.

von Andreas Bombe (Gast)


Lesenswert?

Nach ISO C99 (bzw. nach dem aktuellen Working Paper) endet die
automatische Argument-Konvertierung mit dem '...' und damit ist das
kein Bug, sondern korrekte Implementierung.

Eine alternative "Lösung" des Problems wäre gewesen, die Header-Datei
für printf zu "vergessen".  Bei aufgerufenen Funktionen ohne Prototyp
wird alles was nicht int (oder double) ist nach int (außer floats: nach
double) konvertiert.

von Rolf Magnus (Gast)


Lesenswert?

> Nach ISO C99 (bzw. nach dem aktuellen Working Paper) endet die
>  automatische Argument-Konvertierung mit dem '...'

Das stimmt zwar, aber das sind nicht die Konvertierungen, die ich
meine.

"The ellipsis notation in a function prototype declarator causes
argument type conversion to stop after the last declared parameter.
The default argument promotions are performed on trailing arguments."


Mit anderen Worten: Wenn die Funktion einen anderen Typ erwartet, als
ihr übergeben wird, wird keine automatische Konvertierung durchgeführt.
Das ist auch logisch, denn der Compiler weiß ja gar nicht, was die
Funktion erwartet. (Beispiel: Wenn ich einen float a printf übergebe,
aber im Formatstring ein %d für int habe, wird keine automatische
Konverierung float->int durchgeführt).
Die "promotions" hingegen werden bei variablen Argumentlisten
ausgeführt, und dazu gehört auch, daß alle Integers, die in einen int
passen würden, in diesen konvertiert werden.

von Rolf Magnus (Gast)


Lesenswert?

> ... daß alle Integers, die in einen int passen würden, in diesen
> konvertiert werden.

Ist etwas unglücklich formuliert. Ich meinte "... daß Werte eines
Integertypen, dessen Bereich komplett von int abgedeckt wird, nach int
konvertiert werden".

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.