Ist es möglich, in C einen Datentyp der Länge ein Bit zu erstellen?
Lesezeit: 5 Minuten
Im Wesentlichen möchte ich einen Datentyp erstellen uint1_t. Ist das überhaupt möglich?
Ich weiß, dass die Größe des Bool-Datentyps ein Byte ist. Aber boolesche Werte benötigen nur ein Bit. Verwendet C also im Wesentlichen nur ein Bit für bool? Wenn ja, was macht es dann mit den anderen sieben? Die Verwendung von acht Bits, wo eines ausreicht, scheint eine solche Platzverschwendung zu sein.
Nein, Sie müssen Vielfache von Bytes verwenden.
– Chris
12. August 2014 um 15:20 Uhr
Sie können einzelne Bits adressieren, aber auf Speicherebene ist die kleinstmögliche Zuordnung ein Byte.
– Markus B
12. August 2014 um 15:21 Uhr
Wie viele uint1_ts willst du? Wenn Sie nur 1 möchten, erhalten Sie mindestens 8.
– jxh
12. August 2014 um 16:03 Uhr
Jonathan Leffler
Es ist nicht wirklich möglich, einen Typ zu erstellen, der ein Bit belegt. Die kleinste adressierbare Einheit in C ist die char (was per Definition ein Byte ist und normalerweise, aber nicht notwendigerweise, 8 Bit lang ist; es kann länger sein, darf aber in Standard C nicht kürzer als 8 Bit sein).
Sie können sich ihm nähern mit:
typedef _Bool uint1_t;
oder:
#include <stdbool.h>
typedef bool uint1_t;
aber es belegt (mindestens) ein Byte, obwohl eine boolesche Variable nur die Werte 0 oder 1 speichert, false oder true.
Sie könnten im Prinzip ein Bitfeld verwenden:
typedef struct
{
unsigned int x : 1;
} uint1_t;
aber das belegt auch mindestens ein Byte (und möglicherweise so viele Bytes wie eine unsigned int; das sind normalerweise 4 Bytes) und Sie müssen verwenden .x um auf den Wert zuzugreifen. Die Verwendung von Bitfeldern ist problematisch (die meisten Aspekte davon sind implementierungsdefiniert, z. B. wie viel Platz die Speichereinheit, die sie enthält, belegen wird) – verwenden Sie keine Bitfelder.
Einschließlich der von Drew McGowen, Drax und Fiddling Bits vorgeschlagenen Änderungen.
Im Gegensatz zu dem, was manche Leute glauben, dort ist ein Datentyp von einem Bit in C99: es heißt _Bool. Sie können auch Bitfelder der Größe 1 deklarieren. Die Tatsache, dass einzelne Bits in C nicht adressierbar sind, schon nicht bedeutet, dass Ein-Bit-Datentypen nicht existieren können. Dieses Argument vergleicht im Grunde Äpfel mit Birnen.
Es gibt jedoch keinen Typ, dessen Speichergröße (sizeof) ist kleiner als ein Byte.
Sie müssen zwischen der Speichergröße von unterscheiden _Bool (der nicht kleiner als ein Byte sein wird) und den Wertebereich für den Typ (der tatsächlich nur den Wert eines Bits hat – 0 oder 1, falsch oder wahr).
– Jonathan Leffler
12. August 2014 um 15:30 Uhr
Bits und Bytes sind Größeneinheiten, Sie können nicht sagen, dass es einen Datentyp von einem Bit gibt, wenn seine Größe ein Byte beträgt, selbst wenn Sie den Rest nicht verwenden. Dies bedeutet, dass 1 Orange 8 Orangen sind, weil Sie die 7 anderen nicht gegessen haben.
– Drax
12. August 2014 um 15:34 Uhr
@JonathanLeffler das ist exakt Was mache ich.
– Das paramagnetische Croissant
12. August 2014 um 16:49 Uhr
Nein, das ist nicht möglich, uint8_t ist der kleinste Datentyp. Innerhalb von struct könnten Sie Bitfelder verwenden, außerdem ist es nicht möglich, einen Datentyp von nur 1 Bit zu haben.
Ich würde die Verwendung von Bitfeldern jedoch nicht empfehlen, außer wenn sie wirklich praktisch sind (zum Beispiel um Protokollheader zu fälschen).
– Rerit
12. August 2014 um 15:22 Uhr
Beachten Sie, dass dies nicht bedeutet, dass Sie einfach tun können typedef struct Bool {unsigned value : 1;} Bool; und erwarten Bool etwas groß sein. Bei mir sind es vier Bytes.
– Chris
12. August 2014 um 15:23 Uhr
Bill Lynch
Das kleinste Objekt, das Sie erstellen können, hat a sizeof == 1. Dieses Objekt wird CHAR_BIT Bits groß, was auf fast jeder Plattform, die Sie jemals sehen werden, 8 sein wird.
Das kleinste Objekt, das Sie erstellen können, ist also a int8_t auch bekannt char.
Sie können Dinge mit Bitfeldern tun, um viele 1-Bit-Zahlen in ein größeres Objekt zu codieren, aber das ist nicht gerade eine Lösung für Ihr Problem.
Am ehesten kommen Sie zu so etwas, indem Sie Bitfelder verwenden. Sie werden innerhalb von a eingerichtet struct und jedes Feld der struct bestimmt seine Breite.
Beispiel:
struct foo
{
unsigned int bla :1; /* this uses only 1 bit */
}
Dieser Fall “verschwendet” immer noch die anderen Teile des int aber wenn Sie andere Felder hätten, könnten Sie jedes Bit davon effektiv nutzen int um einen booleschen Wert darzustellen
Kurze Antwort ist “nein”; mit Ausnahme von Bitfeldern alle Typen muss auf eine ganze Anzahl von Bytes abbilden (und mehrere Bitfelder belegen dasselbe Byte, wenn sie alle passen).
1 Die Darstellungen aller Arten sind nicht spezifiziert, außer wie in diesem Unterabschnitt angegeben.
2 Mit Ausnahme von Bitfeldern bestehen Objekte aus zusammenhängenden Folgen von einem oder mehreren Bytes, deren Anzahl, Reihenfolge und Kodierung entweder explizit angegeben oder durch die Implementierung definiert sind.
3 Werte, die in vorzeichenlosen Bitfeldern und Objekten vom Typ unsigned char gespeichert sind, müssen in reiner Binärschreibweise dargestellt werden.49)
4 Werte, die in Nicht-Bitfeld-Objekten eines anderen Objekttyps gespeichert sind, bestehen aus n × CHAR_BIT
Bits, wo n ist die Größe eines Objekts dieses Typs in Byte. Der Wert kann in ein Objekt des Typs kopiert werden unsigned char [n] (zB durch memcpy); Die resultierende Gruppe von Bytes wird als the bezeichnet Objektdarstellung des Wertes. In Bitfeldern gespeicherte Werte bestehen aus m Bits, wo m ist die für das Bitfeld angegebene Größe. Die Objektdarstellung ist die Menge von m
Bits, die das Bitfeld in der es enthaltenden adressierbaren Speichereinheit umfasst. Zwei Werte (außer NaNs) mit derselben Objektdarstellung sind im Vergleich gleich, aber Werte, die im Vergleich gleich sind, können unterschiedliche Objektdarstellungen haben
49) Eine Positionsdarstellung für ganze Zahlen, die die Binärziffern 0 und 1 verwendet, bei der die durch aufeinanderfolgende Bits dargestellten Werte additiv sind, mit 1 beginnen und mit aufeinanderfolgenden ganzzahligen Potenzen von 2 multipliziert werden, außer vielleicht dem Bit mit der höchsten Position. (Adaptiert aus dem American National Dictionary für Informationsverarbeitungssysteme.) Ein Byte enthält CHAR_BIT Bits und die Werte von type unsigned char reichen von 0 bis 2CHAR_BIT − 1.
Shreemay Panhalkar
Ja, Sie können eine Ein-Bit-Variable erstellen, angenommen int a:1; Sie können ihm nur einen Wert zuweisen, aber nicht scannen.
13711100cookie-checkIst es möglich, in C einen Datentyp der Länge ein Bit zu erstellen?yes
Nein, Sie müssen Vielfache von Bytes verwenden.
– Chris
12. August 2014 um 15:20 Uhr
Sie können einzelne Bits adressieren, aber auf Speicherebene ist die kleinstmögliche Zuordnung ein Byte.
– Markus B
12. August 2014 um 15:21 Uhr
Wie viele
uint1_t
s willst du? Wenn Sie nur 1 möchten, erhalten Sie mindestens 8.– jxh
12. August 2014 um 16:03 Uhr