Was ist der Vorteil der Verwendung von uint8_t
mehr als unsigned char
in C?
Ich weiß, dass auf fast jedem System uint8_t
nur ein Typedef für ist unsigned char
, warum also verwenden?
Es dokumentiert Ihre Absicht - Sie speichern kleine Zahlen anstelle eines Zeichens.
Es sieht auch besser aus, wenn Sie andere Typedefs wie uint16_t
oder verwenden int32_t
.
unsigned char
odersigned char
Dokumentation der Absicht, da schmuckloschar
zeigt, dass Sie mit Charakteren arbeiten.unsigned
warunsigned int
per Definition?char
scheint dies ein Zeichen zu implizieren, während es im Kontext einer UTF8-Zeichenfolge nur ein Byte eines Multibyte-Zeichens sein kann. Die Verwendung von uint8_t könnte klarstellen, dass man nicht an jeder Position ein Zeichen erwarten sollte - mit anderen Worten, dass jedes Element des Strings / Arrays eine beliebige Ganzzahl ist, über die man keine semantischen Annahmen treffen sollte. Natürlich wissen das alle C-Programmierer, aber es kann Anfänger dazu bringen, die richtigen Fragen zu stellen.Um pedantisch zu sein, haben einige Systeme möglicherweise keinen 8-Bit-Typ. Laut Wikipedia :
Es
uint8_t
ist also nicht garantiert, dass es existiert, obwohl dies für alle Plattformen gilt, bei denen 8 Bit = 1 Byte sind. Einige eingebettete Plattformen mögen unterschiedlich sein, aber das wird sehr selten. Einige Systeme definierenchar
Typen möglicherweise als 16-Bit. In diesem Fall gibt es wahrscheinlich keinen 8-Bit-Typ.Abgesehen von diesem (kleinen) Problem ist die Antwort von @Mark Ransom meiner Meinung nach die beste. Verwenden Sie diejenige, die am deutlichsten zeigt, wofür Sie die Daten verwenden.
Ich gehe auch davon aus, dass Sie dies gemeint haben
uint8_t
(das Standard-Typedef von C99 imstdint.h
Header) und nichtuint_8
(nicht Teil eines Standards).quelle
uint8_t
(oder dazu tippen) darf . Dies liegt daran, dass der 8-Bit-Typ nicht verwendete Bits in der Speicherdarstellung enthalten würde, dieuint8_t
nicht vorhanden sein dürfen.typedef unsigned integer type uint8_t; // optional
Daher ist im Wesentlichen keine C ++ - Standardkonforme Bibliothek erforderlich, um uint8_t überhaupt zu definieren (siehe Kommentar // optional) )Der springende Punkt ist, implementierungsunabhängigen Code zu schreiben.
unsigned char
Es wird nicht garantiert, dass es sich um einen 8-Bit-Typ handelt.uint8_t
ist (falls verfügbar).quelle
sizeof(unsigned char)
wird1
für 1 Byte zurückgegeben. aber wenn ein System char und int die gleiche Größe von z. B. 16 Bit haben,sizeof(int)
wird auch zurückgegeben1
Wie Sie sagten, " fast jedes System".
char
ist wahrscheinlich eine der weniger wahrscheinlichen Änderungen, aber sobald Sie anfangen,uint16_t
und Freunde zu verwenden, verwenden Sieuint8_t
Mischungen besser und können sogar Teil eines Codierungsstandards sein.quelle
Nach meiner Erfahrung gibt es zwei Stellen, an denen uint8_t 8 Bit (und uint16_t usw.) bedeuten soll und an denen Felder kleiner als 8 Bit sein können. An beiden Stellen kommt es auf den Speicherplatz an, und beim Debuggen müssen wir uns häufig einen Rohdatenauszug der Daten ansehen und schnell feststellen können, was diese darstellen.
Das erste betrifft HF-Protokolle, insbesondere in Schmalbandsystemen. In dieser Umgebung müssen wir möglicherweise so viele Informationen wie möglich in eine einzelne Nachricht packen. Der zweite ist im Flash-Speicher, wo wir möglicherweise nur sehr begrenzten Speicherplatz haben (z. B. in eingebetteten Systemen). In beiden Fällen können wir eine gepackte Datenstruktur verwenden, in der der Compiler das Packen und Entpacken für uns übernimmt:
Welche Methode Sie verwenden, hängt von Ihrem Compiler ab. Möglicherweise müssen Sie auch mehrere verschiedene Compiler mit denselben Header-Dateien unterstützen. Dies geschieht in eingebetteten Systemen, in denen Geräte und Server völlig unterschiedlich sein können. Beispielsweise verfügen Sie möglicherweise über ein ARM-Gerät, das mit einem x86-Linux-Server kommuniziert.
Es gibt einige Einschränkungen bei der Verwendung gepackter Strukturen. Das größte Problem ist, dass Sie vermeiden müssen, die Adresse eines Mitglieds zu dereferenzieren. Auf Systemen mit mutibyte-ausgerichteten Wörtern kann dies zu einer falsch ausgerichteten Ausnahme führen - und zu einem Coredump.
Einige Leute werden sich auch Sorgen um die Leistung machen und argumentieren, dass die Verwendung dieser gepackten Strukturen Ihr System verlangsamen wird. Es ist richtig, dass der Compiler hinter den Kulissen Code hinzufügt, um auf die nicht ausgerichteten Datenelemente zuzugreifen. Sie können dies anhand des Assembler-Codes in Ihrer IDE sehen.
Da gepackte Strukturen für die Kommunikation und Datenspeicherung am nützlichsten sind, können die Daten beim Arbeiten damit im Speicher in eine nicht gepackte Darstellung extrahiert werden. Normalerweise müssen wir sowieso nicht mit dem gesamten Datenpaket im Speicher arbeiten.
Hier ist eine relevante Diskussion:
Pragma Pack (1) noch __attribute__ ((ausgerichtet (1))) funktionieren
Ist das __attribute __ ((gepackt)) / #pragma pack von gcc unsicher?
http://solidsmoke.blogspot.ca/2010/07/woes-of-structure-packing-pragma-pack.html
quelle
Es gibt wenig. Unter dem Gesichtspunkt der Portabilität
char
kann nicht kleiner als 8 Bit sein, und nichts kann kleiner sein alschar
. Wenn also eine bestimmte C-Implementierung einen vorzeichenlosen 8-Bit-Integer-Typ hat, wird dies der Fall seinchar
. Alternativ kann es sein, dass es zu diesem Zeitpunkt überhaupt keine gibttypedef
gibt. Zu Tricks umstritten.Es könnte verwendet werden, um Ihren Code in dem Sinne besser zu dokumentieren, dass klar ist, dass Sie dort 8-Bit-Bytes und sonst nichts benötigen. In der Praxis ist dies jedoch praktisch überall eine vernünftige Erwartung (es gibt DSP-Plattformen, auf denen dies nicht der Fall ist, aber die Wahrscheinlichkeit, dass Ihr Code dort ausgeführt wird, ist gering, und Sie können genauso gut einen Fehler machen, wenn Sie eine statische Zusicherung oben in Ihrem Programm verwenden eine solche Plattform).
quelle
unsigned char
in der Lage sein, Werte zwischen 0 und 255 zu halten. Wenn Sie dies in 4 Bits tun können, ist mein Hut vor Ihnen.uint8_t
zur Implementierung hinzufügen . Ich frage mich, ob Compiler für DSPs mit 16-Bit-Zeichen normalerweise implementiertuint8_t
werden oder nicht.#include <stdint.h>
und zu verwendenuint8_t
. Wenn die Plattform es hat, wird es Ihnen geben. Wenn die Plattform es nicht hat, wird Ihr Programm nicht kompiliert und der Grund ist klar und unkompliziert.Das ist zum Beispiel sehr wichtig, wenn Sie einen Netzwerkanalysator schreiben. Paket-Header werden durch die Protokollspezifikation definiert, nicht durch die Funktionsweise des C-Compilers einer bestimmten Plattform.
quelle
Auf fast jedem System habe ich uint8_t == unsigned char getroffen, aber dies wird vom C-Standard nicht garantiert. Wenn Sie versuchen, tragbaren Code zu schreiben und es genau darauf ankommt, wie groß der Speicher ist, verwenden Sie uint8_t. Verwenden Sie andernfalls ein Zeichen ohne Vorzeichen.
quelle
uint8_t
Entspricht immer dem Bereich und der Größe vonunsigned char
und dem Auffüllen (keine), wennunsigned char
es sich um 8-Bit handelt. Wennunsigned char
nicht 8-Bit ist,uint8_t
existiert nicht.unsigned char
es sich um 8-Bit handelt, handelt es sichuint8_t
garantiert um einetypedef
davon und nichttypedef
um eine erweiterte vorzeichenlose Ganzzahl ?unsigned char/signed char/char
wie der kleinste Typ - nicht kleiner als 8 Bit.unsigned char
hat keine Polsterung. Umuint8_t
zu sein, muss es 8-Bit sein, keine Auffüllung, da aufgrund einer Implementierung ein ganzzahliger Typ bereitgestellt wird: der den Mindestanforderungen von entsprichtunsigned char
. "... garantiert ein typedef ..." scheint eine gute Frage zu sein.