Daten eines Bitfeldes via for/Next nutzen

Gast #4161002
Lesenswert?
• ▲
▼
Hallo.

Ich würde gerne mit einer For/Next Schleife auf ein Bitfeld zugreifen 
und weiß grade nicht wie ich dies in dieser Situation machen soll.

Bitfeld:
1
uint8_t testdata[10] = {1};
2

3
struct data
4
  {
5
    uint8_t bit1: 1;
6
    uint8_t bit2: 1;
7
    uint8_t bit3: 1;
8
    uint8_t bit4: 1;
9
    uint8_t bit5: 1;
10
    uint8_t bit6: 1;
11
    uint8_t bit7: 1;
12
    uint8_t bit8: 1;
13
    uint8_t bit9: 1;
14
    uint8_t bit10: 1;
15
  } ReceiveBuffer;

nun möchte ich z.B. ein Array oder was auch immer in diese Struktur 
kopieren:
1
for (i=0;i<10;i++)
2
{
3
    ReceiveBuffer.bit & i = testdata[i];
4
}

Mit dem  "*.bit & i" soll nur verdeutlichen wo gerade mein Problem ist 
;)
Dass der Syntax nicht stimmt ist ja logisch...

Ich dachte zuerst ich kopiere an die Struct-Adresse + i eine 1 oder 0, 
aber laut Doku wird das Struct ja im Speicherbereich nicht zwingend 
hintereinander angelegt.

Wie muss ich das denn schreiben, dass ich es nutzen kann?
Oder gibt es hier gar keine Lösung?

Danke fürs überlegen und nun erst einmal gute Nacht!
#4161128
Lesenswert?
• ▲
▼
Verwende niemals Bitfields! Auch wenn man damit etwas Platzsparen kann, 
bool ist meistens schneller. Bitfields sind zum Aufbereiten Empfangener 
Daten sowie dem Speichern derselben ungeeignet. Man kann sich über die 
Reihenfolge von Bitferldern nie Sicher sein. Ich empfehle sowas:

Ungetestet:
1
#define DEC_BITS(T,ID,N) T ID[((N)+sizeof(T)*8-1)/sizeof(T)/8]
2
#define GET_BIT(ID,I) (((unsigned char*)(ID))[(I)/8]&(1<<((I)&7)))
3
#define SET_BIT(ID,I) (((unsigned char*)(ID))[(I)/8]|=(1<<((I)&7)))
4
#define UNSET_BIT(ID,I) (((unsigned char*)(ID))[(I)/8]&=(1<<((I)&7)))
5
#define SET_BIT_TO(ID,I,X) ((void)((X)?SET_BIT(ID,I):UNSET_BIT(ID,I)),(X))
6

7
struct data {
8
  DEC_BITS(uint8_t,bit,10);
9
} ReceiveBuffer;
1
for(i=0;i<10;i++){
2
  (void)SET_BIT_TO(ReceiveBuffer.bit,i,testdata[i]);
3
}
#4161235
Lesenswert?
• ▲
▼
Rufus Τ. Firefly schrieb:
> Daniel A. schrieb:
>> Man kann sich über die Reihenfolge von Bitferldern nie Sicher sein.
>
> Was verleitet Dich zu dieser Annahme?

Ich kann das nur mit K&R bestätigen. Unter anderem schreiben die beiden:
1
Almost everything about fields is implementation-dependent. 
2
Whether a field may overlap a word boundary is implementation-defined...
3
Fields are assigned left to right on some machines and right to left on others. 
4
This means that although fields are useful for maintaining internally-defined 
5
data structures, the question of which end comes first has to be carefully
6
considered when picking apart externally-defined data; 
7
programs that depend on such things are not portable.
Gast #4163488
Lesenswert?
• ▲
▼
Hi da.

Vielen Dank für die Tips!

Werde das Ganze dann doch mit einer Variable und Bitmanipulation regeln.
Schade, die Struktur hätte man schön im Debugger ansehen können.
Leider kann das AtmelStudio ja nur DEZ und HEX als Anzeige.

Schönes Wochenende!
Gast #4163518
Lesenswert?
• ▲
▼
Daniel A. schrieb:
> Verwende niemals Bitfields! Auch wenn man damit etwas Platzsparen kann,
> bool ist meistens schneller. Bitfields sind zum Aufbereiten Empfangener
> Daten sowie dem Speichern derselben ungeeignet. Man kann sich über die
> Reihenfolge von Bitferldern nie Sicher sein. Ich empfehle sowas:

irgendwie verwechselst du was ...

Das mit der Reihenfolge ist wegen Little/Big Endian.
Und bei ARM gibt es effiziente Befehle zum setzen/löschen/abfragen von 
Bits.
#4163563
Lesenswert?
• ▲
▼
Hans Ulli Kroll schrieb:
> Daniel A. schrieb:
>> Verwende niemals Bitfields! Auch wenn man damit etwas Platzsparen kann,
>> bool ist meistens schneller. Bitfields sind zum Aufbereiten Empfangener
>> Daten sowie dem Speichern derselben ungeeignet. Man kann sich über die
>> Reihenfolge von Bitferldern nie Sicher sein. Ich empfehle sowas:
>
> irgendwie verwechselst du was ...
>
> Das mit der Reihenfolge ist wegen Little/Big Endian.

Das wurde hier bereits ausgibig besprochen:
Beitrag "Re: rechnet der preprocessor in C gcc (AVR) multiplikation aus?"
Bitordering wird nur von ABI definiert. Ich sage das nur deshalb so 
dramatisch, damit niemand auf die Idee kommt meinen Fehler zu 
wiederholen und bitfelder zum Parsen, Speichern, etc. von Daten 
verwendet. Eine andere Platform, oder ein ABI change mit einer neuen 
Compilerversion, und die Reihenfolge kann schonwieder ganz anders 
Aussehen.


> Und bei ARM gibt es effiziente Befehle zum setzen/löschen/abfragen von
> Bits.

Das mag sein, aber um diese zu nutzen ist man ja nicht zwangslaufig auf 
Bitfields angewiesen. Ich habe noch nie einen fall gesehen, in welchem 
diese einen echten Vorteil bieten. Natürlich gibt es Spezialfälle, in 
welchen diese sinvoll sind, aber die sind sehr selten.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.