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
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.
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.
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.
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.
> 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.
> ... 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.