HI, ich habe eine Frage zum Thema Bitfeld in Struct in Union. Es geht mir dabei um einen Datentyp bestehend aus 8 Bits, welche man entweder gemeinsam oder einzeln ansprechen können soll. Ich würde in meinem Programm gern folgendes schreiben können: typedef struct { uint8_t bit0:1, bit1:1, bit2:1, bit3:1, bit4:1, bit5:1, bit6:1, bit7:1, }meintyp; void func1 (meintyp a) { } void main (void) { uint8_t zahl=0; meintyp_t a; a=4; a=zahl; a.bit0=1; a.bit1=1; func1(a); func1(23); } Wie kann ich das lösen? Wenn ich es so gestalte: typedef union { uint8_t byte; uint8_t bit0:1, bit1:1, bit2:1, bit3:1, bit4:1, bit5:1, bit6:1, bit7:1, }bits; }meintyp; dann müsste ich doch: void main (void) { uint8_t zahl=0; meintyp_t a; a.byte=4; a.byte=zahl; a.bit0=1; a.bit1=1; .... } schreiben oder!? Gruß, Hannes
1 | typedef union |
2 | {
|
3 | uint8_t byte; |
4 | struct
|
5 | {
|
6 | unsigned bit0:1; |
7 | unsigned bit1:1; |
8 | unsigned bit2:1; |
9 | unsigned bit3:1; |
10 | unsigned bit4:1; |
11 | unsigned bit5:1; |
12 | unsigned bit6:1; |
13 | unsigned bit7:1; |
14 | };
|
15 | } meintyp_t; |
16 | |
17 | int main (void) |
18 | {
|
19 | uint8_t zahl=0; |
20 | meintyp_t a; |
21 | |
22 | a.byte=4; |
23 | a.byte=zahl; |
24 | |
25 | a.bit0=1; |
26 | a.bit1=1; |
27 | return 0; |
28 | }
|
Klaus Wachtler schrieb:
1 | unsigned bit0:1; |
Wenn man da das "unsigned" weglässt, nimmt er dann ein Bit fürs Vorzeichen? ;-)
Wenn du unsigned weglässt, geht gar nichts mehr, weil der Typ fehlt. Lässt du nur das un weg und machst dann folgendes:
1 | a.bit1=1; |
2 | printf( "%d\n", a.bit1 ); |
.. kommt das raus:
1 | klaus@i4a:~ > gcc -Wall t.c && ./a.out |
2 | -1 |
Alle gesetzten Bit in einer signed sind offenbar wie üblich -1 :-)) Je nach Fall ist es egal, ein Bit wird man eh nur auf gleich oder ungleich 0 testen. Ein Vergleich mit 1 wird aber lustige Folgen haben.
Klaus Wachtler schrieb:
>
1 | > typedef union |
2 | > { |
3 | > uint8_t byte; |
4 | > struct |
5 | > { |
6 | > unsigned bit0:1; |
7 | > unsigned bit1:1; |
8 | > unsigned bit2:1; |
9 | > unsigned bit3:1; |
10 | > unsigned bit4:1; |
11 | > unsigned bit5:1; |
12 | > unsigned bit6:1; |
13 | > unsigned bit7:1; |
14 | > }; |
15 | > } meintyp_t; |
16 | >
|
Anonyme struct members sind zwar äußerst praktisch, aber leider nicht standardkonform und werden daher nicht von allen Compilern unterstützt. GCC und ARM RealView (mit entsprechendem #pragma) erlauben dieses Konstrukt. Gruß Marcus http://www.doulos.com/arm/
@Hallo KLaus, danke für die Rückmeldung doch mein eigentliches Problem kommt erst noch. @Marcus Harnisch, das ist in diesem Fall ohne Folge da ich keinen datenaustausch auf unterschiedlichen Architekturen ausführen werde und keine unterschiedlichen Kompiler nutze, und der Code nur auf einem Prozessor laufen wird. Zumal das ganze nur zur internen Verwaltung innerhalb eines geschachtelten abgeschlossenen c Objektes zum Einsatz kommt. 1) fehlt vor den bits des bitfeldes nicht der typ, oder ist unvollständig? oder geht das, weil es eine union ist? das sieht komisch aus. 2) soweit das ich das schreiben kann: uint8_t zahl=0; meintyp_t a; a.byte=4; a.byte=zahl; a.bit0=1; a.bit1=1; return 0; war ich schon, nur ich würde das gern so schreiben können: void func1 (meintyp a) { } void main (void) { uint8_t zahl=0; meintyp_t a; a=4; a=zahl; a.bit0=1; a.bit1=1; func1(a); func1(23); } ohne das .byte wenn ich einen 8bit wert zuweise, und wenn eine Funktion diesen typ als übergabetyp hat, dann würde ich sie gern wie oben aufgezeigt aufrufen können - geht das? die 23 kann nicht zugewiesen werden, wie bekomme ich das hin, ohne vorher auf das "objekt" zu zeigen, von hinten durch die brust. Cast schlägt auch fehl...deswegen ja die Geschichte mit der union... Gruß, Hannes
Hannes schrieb: > ... > 1) > fehlt vor den bits des bitfeldes nicht der typ, oder ist unvollständig? > oder geht das, weil es eine union ist? das sieht komisch aus. unsigned ist ein Typ; du kannst auch unsigned int schreiben, wenn dir das lieber ist. signes ist int ebenso wie signed int, und unsigned ist unsigned int, und short ist short int etc. > > 2) > soweit das ich das schreiben kann: > > uint8_t zahl=0; > meintyp_t a; > > a.byte=4; > a.byte=zahl; > > a.bit0=1; > a.bit1=1; > return 0; > > war ich schon, nur ich würde das gern so schreiben können: > > void func1 (meintyp a) > { > > > } > > > void main (void) > { > uint8_t zahl=0; > meintyp_t a; > > a=4; > a=zahl; > a.bit0=1; > a.bit1=1; > > func1(a); > func1(23); > } > > ohne das .byte wenn ich einen 8bit wert zuweise, und wenn eine Funktion > diesen typ als übergabetyp hat, dann würde ich sie gern wie oben > aufgezeigt aufrufen können - geht das? nein. Bzw. nur mit cast, aber dann kannst du auch .byte schreiben. > > die 23 kann nicht zugewiesen werden, wie bekomme ich das hin, ohne > vorher auf das "objekt" zu zeigen, von hinten durch die brust. Cast > schlägt auch fehl...deswegen ja die Geschichte mit der union... nicht in C, in C++ geht es mit Überladen von Operatoren.. > > Gruß, > Hannes
> typedef union > { > uint8_t byte; > struct > { > unsigned bit0:1; > unsigned bit1:1; > unsigned bit2:1; > unsigned bit3:1; > unsigned bit4:1; > unsigned bit5:1; > unsigned bit6:1; > unsigned bit7:1; > }; > } meintyp_t; > mach mal ein sizeof(meintyp_t). Meiner meinung nach sollte da eine 4 rauskommen, auch wenn du prgma pack verwendest. da das bitfeld aller wahrscheinlichkeit 32 bit breit ist.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.