Ich habe den folgenden Code:
%Vor%Die Ausgabe ist:
%Vor% Ich kann sehen, dass ein Wert entsprechend dem an printf
function übergebenen Wert als signed oder unsigned interpretiert wird. In beiden Fällen sind die Bytes gleich ( ffffffff
). Was ist dann das Wort unsigned
?
Weisen Sie int -1
einem unsigned
zu: Da -1
nicht in den Bereich [0...UINT_MAX]
passt, werden Vielfache von UINT_MAX+1
hinzugefügt, bis die Antwort im Bereich ist. Offensichtlich UINT_MAX
ist pow(2,32)-1 or 429496725
auf der Maschine von OP, also hat a
den Wert 4294967295 .
Der Bezeichner "%x"
, "%u"
erwartet eine übereinstimmende unsigned
. Da diese nicht übereinstimmen: "Wenn eine Konvertierungsspezifikation ungültig ist, ist das Verhalten nicht definiert.
Wenn ein Argument nicht der richtige Typ für die entsprechende Konvertierungsspezifikation ist, ist das Verhalten undefiniert . "C11 §7.21.6.1 9. Der printf-Spezifizierer ändert b
nicht.
Der "%d"
-Spezifikator erwartet eine übereinstimmende int
. Da diese nicht übereinstimmen, mehr UB .
Bei gegebenem undefiniertem Verhalten werden die Schlussfolgerungen nicht unterstützt.
In beiden Fällen sind die Bytes gleich (ffffffff).
Auch bei gleichem Bitmuster können unterschiedliche Typen unterschiedliche Werte haben. ffffffff
als unsigned
hat den Wert 4294967295. Als int
, abhängige Ganzzahlkodierung mit Vorzeichen, hat sie den Wert -1, -2147483647 oder TBD. Als float
kann es ein NAN sein.
Was ist ein vorzeichenloses Wort für?
unsigned
speichert eine ganze Zahl im Bereich [0 ... UINT_MAX]
. Es hat nie einen negativen Wert. Wenn Code eine nicht negative Zahl benötigt, verwenden Sie unsigned
. Wenn Code eine Zählnummer benötigt, die +, - oder 0 sein kann, verwenden Sie int
.
Update: Um zu vermeiden, dass ein Compiler vor der Zuweisung eines signierten int
zu unsigned
warnt, verwenden Sie das Folgende. Dies ist ein unsigned
1u
wird negiert - was wie oben definiert ist. Der Effekt ist der gleiche wie ein -1
, vermittelt aber dem Compiler direkte Absichten.
Die Verwendung von unsigned
in der Variablendeklaration ist für die Programmierer selbst nützlicher - behandeln Sie die Variablen nicht als negativ. Wie Sie bemerkt haben, haben sowohl -1
als auch 4294967295
genau dieselbe Bitdarstellung für eine 4-Byte-Ganzzahl. Es geht darum, wie Sie sie behandeln oder sehen .
Die Anweisung unsigned int a = -1;
konvertiert -1
im Zweierkomplement und weist die Bitdarstellung in a
zu. Der printf()
specifier x
, d
und u
zeigen, wie die in der Variablen a
gespeicherte Bitdarstellung in einem anderen Format aussieht.
Wenn Sie unsigned int a to -1;
initialisieren, bedeutet dies, dass Sie das 2's
Komplement von -1
im Speicher von a
speichern.
Was ist nichts als 0xffffffff
oder 4294967295
.
Wenn Sie es mit %x or %u
format specifier drucken, erhalten Sie diese Ausgabe.
Durch Angabe der Signedness einer Variablen zur Festlegung der minimalen und maximalen Wertgrenze, die gespeichert werden kann.
Wie bei unsigned int
: Der Bereich ist von 0 to 4,294,967,295
und int
: der Bereich ist von -2,147,483,648 to 2,147,483,647
In hexadezimal kann kein negativer Wert erhalten werden. So sieht es aus wie ffffffff .
Der Vorteil der Verwendung der unsignierten Version (wenn Sie wissen, dass die enthaltenen Werte nicht negativ sind) ist, dass der Computer manchmal Fehler für Sie entdeckt (das Programm wird " crash "wenn der Variablen ein negativer Wert zugewiesen wird.