Forum: Mikrocontroller und Digitale Elektronik Bitfeld in Struct in Union


von Hannes (Gast)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

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
}

von Mark B. (markbrandis)


Lesenswert?

Klaus Wachtler schrieb:
1
unsigned      bit0:1;

Wenn man da das "unsigned" weglässt, nimmt er dann ein Bit fürs 
Vorzeichen? ;-)

von Klaus W. (mfgkw)


Lesenswert?

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.

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

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/

von Hannes (Gast)


Lesenswert?

@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

von Klaus W. (mfgkw)


Lesenswert?

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

von Vlad T. (vlad_tepesch)


Lesenswert?

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

von aha (Gast)


Lesenswert?

Ein Riesenaufwand weil man nicht mit Hex operieren will...

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
Noch kein Account? Hier anmelden.