Was ist der Unterschied zwischen signiertem und nicht signiertem int?
Was ist der Unterschied zwischen signiertem und nicht signiertem int?
Antworten:
Wie Sie wahrscheinlich wissen, werden int
s intern binär gespeichert. Normalerweise int
enthält a 32 Bit, in einigen Umgebungen jedoch 16 oder 64 Bit (oder sogar eine andere Zahl, normalerweise, aber nicht unbedingt eine Zweierpotenz).
Schauen wir uns für dieses Beispiel 4-Bit-Ganzzahlen an. Winzig, aber nützlich zur Veranschaulichung.
Da eine solche Ganzzahl vier Bits enthält, kann sie einen von 16 Werten annehmen. 16 ist zwei nach der vierten Potenz oder 2 mal 2 mal 2 mal 2. Was sind diese Werte? Die Antwort hängt davon ab, ob diese Ganzzahl a signed int
oder an ist unsigned int
. Mit a unsigned int
ist der Wert niemals negativ; Dem Wert ist kein Vorzeichen zugeordnet. Hier sind die 16 möglichen Werte eines Vier-Bit unsigned int
:
bits value
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9
1010 10
1011 11
1100 12
1101 13
1110 14
1111 15
... und hier sind die 16 möglichen Werte eines Vier-Bit signed int
:
bits value
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 -8
1001 -7
1010 -6
1011 -5
1100 -4
1101 -3
1110 -2
1111 -1
Wie Sie sehen können, ist für signed int
s das höchstwertige Bit 1
genau dann, wenn die Zahl negativ ist. Deshalb ist signed int
dieses Bit für s als "Vorzeichenbit" bekannt.
(unsigned)(-1)
ist, muss es der maximal darstellbare Wert für unsigned
(unabhängig von der binären Darstellung) sein, was für das Zweierkomplement trivial gilt, jedoch nicht für andere Darstellungen.
int
und unsigned int
sind zwei verschiedene ganzzahlige Typen. ( int
kann auch als signed int
oder nur bezeichnet werden signed
; unsigned int
kann auch als bezeichnet werden unsigned
.)
Wie die Namen andeuten, int
handelt es sich um einen vorzeichenbehafteten Ganzzahltyp und unsigned int
um einen vorzeichenlosen Ganzzahltyp. Dies bedeutet, dass int
negative Werte und unsigned int
nur nicht negative Werte dargestellt werden können.
Die C-Sprache stellt einige Anforderungen an die Bereiche dieser Typen. Der Bereich von int
muss mindestens -32767
... sein +32767
, und der Bereich unsigned int
muss mindestens 0
... sein 65535
. Dies bedeutet, dass beide Typen mindestens 16 Bit sein müssen. Sie sind 32 Bit auf vielen Systemen oder sogar 64 Bit auf einigen. int
hat normalerweise einen zusätzlichen negativen Wert aufgrund der Zweierkomplementdarstellung, die von den meisten modernen Systemen verwendet wird.
Der vielleicht wichtigste Unterschied ist das Verhalten von vorzeichenbehafteter und vorzeichenloser Arithmetik. Bei signierten int
hat der Überlauf ein undefiniertes Verhalten. Denn unsigned int
es gibt keinen Überlauf; Jede Operation, die einen Wert außerhalb des Bereichs des Typs ergibt, wird beispielsweise umbrochen UINT_MAX + 1U == 0U
.
Jeder ganzzahlige Typ, entweder mit oder ohne Vorzeichen, modelliert einen Teilbereich der unendlichen Menge mathematischer Ganzzahlen. Solange Sie mit Werten im Bereich eines Typs arbeiten, funktioniert alles. Wenn Sie sich der Unter- oder Obergrenze eines Typs nähern, stoßen Sie auf eine Diskontinuität und können unerwartete Ergebnisse erzielen. Bei vorzeichenbehafteten Ganzzahltypen treten die Probleme nur bei sehr großen negativen und positiven Werten auf, die INT_MIN
und überschreiten INT_MAX
. Bei vorzeichenlosen Ganzzahltypen treten Probleme bei sehr großen positiven Werten und bei Null auf . Dies kann eine Fehlerquelle sein. Dies ist beispielsweise eine Endlosschleife:
for (unsigned int i = 10; i >= 0; i --) [
printf("%u\n", i);
}
da i
ist immer größer oder gleich Null ist ; Das ist die Natur von Typen ohne Vorzeichen. (Wenn innerhalb der Schleife i
Null ist, wird i--
der Wert auf gesetzt UINT_MAX
.)
Manchmal wissen wir im Voraus, dass der in einer bestimmten Ganzzahlvariablen gespeicherte Wert immer positiv ist - wenn er beispielsweise nur zum Zählen von Dingen verwendet wird. In einem solchen Fall können wir die Variable als unsigniert deklarieren, wie in , unsigned int num student;
. Mit einer solchen Deklaration verschiebt sich der Bereich der zulässigen Ganzzahlwerte (für einen 32-Bit-Compiler) vom Bereich -2147483648 bis +2147483647 zum Bereich 0 bis 4294967295. Wenn Sie also eine Ganzzahl als vorzeichenlos deklarieren, verdoppelt sich die Größe der größtmöglichen fast Wert, den es sonst halten kann.
Für Laien ist ein vorzeichenloses int eine Ganzzahl, die nicht negativ sein kann und daher einen höheren Bereich positiver Werte aufweist, den sie annehmen kann. Ein vorzeichenbehaftetes int ist eine Ganzzahl, die negativ sein kann, aber einen niedrigeren positiven Bereich hat, wenn mehr negative Werte angenommen werden.
In der Praxis gibt es zwei Unterschiede:
cout
in C ++ oder printf
in C): Die vorzeichenlose Ganzzahlbitdarstellung wird von den Druckfunktionen als nichtnegative Ganzzahl interpretiert.Dieser Code kann die Ganzzahl anhand des Ordnungskriteriums identifizieren:
char a = 0;
a--;
if (0 < a)
printf("unsigned");
else
printf("signed");