In C/C++, was für eine unsigned char
wird verwendet? Wie unterscheidet es sich von einem normalen char
?
Was ist ein unsigned char?
Landon Kühn
Fruny
In C++ gibt es drei unterscheidbar Zeichentypen:
char
signed char
unsigned char
Wenn Sie Zeichentypen für verwenden Textverwenden Sie das unqualifizierte char
:
- es ist die Art von Zeichenliteralen wie
'a'
oder'0'
(Nur in C++, in C ist ihr Typint
) - es ist der Typ, der C-Saiten wie bildet
"abcde"
Es funktioniert auch als Zahlenwert, aber es ist nicht angegeben, ob dieser Wert als vorzeichenbehaftet oder als vorzeichenlos behandelt wird. Hüten Sie sich vor Zeichenvergleichen durch Ungleichungen – obwohl Sie sich auf ASCII (0-127) beschränken, sind Sie gerade noch sicher.
Wenn Sie Zeichentypen wie verwenden Zahlenverwenden:
signed char
was dir gibt wenigstens Bereich von -127 bis 127. (-128 bis 127 ist üblich)unsigned char
was dir gibt wenigstens Bereich 0 bis 255.
„Mindestens“, weil der C++-Standard nur den minimalen Wertebereich vorgibt, den jeder numerische Typ abdecken muss. sizeof (char)
muss 1 sein (dh ein Byte), aber ein Byte könnte theoretisch beispielsweise 32 Bit umfassen. sizeof
würde immer noch seine Größe als melden 1
– was bedeutet, dass Sie könnten verfügen über sizeof (char) == sizeof (long) == 1
.
-
Um es klar zu sagen, könnten Sie 32-Bit-Zeichen und 32-Bit-Ganzzahlen haben und sizeof(int) != sizeof(char) haben? Ich weiß, dass der Standard sagt sizeof(char) == 1, aber basiert die relative sizeof(int) auf dem tatsächlichen Größenunterschied oder dem Unterschied im Bereich?
– Josef Garwin
11. Januar 2009 um 23:21 Uhr
-
+1. Aber es gibt vier verschiedene Zeichentypen in C++, wchar_t ist einer davon.
– Eric Z
24. August 2013 um 9:19 Uhr
-
seit c++11 gibt es 6 verschiedene Typen: char, signed char, unsigned char, wchar_t, char16_t, char32_t.
– Marcinj
16. Februar 2014 um 9:53 Uhr
-
@unheilig Es ist üblich, ein Leerzeichen danach zu setzen
sizeof
weil es keine Funktion, sondern ein Operator ist. Es ist imho ein noch besserer Stil, die Klammern wegzulassen, wenn man die Größe einer Variablen nimmt.sizeof *p
odersizeof (int)
. Damit ist schnell klar, ob es sich um einen Typ oder eine Variable handelt. Ebenso ist es auch überflüssig, hinter Klammern zu setzenreturn
. Es ist keine Funktion.– Patrick Schlüter
28. November 2014 um 12:00 Uhr
-
“Byte” bezieht sich in diesem Zusammenhang auf die kleinste adressierbare Speichereinheit. Die C- und C++-Standards verlangen, dass ein Byte mindestens 8 Bit lang ist, aber sie geben kein Maximum an. Auf so ziemlich allen Allzweckcomputern von heute (einschließlich allem, was mit neueren Posix-Versionen kompatibel ist) ist ein Byte genau 8 Bit, aber spezialisierte DSP-Plattformen und Retro-Systeme können größere Bytes haben.
– Plugwash
1. März 2019 um 18:48 Uhr
Tod Gamblin
Dies ist implementierungsabhängig, da der C-Standard NICHT die Signiertheit von definiert char
. Je nach Plattform kann char sein signed
oder unsigned
also müssen Sie explizit danach fragen signed char
oder unsigned char
wenn Ihre Implementierung davon abhängt. Benutz einfach char
wenn Sie beabsichtigen, Zeichen aus Zeichenfolgen darzustellen, da dies mit dem übereinstimmt, was Ihre Plattform in die Zeichenfolge einfügt.
Der Unterschied zwischen signed char
und unsigned char
ist wie erwartet. Auf den meisten Plattformen signed char
wird eine 8-Bit-Zweierkomplementzahl sein, die von reicht -128
zu 127
und unsigned char
wird eine 8-Bit-Ganzzahl ohne Vorzeichen (0
zu 255
). Beachten Sie, dass der Standard dies NICHT erfordert char
Typen haben 8 Bits, nur das sizeof(char)
Rückkehr 1
. Sie können die Anzahl der Bits in einem Zeichen mit abrufen CHAR_BIT
in limits.h
. Es gibt heute nur wenige Plattformen, auf denen dies etwas anderes sein wird 8
obwohl.
Zu diesem Thema gibt es eine schöne Zusammenfassung Hier.
Wie andere bereits erwähnt haben, seit ich dies gepostet habe, sind Sie besser dran int8_t
und uint8_t
wenn Sie wirklich kleine ganze Zahlen darstellen wollen.
-
signed char haben nur einen Mindestbereich von -127 bis 127, nicht von -128 bis 127
– 12431234123412341234123
28. Januar 2017 um 6:40 Uhr
-
@ 12431234123412341234123: Technisch richtig, da der C-Standard -127 bis 127 als Mindestbereich definiert. Ich fordere Sie jedoch auf, eine Plattform zu finden, die keine Zweierkomplement-Arithmetik verwendet. Auf fast jeder modernen Plattform beträgt der tatsächliche Bereich der Zeichen mit Vorzeichen -128 bis 127.
– Tod Gamblin
6. Februar 2017 um 7:55 Uhr
-
CHAR_BIT
muss laut Standard mindestens 8 Bit betragen.– Martinkunew
12. März 2019 um 16:31 Uhr
Johannes Schaub – litb
Da ich das Gefühl habe, dass es wirklich erforderlich ist, möchte ich nur einige Regeln von C und C++ angeben (in dieser Hinsicht sind sie gleich). Zuerst, alle Bits von unsigned char
Beteiligen Sie sich an der Bestimmung des Werts eines unsignierten char-Objekts. Sekunde, unsigned char
ist ausdrücklich unsigniert angegeben.
Jetzt hatte ich eine Diskussion mit jemandem darüber, was passiert, wenn Sie den Wert konvertieren -1
vom Typ int bis unsigned char
. Er lehnte die Idee ab, dass die daraus resultierenden unsigned char
hat alle seine Bits auf 1 gesetzt, weil er sich Sorgen um die Vorzeichendarstellung machte. Aber das musste er nicht sein. Aus dieser Regel folgt unmittelbar, dass die Konvertierung das tut, was beabsichtigt ist:
Wenn der neue Typ vorzeichenlos ist, wird der Wert konvertiert, indem wiederholt eins mehr als der maximale Wert, der im neuen Typ dargestellt werden kann, addiert oder subtrahiert wird, bis der Wert im Bereich des neuen Typs liegt. (
6.3.1.3p2
in einem C99-Entwurf)
Das ist eine mathematische Beschreibung. C++ beschreibt es in Begriffen des Modulo-Kalküls, was zu derselben Regel führt. Wie auch immer, was ist nicht garantiert ist, dass alle Bits in der Ganzzahl sind -1
sind eins vor der Umstellung. Also, was haben wir, damit wir das Ergebnis behaupten können unsigned char
hat alle seine CHAR_BIT
Bits auf 1 gesetzt?
- Alle Bits sind an der Wertbestimmung beteiligt, dh es kommen keine Füllbits im Objekt vor.
- Nur einmal hinzufügen
UCHAR_MAX+1
zu-1
ergibt einen Wert im Bereich, nämlichUCHAR_MAX
Das reicht eigentlich! Wann immer Sie also eine haben möchten unsigned char
Wenn alle seine Bits eins sind, tust du es
unsigned char c = (unsigned char)-1;
Daraus folgt auch, dass es sich um eine Konvertierung handelt nicht nur höherwertige Bits abschneiden. Das glückliche Ereignis für Zweierkomplement ist, dass es sich dort nur um eine Kürzung handelt, aber das gilt nicht unbedingt für andere Zeichendarstellungen.
-
Warum nicht einfach verwenden
UCHAR_MAX
?– Nicolas
4. Januar 2011 um 22:01 Uhr
-
Weil
(unsigned type)-1
ist eine Art Redewendung.~0
ist nicht.– Patrick Schlüter
28. November 2014 um 12:07 Uhr
-
wenn ich sowas habe
int x = 1234
undchar *y = &x
. Binäre Darstellung von1234
ist00000000 00000000 00000100 11010010
. Meine Maschine ist Little Endian, also kehrt sie sie um und speichert sie im Speicher11010010 00000100 00000000 00000000
LSB kommt zuerst. Jetzt Hauptteil. wenn ich benutzeprintf("%d" , *p)
.printf
wird das erste Byte lesen11010010
nur die Ausgabe ist-46
aber11010010
ist210
also warum druckt es-46
. Ich bin wirklich verwirrt, ich schätze, einige Char-to-Integer-Promotion macht etwas, aber ich weiß es nicht.– Suraj Jain
17. August 2016 um 10:23 Uhr
Zachary Garrett
Wie zum Beispiel Verwendungen von unsigned char:
unsigned char
wird häufig in der Computergrafik verwendet, die sehr oft (aber nicht immer) jeder Farbkomponente ein einzelnes Byte zuweist. Es ist üblich, eine RGB- (oder RGBA-) Farbe als 24 (oder 32) Bit dargestellt zu sehen, jedes ein unsigned char
. Seit unsigned char
Werte fallen in den Bereich [0,255]werden die Werte typischerweise wie folgt interpretiert:
- 0 bedeutet ein vollständiges Fehlen einer gegebenen Farbkomponente.
- 255 bedeutet 100 % eines bestimmten Farbpigments.
Sie würden also RGB-Rot als (255,0,0) -> (100% Rot, 0% Grün, 0% Blau) erhalten.
Warum nicht ein verwenden signed char
? Arithmetik und Bitverschiebung werden problematisch. Wie bereits erläutert, a signed char
Der Bereich von wird im Wesentlichen um -128 verschoben. Eine sehr einfache und naive (meistens ungenutzte) Methode zum Konvertieren von RGB in Graustufen besteht darin, alle drei Farbkomponenten zu mitteln, aber dies führt zu Problemen, wenn die Werte der Farbkomponenten negativ sind. Rot (255, 0, 0) wird bei Verwendung zu (85, 85, 85) gemittelt unsigned char
Arithmetik. Allerdings, wenn die Werte waren signed char
s (127,-128,-128), würden wir mit (-99, -99, -99) enden, was (29, 29, 29) in unserem wäre unsigned char
Leerzeichen, was falsch ist.
munna
unsigned char
nimmt nur positive Werte …. wie 0 zu 255
wohingegen
signed char
nimmt sowohl positive als auch negative Werte an….wie -128 zu +127
signed char
hat einen Bereich von -128 bis 127; unsigned char
hat einen Bereich von 0 bis 255.
char
entspricht je nach Compiler entweder signed char oder unsigned char, ist aber ein eigener Typ.
Wenn Sie Zeichenfolgen im C-Stil verwenden, verwenden Sie einfach char
. Wenn Sie Zeichen für Arithmetik verwenden müssen (ziemlich selten), geben Sie aus Gründen der Portabilität explizit signed oder unsigned an.
Stich
char
und unsigned char
sind nicht garantiert auf allen Plattformen 8-Bit-Typen – sie sind garantiert 8-Bit oder größer. Einige Plattformen haben 9-Bit-, 32-Bit- oder 64-Bit-Bytes. Die heute gängigsten Plattformen (Windows, Mac, Linux x86 usw.) haben jedoch 8-Bit-Bytes.