Seite 1 von 1
Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"
Verfasst: Sa Dez 18, 2010 8:27 pm
von Dirty Oerti
Tag zusammen
Ich habe heute feststellen müssen, dass C leider nicht in die Lage versetzt, Arrays aus Bitfeldern zu kreieren.
Folgendes funktioniert, wie wir ja alle wissen:
Code: Alles auswählen
struct Byte
{
unsigned int bit0 :1;
unsigned int bit1 :1;
unsigned int bit2 :1;
unsigned int bit3 :1;
unsigned int bit4 :1;
unsigned int bit5 :1;
unsigned int bit6 :1;
unsigned int bit7 :1;
};
So kann ich (auch im Programmcode gut leserlich) auf einzelne Bits zugreifen.
Wenn ich das nun aber für mehr Bits machen möchte, dann wird die Schreibarbeit ziemlich unangenehm...
Also wäre es doch schön, einfach das folgende tun zu können:
Leider funktioniert das nicht ^^
Das ist doch etwas ärgerlich.
Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"
Verfasst: Sa Dez 18, 2010 8:32 pm
von cloidnerux
Das ist doch etwas ärgerlich.
Aber du kannst dir Helfen:
Code: Alles auswählen
int GetBit(int flags, int index)
{
return (flags >> index) & 1;
}
oder Für viele Flags:
Code: Alles auswählen
for(int i = 0; i < flagsCount; i++)
{
int myFlag = (flags >> i) & 1;
}
Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"
Verfasst: Sa Dez 18, 2010 8:37 pm
von Jside
Mhmhm mach doch ne funktion die bei dem gegeben Index den Bit setzt/lie[ss]t oder wenn du C++ benutzt erstell dir doch ne Klasse fuer und lade den array accessor Operator ueber.
Code: Alles auswählen
void set_bit(unsigned int *d, unsigned char idx) {
if(sizeof(unsigned int) * 8 <= idx) return;
(*d) |= 1<<idx;
}
Pass aber auf es gibt auch Systeme bei denen ein Byte 4 oder 6Bit hat(auch wenn du warscheinlich niemals etwas mit denen zutun haben wirst(sind naemlich schon in die Jahre gekommen^^))...
Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"
Verfasst: Sa Dez 18, 2010 11:12 pm
von Dirty Oerti
Naja, ich meinte damit nicht, dass ich deswegen nicht viele Bits ansprechen kann

Es ist nur ärgerlich ^^
Etwas ala bit[4] wäre natürlich perfekt leserlich gewesen.
Im Endeffekt mach ich das so:
Das sind jetzt 4*32 = 128 Byte = 1024 Bit
Code: Alles auswählen
struct Daten daten;
unsigned int wert;
unsigned int bit = 234;
wert = (daten.d[bit/32] >> (bit%32)) & 1;
Zumindest, wenn ich das grad richtig im Kopf hab ^^
Das ein Byte nicht unbedingt 8 Bit sind ist klar, ich unterstütze aber nur Systeme, bei denen ein Byte 8 Bit breit ist

Somit hab ich das Problem nicht ^^
Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"
Verfasst: Sa Dez 18, 2010 11:20 pm
von cloidnerux
Naja, ich meinte damit nicht, dass ich deswegen nicht viele Bits ansprechen kann

Es ist nur ärgerlich ^^
Etwas ala bit[4] wäre natürlich perfekt leserlich gewesen.
Wie Jside erwähnt hat, du kannst in einer Klasse den Indexoperator überladen.
Zudem kann der GCC auch nicht anders als mit Shift und & das Bit erreichen.
Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"
Verfasst: So Dez 19, 2010 12:07 am
von Kerli
Das braucht man gar nicht selber schreiben. Das gibt es eh schon in der Standardbibliothek: =>
http://www.cplusplus.com/reference/stl/bitset/
Ansonsten kannst du das anstatt zu tippen, auch mit Macros lösen (
http://www.boost.org/doc/libs/release/l ... index.html). Ist aber vermutlich keine sehr schöne Lösung...
Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"
Verfasst: So Dez 19, 2010 12:59 am
von Dirty Oerti
cloidnerux hat geschrieben:Wie Jside erwähnt hat, du kannst in einer Klasse den Indexoperator überladen.
Still @ C != C++
Natürlich kann ich mir entsprechende Funktionen schreiben
cloidnerux hat geschrieben:Zudem kann der GCC auch nicht anders als mit Shift und & das Bit erreichen.
Ja, das ist klar, folgt aus der Definition des Bytes.
Mir ging es in diesem Fall nur um die "Leserbarkeit" bzw die einfache Möglichkeit, das aufzuschreiben.
Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"
Verfasst: So Dez 19, 2010 11:59 am
von Xin
Bei meinem Compiler gehe ich auf 256 Zeichen ein. Bei jedem Zeichen unterscheide ich, ob es Symbole trennt oder Teil eines Symbols oder Schlüsselwortes sein kann.
Macht 256 Ja/Nein-Informationen, also 256 Bit. 256 Bit sind 32 Byte.
Code: Alles auswählen
class Language : public SubTypeable
, public XSD::Util::CNamedNode<Language> // LanguageList
{
...
/* SeperatorArray
** Enth�lt die Informationen, ob ein ASCII-Zeichen als Trennsymbol fungiert oder nicht.
** Je 1 Bit pro Zeichen.
*/
char SeperatorArray[32];
void AddSeperator(unsigned char);
void RemSeperator(unsigned char);
bool IsSeperator(unsigned char);
...
};
Und die dafür erforderlich Implementierung:
Code: Alles auswählen
void Language::AddSeperator(unsigned char t)
{
SeperatorArray[ t >> 3 ] |= (1 << (t & 7));
}
bool Language::IsSeperator(unsigned char t)
{
return 0 != ( SeperatorArray[ t >> 3 ] & (1 << (t & 7)) );
}
void Language::RemSeperator(unsigned char t)
{
SeperatorArray[ t >> 3 ] &= ~(1 << (t & 7));
}
Der unsigned char ist der Index, andere Indize-Größen sind allerdings genauso drin.
Das ganze kannst Du natürlich in einer eigenen Klasse mit dem operator[] abbilden - was vermutlich eine gute Idee wäre.