Verwendung von Bitmask in C++
-
Verwenden von
struct
zum Definieren von Bitmasken und Implementieren von Datumsobjekten in C++ -
Benutzen Sie
struct
undunion
, um eine Bitmaske zu definieren und ein Datumsobjekt in C++ zu implementieren -
Verwenden von
std::bitset
zum Definieren von Bitmasken in C++
In diesem Artikel werden mehrere Methoden zur Verwendung von Bitmasken in C++ vorgestellt.
Verwenden von struct
zum Definieren von Bitmasken und Implementieren von Datumsobjekten in C++
struct
ist eine beliebte Datenstruktur in C++. Außerdem unterscheidet sie sich nur geringfügig von der class
im Gegensatz zur Sprache C. In diesem Fall müssen wir nur struct
mit mehreren Datenmitgliedern definieren, aber es wird eine neue Notation :
nach jedem Variablennamen und einer angegebenen Ganzzahl verwendet. Wie im Beispielcode gezeigt, haben wir ein struct
mit Datenmitgliedern vom Typ uint32_t
deklariert, und die Summe der Zahlen auf der rechten Seite ist 32. Diese Konstruktion impliziert, dass das struct
die Größe eines einzelnen uint32_t
-Datentyps im Speicher belegt und der Anwender auf seine Bitfeldbereiche (23:5:4) separat zugreifen kann.
Diese Methode wird meist verwendet, um Speicherplatz für Datenstrukturen zu sparen, die in ähnliche structs
gequetscht werden könnten. Es ist auch eine der üblichen Methoden, um in der Programmiersprache C++ auf kleinere Daten als ein Byte zuzugreifen. Beachten Sie, dass das erste Mitglied year
nur ganzzahlige Werte bis 223-1 aufnehmen kann und die anderen Mitglieder in ähnlicher Weise folgen.
#include <iostream>
using std::cout;
using std::endl;
struct {
uint32_t year : 23;
uint32_t day : 5;
uint32_t month : 4;
} typedef Bitfield;
int main() {
Bitfield date = {2020, 13, 12};
cout << "sizeof Bitfield: " << sizeof(date) << " bytes\n";
cout << "date: " << date.day << "/" << date.month << "/" << date.year << endl;
return EXIT_SUCCESS;
}
Ausgabe:
sizeof Bitfield: 4 bytes
date: 13/12/2020
Benutzen Sie struct
und union
, um eine Bitmaske zu definieren und ein Datumsobjekt in C++ zu implementieren
Die vorherige Methode ist eine ausreichende und korrekte Art, Bitmaske zu implementieren. Sie hat jedoch einen Nachteil - der Zugriff auf und die Zuweisung von Werten an Mitglieder nimmt relativ mehr Zeit in Anspruch als Operationen an eingebauten Typen. Dies kann durch die Implementierung eines Objekts vom Typ union
gelöst werden, das aus einem struct
und einer einzelnen Variablen vom eingebauten Typ besteht. Beachten Sie, dass das Layout von struct
das gleiche ist, das wir in der vorherigen Methode konstruieren würden. In diesem Fall ist der Unterschied die Variable uint32_t ydm
, die die gleiche Größe wie das struct
einnimmt.
Die Idee ist, die Datenmitglieder schneller zu initialisieren/ihren Werten zuzuweisen. Wir konstruieren nämlich eine Ganzzahl mit bitweisen Operationen, die genau dem Layout der Bits entsprechen, wenn sie im struct
gespeichert sind, und weisen sie dann einem einzelnen uint32_t
-Mitglied zu. Das spart Zeit, wenn man nur einmal auf die Daten zugreift, anstatt die gleiche Operation für jedes der drei Mitglieder zu wiederholen.
Bitweise Arithmetik ist relativ einfach; wir beginnen nämlich mit dem Wert des ersten Mitglieds im struct
, der mit dem Ergebnis des nächsten Mitglieds, das um die Anzahl der Bits, die das vorherige Mitglied belegt, nach links verschoben ist, ODER-verknüpft wird, und es folgt in ähnlicher Weise.
#include <iostream>
using std::cout;
using std::endl;
union BitfieldFast {
struct {
uint32_t year : 23;
uint32_t day : 5;
uint32_t month : 4;
};
uint32_t ydm;
};
int main() {
BitfieldFast date_f{};
date_f.ydm = 2020 | (13 << 23) | (12 << 28);
cout << "sizeof BitfieldFast: " << sizeof(date_f) << " bytes\n";
cout << "date: " << date_f.day << "/" << date_f.month << "/" << date_f.year
<< endl;
return EXIT_SUCCESS;
}
sizeof BitfieldFast: 4 bytes
date: 13/12/2020
Verwenden von std::bitset
zum Definieren von Bitmasken in C++
std::bitset
ist eine Standardbibliotheksfunktion, die die Klasse zum Speichern der binären Maskendaten enthält. bitset
hat mehrere nützliche Manipulationsfunktionen eingebaut, und die Deklaration ist recht mühelos. Es kann mit einem binären String
-Wert oder mehreren Zahlenwerten initialisiert werden. Bitweise Operationen sind eingebaute Methoden und können mit traditionellen Operatoren, die überladen sind, aufgerufen werden. Beachten Sie, dass die Methode reset
das Bitset
, von dem sie aufgerufen wird, permanent verändert.
#include <bitset>
#include <iostream>
using std::cout;
using std::endl;
int main() {
std::bitset<16> bs1("1100100011110010");
std::bitset<16> bs2(0xfff0);
cout << "bs1 : " << bs1 << endl;
cout << "bs2 : " << bs2 << endl;
cout << "NOT bs1 : " << ~bs1 << endl;
cout << "bs1 AND bs2: " << (bs1 & bs2) << endl;
cout << "bs1 reset : " << bs1.reset() << endl;
return EXIT_SUCCESS;
}
Ausgabe:
bs1 : 1100100011110010
bs2 : 1111111111110000
NOT bs1 : 0011011100001101
bs1 AND bs2: 1100100011110000
bs1 reset : 0000000000000000
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook