Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"

Beitrag von Dirty Oerti » Sa Dez 18, 2010 8:27 pm

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:

Code: Alles auswählen

struct Byte
{
  unsigned int bit :1 [8];
};
Leider funktioniert das nicht ^^
Das ist doch etwas ärgerlich.
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"

Beitrag von cloidnerux » Sa Dez 18, 2010 8:32 pm

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;
}
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Jside
Beiträge: 377
Registriert: Di Nov 11, 2008 12:56 am

Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"

Beitrag von Jside » Sa Dez 18, 2010 8:37 pm

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^^))...

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"

Beitrag von Dirty Oerti » Sa Dez 18, 2010 11:12 pm

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:

Code: Alles auswählen

struct Daten
{
  unsigned int d[32];
}
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 :-P
Somit hab ich das Problem nicht ^^
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"

Beitrag von cloidnerux » Sa Dez 18, 2010 11:20 pm

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.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"

Beitrag von Kerli » So Dez 19, 2010 12:07 am

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...
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"

Beitrag von Dirty Oerti » So Dez 19, 2010 12:59 am

Kerli hat geschrieben:Das braucht man gar nicht selber schreiben. Das gibt es eh schon in der Standardbibliothek: => http://www.cplusplus.com/reference/stl/bitset/
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.
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Ein bisschen ärgerlich: C kennt keine Arrays aus "Bitfields"

Beitrag von Xin » So Dez 19, 2010 11:59 am

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.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten