Warum kann ein printf () in C nicht zwei 64-Bit-Werte gleichzeitig ausgeben?

7

Ich arbeite an einem 32-Bit-System. Wenn ich versuche, mehr als einen 64-Bit-Wert in einem einzelnen Druck zu drucken, kann er keine weiteren (d. H. Zweiten, dritten, ...) Variablenwerte drucken.

Beispiel:

%Vor%

Warum kann dieser Druck nicht alle Werte drucken?

Ich ändere meine Frage

%Vor%

mit diesem Ergebnis ist: a ist 12345678 & amp; b ist 8765432100000000 & amp; c ist 1111111100000000

Wenn ich einen Wert nicht richtig ausdrücke, warum ändern sich dann die Werte des anderen?

    
Jeegar Patel 27.07.2011, 20:21
quelle

5 Antworten

10

Sie müssen das richtige Format verwenden:

%Vor%

Ausgabe:

%Vor%     
XYZ 27.07.2011, 20:32
quelle
14

Sie sollten die in <inttypes.h>

definierten Makros verwenden %Vor%

Es ist hässlich, aber es ist tragbar. Dies wurde in C99 eingeführt, also benötigen Sie einen C99-kompatiblen Compiler.

    
Vinicius Kamakura 27.07.2011 20:28
quelle
2

Es werden alle auf meinem Computer gedruckt, aber es gibt drei Kompilierungswarnungen, da %llx eine long long unsigned int erwartet.

Sind Sie sicher, dass Sie 64-Bit-Typen verwenden müssen? Alle drei Hexcodes sind nur 32 Bit. Vielleicht könnten Sie einfach 32 Bits verwenden und tun:

%Vor%

(Oder verwenden Sie das Stdint-Äquivalent von 32bit unsigned int)

Es sei denn, Sie benötigen 64 Bits, damit Sie später weitere Bits hinzufügen können.

    
Paulpro 27.07.2011 20:28
quelle
1

Verwenden:

%Vor%

Schaut nach innen "inttypes.h".

    
nvd 25.03.2013 17:25
quelle
0

Wie für ein Forum mit dem Namen Stapelüberlauf angezeigt, ist die Ursache für die unerwartete Ausgabe von printf() auf Stapelfehlstellungen zurückzuführen. Die Größenabweichung zwischen der Konvertierungsspezifikation %x und dem Funktionsargument a verursacht die Fehlausrichtung.

Beim Kompilieren der Anweisung

%Vor%

Der Compiler generiert Maschinencode, der die Funktionsargumente auf dem Stapel in der Reihenfolge von rechts nach links verschiebt.

Der Compiler verwendet die Variablendeklarationen, nicht die Formatzeichenfolge, um die Datengröße jedes Arguments auf dem Stapel zu bestimmen (außer möglicherweise zum Generieren von Warnungen). In einer x86-CPU (wie bei den meisten Maschinen) wird der Stapelzeiger bei jedem Drücken dekrementiert. Beim Eingeben der Bibliotheksfunktion printf() hat der Stapel daher das folgende Layout:

%Vor%

Die Top-of-Stack-Adresse von 0084 ist für dieses Beispiel beliebig.

Da alle drei Variablen als uint64_t deklariert sind, verschiebt der kompilierte Code diese Variablen im Stack als 64-Bit-Werte. Bei einer Little-Endian-Maschine wie einer x86-CPU landen die High-Bytes jedes uint64 -Werts in den höheren Adressen.

Die Implementierung von printf() verwendet die Formatzeichenfolge, um die Anzahl und die Größe der Argumente auf dem Stapel zu bestimmen. Im Gegensatz zum Compiler erhält printf() keine Informationen über die ursprünglichen Variablendeklarationen. Die erste Konvertierungsspezifikation lautet %x . Daher erwartet printf() a als 32-Bit-Wert und analysiert daher printf() das Stack-Layout wie folgt:

%Vor%

Die Stapelfehlausrichtung erklärt, warum a 12345678 wie erwartet ausgibt, aber b und c wurden effektiv um 32 Bit nach 8765432100000000 und 1111111100000000 nach links verschoben.

Das Korrigieren der ersten %x Konvertierungsspezifikation oder des Casting Arguments a auf uint32 sollte das Problem beheben.

    
Fred Schleifer 10.02.2017 19:33
quelle

Tags und Links