Warum kann man printf() in C nicht drucken zwei 64-bit-Werte zur gleichen Zeit?
Arbeite ich auf einem 32-bit-system. Wenn ich versuche zu drucken, die mehr als eine 64-bit-Wert in einer einzigen printf -, dann kann es nicht drucken, keine weiteren (d.h. 2., 3., ...) variable Werte.
Beispiel:
uint64_t a = 0x12345678;
uint64_t b = 0x87654321;
uint64_t c = 0x11111111;
printf("a is %llx & b is %llx & c is %llx",a,b,c);
Warum kann das printf nicht drucken aller Werte?
Ich bin das ändern meiner Frage
printf("a is %x & b is %llx & c is %llx",a,b,c);
by doing " dieses Ergebnis ist : ein 12345678 & b ist 8765432100000000 & c ist 1111111100000000
wenn ich bin nicht den Druck ein Wert richtig, warum dann der andere Wert sind gona ändern??
- Was ist der output (oder Fehler), dass Sie bekommen?
- Tatsächlich, es funktioniert: ideone.com/um0QL
- Sie können nicht verwenden
ll
füruint64_t
. Sie können nurll
fürlong long
Arten. Sollten Sie die<inttypes.h>
Makros! - Wenn ich dein code-snippet in ein komplettes Programm, es liefert die erwartete Ausgabe. Bitte geben Sie eine minimale, vollständige Beispiel-Programm zusammen mit dem erwarteten Ausgang und die Ausgabe, die Sie tatsächlich sehen. Für eine Erklärung, die zum erstellen einer minimalen komplette Programm, und warum, dass ist ein nützliches Werkzeug, finden Sie unter sscce.org.
- Was compiler, os und compiler-Optionen verwenden Sie?
- SB: Xcode 4.1 sagt mir
%llx
ist korrekt für ein uint64_t. - Das ist Zufall, nicht tragbar!
- Ja, du hast Recht. PRIx64 auflöst "llx" hier, aber PRIx64 ist tragbar und "llx" ist es nicht.
- Gut,
llx
ist auch portabel, es ist einfach bezieht sich auf eine andere Art! 🙂 Fürunsigned long long int
Sie druckenllu
oderllx
fürunsigned long int
Sie druckenlu
oderlx
, und fürunsigned int
Sie druckenu
oderx
. Never mind, dass diese alle sind bitweise identisch, aber Sie sind unterschiedliche Typen in der Sprache. - Ich meinte es ist nicht tragbar, wenn Sie nicht den Umgang mit einer lange, lange geben.
- printf("a ist %x & b ist %llx & c ist %llx",a,b,c); dadurch ergibt sich : ein 12345678 & b ist 8765432100000000 & c ist 1111111100000000, wenn ich nicht den Druck ein Wert richtig, warum dann der andere Wert sind gona ändern??
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie das richtige format:
Ausgabe:
#
tun (wie in%#
) ?Sollten Sie die definierten Makros
<inttypes.h>
Es ist hässlich wie die Hölle, aber es ist tragbar. Das wurde in C99, so benötigen Sie einen C99-kompatible compiler.
PRIx64
ist auf Xcode 4.1, wenn es nicht "llx"?printf("PRIx64 is %s\n", PRIx64")
oder die kürzereprintf("PRIx64 is "PRIx64"\n");
PRIx64
etc. Aber meine Vermutung, was macht den Unterschied, denn die OP ist nur die\n
am Ende der format-string...#define PRIx64 __PRI_64_LENGTH_MODIFIER__ "x"
und#define __PRI_64_LENGTH_MODIFIER__ "ll"
.printf
wird mit pop vom stack falsche Anzahl von bytes. eine ist 8 bytes, aber mit%x
entfernt nur 4. also die anderen 4 bleiben auf dem stack, dann%llx
entfernt 8 bytes, aber Sie sind falsch, denn die 4 sind vona
und 4 vonb
. Das gleiche geschieht mit der nächsten%llx
.Er druckt Sie alle auf meinem computer, aber es gibt drei Kompilierung Warnungen seit
%llx
erwartet einelong long unsigned int
.Sind Sie sicher, dass Sie brauchen, um mit 64-bit-Typen aber? Alle drei hexcodes sind nur 32-bit. Vielleicht könnte man nur 32 bits und tun:
(Oder verwenden Sie den stdint-äquivalent von 32-bit unsigned int)
Wenn Sie Sie benötigen 64 bits, so dass Sie hinzufügen können, mehr bits, um Sie später.
Als angemessen für ein forum namens Stack Overflow, die Ursache der unerwarteten
printf()
Ausgabe ist aufgrund Stapel Versatz. Die Größe der Diskrepanz zwischen der%x
Umwandlung-Spezifikation und Funktion argumenta
Ursachen der Fehlstellung.Beim kompilieren der Anweisung
erzeugt der compiler Maschinencode, der schiebt die Funktionsargumente auf dem stack von rechts nach Links um.
Verwendet der compiler den Variablen-Deklarationen, nicht die format-string, um zu bestimmen, die Größe der Daten der einzelnen Argumente auf dem stack (außer vielleicht für die Generierung von Warnungen). In einer x86 CPU (wie in den meisten Maschinen) der stack-pointer dekrementiert mit jedem Stoß. Bei der Eingabe der
printf()
library-Funktion, die Stapel deshalb hat das folgende layout:Den top-of-stack-Adresse 0084 willkürlich für dieses Beispiel.
Da alle drei Variablen sind deklariert als
uint64_t
, die den kompilierten code schiebt diese Variablen auf dem stack als 64-bit-Werte. Für eine little-endian-Maschine wie eine x86 CPU, die high-bytes der einzelnenuint64
Wert am Ende in die höheren Adressen.Die Umsetzung der
printf()
verwendet die format-string bestimmt die Anzahl und Größe der Argumente auf dem stack. Im Gegensatz zum compiler,printf()
erhält keine Informationen über den ursprünglichen Variablen-Deklarationen. Die erste konvertierungsspezifikation ist%x
, soprintf()
erwarteta
eine 32-bit-Wert, und daherprintf()
analysiert die stack-layout wie folgt:Den Stapel Versatz erklärt, warum
a
Drucke 12345678 als erwartet, aberb
undc
wurden effektiv Links-verschoben von 32 bit auf 8765432100000000 und 1111111100000000.Korrektur der ersten
%x
Konvertierung Spezifikation oder casting-argumenta
auf uint32 sollte das problem lösen.Verwenden:
Haben Sie einen Blick hinein "inttypes.h".