Wofür unsigned char
wird in C / C ++ ein verwendet? Wie unterscheidet es sich von einem normalen char
?
In C ++ gibt es drei verschiedene Zeichentypen:
char
signed char
unsigned char
Wenn Sie Zeichentypen für Text verwenden , verwenden Sie Folgendes char
:
'a'
oder '0'
."abcde"
Es funktioniert auch als Zahlenwert, es ist jedoch nicht angegeben, ob dieser Wert als signiert oder nicht signiert behandelt wird. Hüten Sie sich vor Charaktervergleichen durch Ungleichungen - obwohl Sie, wenn Sie sich auf ASCII (0-127) beschränken, fast sicher sind.
Wenn Sie Zeichentypen als Zahlen verwenden , verwenden Sie:
signed char
, was Ihnen mindestens den Bereich von -127 bis 127 gibt. (-128 bis 127 ist üblich)unsigned char
, was Ihnen mindestens den Bereich von 0 bis 255 gibt."Zumindest", da der C ++ - Standard nur den Mindestwertebereich angibt, den jeder numerische Typ abdecken muss. sizeof (char)
muss 1 sein (dh ein Byte), aber ein Byte könnte theoretisch beispielsweise 32 Bit sein. sizeof
wäre noch seine Größe berichten wie1
- was bedeutet , dass Sie könnte haben sizeof (char) == sizeof (long) == 1
.
sizeof
da es sich nicht um eine Funktion, sondern um einen Operator handelt. Es ist imho noch besser, die Klammer wegzulassen, wenn man die Größe einer Variablen nimmt.sizeof *p
odersizeof (int)
. Dies macht schnell klar, ob es sich um einen Typ oder eine Variable handelt. Ebenso ist es überflüssig, nach Klammern zu setzenreturn
. Es ist keine Funktion.char
: Es ist die Art von Zeichenliteralen wie'a'
oder'0'
." ist wahr in C ++ aber nicht C. In C'a'
ist einint
.Dies ist implementierungsabhängig, da der C-Standard NICHT die Signatur von definiert
char
. Je nach Plattform kann charsigned
oder seinunsigned
, daher müssen Sie explizit nachfragensigned char
oderunsigned char
ob Ihre Implementierung davon abhängt. Verwendenchar
Sie diese Option nur, wenn Sie Zeichen aus Zeichenfolgen darstellen möchten, da dies mit dem übereinstimmt, was Ihre Plattform in die Zeichenfolge einfügt.Der Unterschied zwischen
signed char
undunsigned char
ist wie erwartet. Auf den meisten Plattformensigned char
wird eine 8-Bit-Zweierkomplementzahl von reichen-128
bis127
undunsigned char
eine 8-Bit-Ganzzahl ohne Vorzeichen (0
bis255
). Beachten Sie, dass der Standard NICHT verlangt, dasschar
Typen 8 Bit haben, sondern nur diesesizeof(char)
Rückgabe1
. Sie können die Anzahl der Bits in einem Zeichen mitCHAR_BIT
in ermittelnlimits.h
. Es gibt heutzutage nur wenige Plattformen, auf denen dies etwas anderes sein8
wird.Es gibt eine schöne Zusammenfassung dieses Problem hier .
Wie andere erwähnt haben , da ich dies geschrieben, du bist besser dran mit
int8_t
unduint8_t
wenn Sie wirklich kleine ganze Zahlen darstellen wollen.quelle
CHAR_BIT
Der Standard muss mindestens 8 Bit betragen.Da ich der Meinung bin, dass dies wirklich erforderlich ist, möchte ich nur einige Regeln für C und C ++ angeben (sie sind in dieser Hinsicht gleich). Zuerst werden alle Bits der
unsigned char
Teilnahme den Wert , wenn jeder unsigned char Objekt zu bestimmen. Zweitensunsigned char
wird ausdrücklich ohne Vorzeichen angegeben.Jetzt hatte ich eine Diskussion mit jemandem darüber, was passiert, wenn Sie den Wert
-1
vom Typ int in konvertierenunsigned char
. Er lehnte die Idee ab, dass das Ergebnisunsigned char
alle seine Bits auf 1 gesetzt hat, weil er sich Sorgen um die Darstellung der Zeichen machte. Aber das muss er nicht. Aus dieser Regel folgt unmittelbar, dass die Konvertierung das tut, was beabsichtigt ist:Das ist eine mathematische Beschreibung. C ++ beschreibt es mit Modulo-Kalkül, das der gleichen Regel entspricht. Was jedoch nicht garantiert ist, ist, dass alle Bits in der Ganzzahl
-1
vor der Konvertierung eins sind. Was haben wir also, damit wir behaupten können, dass das Ergebnisunsigned char
alle seineCHAR_BIT
Bits auf 1 gesetzt hat?UCHAR_MAX+1
zu-1
erhalten Sie einen Wert im Bereich, nämlichUCHAR_MAX
Das reicht eigentlich! Also, wann immer Sie wollen,
unsigned char
dass alle seine Teile eins haben, tun Sie esDaraus folgt auch, dass eine Konvertierung nicht nur Bits höherer Ordnung abschneidet. Das glückliche Ereignis für das Zweierkomplement ist, dass es dort nur eine Kürzung ist, aber dasselbe gilt nicht unbedingt für andere Zeichendarstellungen.
quelle
UCHAR_MAX
?(unsigned type)-1
es eine Art Redewendung ist.~0
ist nicht.int x = 1234
undchar *y = &x
. Binäre Darstellung von1234
ist00000000 00000000 00000100 11010010
. Meine Maschine ist Little Endian, also kehrt sie es um und das Speichern im Speicher11010010 00000100 00000000 00000000
LSB steht an erster Stelle. Jetzt Hauptteil. wenn ich benutzeprintf("%d" , *p)
.printf
lesen werden erste Byte ist11010010
der Ausgang nur ,-46
sondern11010010
ist210
so , warum gedruckt wird es-46
. Ich bin wirklich verwirrt, ich denke, ein Zeichen für eine ganzzahlige Werbung macht etwas, aber ich weiß es nicht.Wie zum Beispiel die Verwendung von nicht signiertem Zeichen :
unsigned char
wird häufig in Computergrafiken verwendet, die sehr oft (wenn auch nicht immer) jeder Farbkomponente ein einzelnes Byte zuweisen. Es ist üblich, eine RGB- (oder RGBA-) Farbe zu sehen, die als 24 (oder 32) Bits dargestellt wirdunsigned char
. Da dieunsigned char
Werte in den Bereich [0,255] fallen, werden die Werte normalerweise wie folgt interpretiert:Sie würden also RGB-Rot als (255,0,0) -> (100% Rot, 0% Grün, 0% Blau) erhalten.
Warum nicht ein
signed char
? Arithmetik und Bitverschiebung werden problematisch. Wie bereits erläutert,signed char
ist der Bereich von a im Wesentlichen um -128 verschoben. Eine sehr einfache und naive (meist nicht verwendete) Methode zum Konvertieren von RGB in Graustufen besteht darin, alle drei Farbkomponenten zu mitteln. Dies ist jedoch problematisch, wenn die Werte der Farbkomponenten negativ sind. Rot (255, 0, 0) ergibt bei Verwendung derunsigned char
Arithmetik einen Durchschnittswert von (85, 85, 85) . Wenn die Werte jedochsigned char
s (127, -128, -128) wären, würden wir am Ende (-99, -99, -99) haben, was (29, 29, 29) in unseremunsigned char
Raum wäre, was falsch ist .quelle
Wenn Sie ein Zeichen als kleine Ganzzahl verwenden möchten, ist es am sichersten, dies mit den Typen
int8_t
und zu tunuint8_t
.quelle
int8_t
unduint8_t
sind optional und nicht auf Architekturen definiert, bei denen die Bytegröße nicht genau 8 Bit beträgt. Umgekehrtsigned char
undunsigned char
sind immer verfügbar und halten garantiert mindestens 8 Bit. Es mag ein üblicher Weg sein, aber nicht der sicherste .signed char
und zu bleibenunsigned char
? Oder würden Sie in diesem speziellen Fall eine bessere "sicherere" Alternative empfehlen? Zum Beispiel, um bei den "echten" Ganzzahltypen zu bleibensigned int
undunsigned int
stattdessen aus irgendeinem Grund?signed char
undunsigned char
ist für alle konformen Implementierungen portierbar und spart Speicherplatz, kann jedoch zu einer gewissen Erhöhung der Codegröße führen. In einigen Fällen würde man mehr Speicherplatz sparen, indem kleine Werte in Bitfeldern oder einzelnen Bits regulärer Ganzzahltypen gespeichert werden. Es gibt keine absolute Antwort auf diese Frage, die Relevanz dieses Ansatzes hängt vom jeweiligen Einzelfall ab. Und diese Antwort spricht die Frage sowieso nicht an.unsigned char
nimmt nur positive Werte an .... wie 0 bis 255wohingegen
signed char
nimmt sowohl positive als auch negative Werte an .... wie -128 bis +127quelle
char
undunsigned char
es wird nicht garantiert, dass es sich auf allen Plattformen um 8-Bit-Typen handelt - es wird garantiert, dass sie 8-Bit oder größer sind. Einige Plattformen verfügen über 9-Bit-, 32-Bit- oder 64-Bit-Bytes . Die heute gängigsten Plattformen (Windows, Mac, Linux x86 usw.) haben jedoch 8-Bit-Bytes.quelle
signed char
hat einen Bereich von -128 bis 127;unsigned char
hat einen Bereich von 0 bis 255.char
wird je nach Compiler entweder einem signierten oder einem nicht signierten Zeichen entsprechen, ist jedoch ein eindeutiger Typ.Wenn Sie Zeichenfolgen im C-Stil verwenden, verwenden Sie einfach
char
. Wenn Sie Zeichen für die Arithmetik verwenden müssen (ziemlich selten), geben Sie für die Portabilität explizit signiert oder nicht signiert an.quelle
An
unsigned char
ist ein vorzeichenloser Bytewert (0 bis 255). Sie denken vielleicht daranchar
, ein "Zeichen" zu sein, aber es ist wirklich ein numerischer Wert. Der regulärechar
Wert ist signiert, sodass Sie 128 Werte haben. Diese Werte werden Zeichen mit ASCII-Codierung zugeordnet. In beiden Fällen ist das, was Sie im Speicher speichern, ein Bytewert.quelle
In Bezug auf direkte Werte wird ein reguläres Zeichen verwendet, wenn bekannt ist, dass die Werte zwischen
CHAR_MIN
undCHAR_MAX
während ein vorzeichenloses Zeichen den doppelten Bereich am positiven Ende liefert. Wenn beispielsweiseCHAR_BIT
8 ist,char
wird garantiert, dass der reguläre Bereich nur [0, 127] beträgt (da er signiert oder nicht signiert sein kann), währendunsigned char
er [0, 255] undsigned char
[-127, 127] ist.In Bezug auf das, wofür es verwendet wird, ermöglichen die Standards, dass Objekte von POD (einfache alte Daten) direkt in ein Array von Zeichen ohne Vorzeichen konvertiert werden. Auf diese Weise können Sie die Darstellung und die Bitmuster des Objekts untersuchen. Die gleiche Garantie für sicheres Punnen besteht nicht für char oder signiertes char.
quelle
unsigned char
, nicht als spezifisches Array , und jede "Konvertierung" wird nur formal definiert, indem vom Objekt in ein reales, deklariertes Array von & kopiert wird und dieses dann überprüft wird. Es ist nicht klar, ob das ODER direkt als solches Array neu interpretiert werden kann, mit den zulässigen Zeigerarithmetiken, dh ob "Sequenz" "Array" in dieser Verwendung. Es gibt ein Kernproblem Nr. 1701, in der Hoffnung, dies zu klären. Zum Glück, denn diese Zweideutigkeit nervt mich in letzter Zeit wirklich.unsigned char
==
unsigned char
des OP nehmen und dann++ptr
von dort aus jedes Byte davon lesen können ... aber AFAICT, es ist nicht speziell als erlaubt definiert, also sind wir es links zu schließen, dass es "wahrscheinlich in Ordnung" aus vielen anderen Passagen (und in vielerlei Hinsicht der bloßen Existenz vonmemcpy
) im Standard ist, ähnlich einem Puzzle. Welches ist nicht ideal. Nun, vielleicht wird sich der Wortlaut irgendwann verbessern. Hier ist das CWG-Problem, das ich erwähnt habe, aber es fehlte Platz zum Verknüpfen - open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1701unsigned char
ist das Herz aller kleinen Tricks. In fast ALLEN Compilern für ALLE Plattformenunsigned char
ist ein einfach ein Byte und eine vorzeichenlose Ganzzahl von (normalerweise) 8 Bits, die als kleine Ganzzahl oder als Bitpaket behandelt werden können.In der Sucht definiert der Standard, wie jemand anderes gesagt hat, nicht das Zeichen eines Zeichens. so haben Sie 3 verschiedene
char
Arten:char
,signed char
,unsigned char
.quelle
Wenn Sie verschiedene Arten von bestimmten Länge und Signedness wie verwendet, sind Sie wahrscheinlich besser dran mit
uint8_t
,int8_t
,uint16_t
, etc. , nur weil sie genau das tun , was sie sagen.quelle
Einige Googler fanden dies , wo die Leute darüber diskutierten.
Ein vorzeichenloses Zeichen ist im Grunde ein einzelnes Byte. Sie würden dies also verwenden, wenn Sie ein Datenbyte benötigen (z. B. möchten Sie damit möglicherweise Flags aktivieren und deaktivieren, die an eine Funktion übergeben werden sollen, wie dies häufig in der Windows-API der Fall ist).
quelle
Ein vorzeichenloses Zeichen verwendet das Bit, das für das Vorzeichen eines regulären Zeichens reserviert ist, als andere Zahl. Dies ändert den Bereich auf [0 - 255] im Gegensatz zu [-128 - 127].
Im Allgemeinen werden vorzeichenlose Zeichen verwendet, wenn Sie kein Zeichen möchten. Dies macht einen Unterschied, wenn Sie beispielsweise Bits verschieben (Shift erweitert das Vorzeichen) und andere Dinge, wenn Sie ein Zeichen als Byte behandeln, anstatt es als Zahl zu verwenden.
quelle
unsigned char
nimmt nur positive Werte an: 0 bis 255, währendsigned char
positive und negative Werte angenommen werden: -128 bis +127.quelle
zitiert aus dem Buch "The C Programming Laugage":
Das Qualifikationsmerkmal
signed
oderunsigned
kann auf char oder eine beliebige Ganzzahl angewendet werden. vorzeichenlose Zahlen sind immer positiv oder null und folgen den Gesetzen des arithmetischen Modulo 2 ^ n, wobei n die Anzahl der Bits im Typ ist. Wenn Zeichen beispielsweise 8 Bit sind, haben vorzeichenlose Zeichenvariablen Werte zwischen 0 und 255, während vorzeichenbehaftete Zeichen Werte zwischen -128 und 127 haben (in einer Zwei-Komplement-Maschine). Ob einfache Zeichen vorzeichenlos oder vorzeichenlos sind, ist Maschine -abhängige, aber druckbare Zeichen sind immer positiv.quelle
signed char
undunsigned char
beide repräsentieren 1 Byte, aber sie haben unterschiedliche Bereiche.In
signed char
wenn man bedenkt ,char letter = 'A'
‚A‘ darstellen, binär von 65 inASCII/Unicode
kann Wenn 65 gespeichert werden , -65 auch gespeichert werden können. Es gibt keine negativen Binärwerte inASCII/Unicode
sich keine Gedanken über negative Werte machen müssen.Beispiel
Ausgabe -:
quelle