Forum: Compiler & IDEs Struct komplett auslesen


von jibbel (Gast)


Lesenswert?

Hi Leute!

jedes mal, wenn ich nicht mehr weiter gewusst habe, habt ihr mit 
geholfen!

Hoffentlich könnt ihr mir auch jetzt weiterhelfen!

ich habe folgendes struct
1
struct
2
  {
3
    unsigned char e1:1;
4
    unsigned char e2:1;
5
    unsigned char d7:1;
6
    unsigned char d6:1;
7
    unsigned char d5:1;
8
    unsigned char d4:1;
9
    unsigned char rs:1;
10
    unsigned char rw:1;
11
  }data;

die einzelnen bits werden im code gesetzt.

Nun will ich aber data auslesen in ein anderes char schreiben!
wie kann ich das machen?

Im Watch-Fenster von Microchips MPLAB wird die der hex-code des struct 
angezeigt, jedoch beim versuch , das struct auszulesen, bricht der 
compiler mit einem error ab.
1
char text;
2
text = data;
hier kommt dann die errormeldung:
error: incompatible types in assignment

K.A. was der von mir will!

wie muss ich den code schreiben, damit ich das komplette struct auslesen 
kann?

lg jibbel

von Mark B. (markbrandis)


Lesenswert?

Rechnen kann man immer ;-)

1
#include <stdio.h>
2
3
int main()
4
{
5
  typedef struct
6
    {
7
       unsigned char e1:1;
8
       unsigned char e2:1;
9
       unsigned char d7:1;
10
       unsigned char d6:1;
11
       unsigned char d5:1;
12
       unsigned char d4:1;
13
       unsigned char rs:1;
14
       unsigned char rw:1;
15
  } data;
16
  
17
  data a;
18
  unsigned char text;
19
20
  a.e1 = 1;
21
  a.e2 = 0;
22
  a.d7 = 0;
23
  a.d6 = 1;
24
  a.d5 = 0;
25
  a.d4 = 1;
26
  a.rs = 1;
27
  a.rw = 0;
28
  text = 128*a.e1 + 64*a.e2 + 32*a.d7 + 16*a.d6 +
29
           8*a.d5 +  4*a.d4 +  2*a.rs +    a.rw;
30
31
  printf("text = 0x%x\n", text);
32
  return 0;
33
}

von Klaus W. (mfgkw)


Lesenswert?

oder die schmutzige und schnelle Variante:
1
  data a;
2
  unsigned char text;
3
  ...
4
  text = *(unsigned char*)&a;

von Mark B. (markbrandis)


Lesenswert?

Klaus Wachtler schrieb:
> oder die schmutzige und schnelle Variante:
>
1
>   data a;
2
>   unsigned char text;
3
>   ...
4
>   text = *(unsigned char*)&a;
5
>

text = 0x69
text2 = 0x96

Tja, da hab ich wohl die Reihenfolge vertauscht... hätte jetzt gedacht, 
dass ein Bitfield vom höchsten Bit an losgeht anstatt vom niedrigsten.

von Klaus W. (mfgkw)


Lesenswert?

wie trügerisch sind Weiber^H^H^H^H^H^HCompilerherzen!

von jibbel (Gast)


Lesenswert?

jungs, ihr seid die besten!
wieder mal habt ihr es geschafft!

lg jibbel

von Klaus W. (mfgkw)


Lesenswert?

wo dürfen wir die Rechnung hinschicken?

von Mano W. (Firma: ---) (manow)


Lesenswert?

Da dein Bitfeld eh 8 Bits groß ist, mach halt ne Union...

sollte eine Alternative zu den vorigen sein (bissl bitgeschupse)
1
text = (a.e1 << 7) | (a.e2 << 6) | (a.d7 << 5) | (a.d6 << 4) |
2
          (a.d5 << 3) |  (a.d4 << 2) | (a.rs << 1) | (a.rw << 0);

von Fabian (Gast)


Lesenswert?

Wieso werden hier soviele Bytes verschwendet?! Was haltet ihr von:
1
typedef union {
2
  unsigned char byte;
3
struct
4
  {
5
    unsigned e1:1;
6
    unsigned e2:1;
7
    unsigned d7:1;
8
    unsigned d6:1;
9
    unsigned d5:1;
10
    unsigned d4:1;
11
    unsigned rs:1;
12
    unsigned rw:1;
13
  }data;
14
}

von 900ss (900ss)


Lesenswert?

Mark Brandis schrieb:
> Tja, da hab ich wohl die Reihenfolge vertauscht...

Ja das hängt allgemein davon ab, ob du eine Little Endian oder Big 
Endian Maschine hast. Bei Little Endian steht Bit0 an oberster Stelle 
bei solch einem struct. Sonst genau anders herum.

von Klaus W. (mfgkw)


Lesenswert?

nein, das hat damit nicht direkt zu tun.

Bei little- und big endian unterscheiden sich dann die Reihenfolge,
in der die Bytes der int im Speicher liegen, was nun bei 8 Bit
bzw. 1 Byte so viel wie wenig ausmacht.

Bitfelder werden (auch falls es um mehr als 1 Byte geht) bei
allen mir bekannten Compilern ab Bit 0 gefüllt, egal wie
die Endianness aussieht.
Ob das jetzt irgendein C-Standard so vorschreibt oder
eine freiwillige Übereinkunft ist, weiß ich nicht.
Hauptsache, es ist so.

von Klaus W. (mfgkw)


Lesenswert?

BTW: hat 900ss was mit Ducati zu tun?

von Rolf Magnus (Gast)


Lesenswert?

> Was haltet ihr von:
>
1
> typedef union {
2
>   unsigned char byte;
3
> struct
4
>   {
5
>     unsigned e1:1;
6
>     unsigned e2:1;
7
>     unsigned d7:1;
8
>     unsigned d6:1;
9
>     unsigned d5:1;
10
>     unsigned d4:1;
11
>     unsigned rs:1;
12
>     unsigned rw:1;
13
>   }data;
14
> }

Nichts. Erstens finde ich es umständlich, überall, wo die Struktur 
verwendet wird, ein '.data' anhängen zu müssen, nur weil an einer 
einzigen Stelle das Byte gebraucht wird, zweitens sind unions gar nicht 
dafür gedacht. Das Verhalten ist laut ISO-C undefiniert.

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Bitfelder werden (auch falls es um mehr als 1 Byte geht) bei
> allen mir bekannten Compilern ab Bit 0 gefüllt, egal wie
> die Endianness aussieht.

Zumindest im ARM ABI wird die Reihenfolge aber geändert. Entsprechende
Compiler müssen sich daran halten.

Gruß
Marcus

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> Nichts. Erstens finde ich es umständlich, überall, wo die Struktur
> verwendet wird, ein '.data' anhängen zu müssen, nur weil an einer
> einzigen Stelle das Byte gebraucht wird, zweitens sind unions gar nicht
> dafür gedacht.

Zumindest sind sie dafür unglaublich praktisch :-) Wenn man dann noch
einen Compiler hat, der per Erweiterung anonymous structs beherrscht
(z.B. GCC, RVCT), dann kann man sich das '.data' sparen.

Gruß
Marcus

von Rolf Magnus (Gast)


Lesenswert?

Ich kann da nichts praktisches dran finden. Außerdem ist es mit Casts 
besser lesbar, weil man da gleich sieht, was passiert, statt daß 
irgendwo "hintenrum" Typen uminterpretiert werden. Sowas will ich doch 
lieber explizit im Code stehen haben. Dazu kommt dann noch das Problem 
mit der ISO-Konformität und Portabilität. Deshalb verstehe ich nicht, 
wieso die union-Methode so weit verbreitet und so populär ist.

von Klaus W. (mfgkw)


Lesenswert?

Portabler oder ISO-konformer ist meine Zeigervariante
auch nicht. Nur viel kürzer.

von 900ss (900ss)


Lesenswert?

Klaus Wachtler schrieb:
> nein, das hat damit nicht direkt zu tun.
>
> Bei little- und big endian unterscheiden sich dann die Reihenfolge,
> in der die Bytes der int im Speicher liegen, was nun bei 8 Bit
> bzw. 1 Byte so viel wie wenig ausmacht.
>
> Bitfelder werden (auch falls es um mehr als 1 Byte geht) bei
> allen mir bekannten Compilern ab Bit 0 gefüllt, egal wie
> die Endianness aussieht.

Ich weiß wenigstens 2 Compiler (für big endian CPUs) bei denen die 
Bitfelder genau anders herum angelegt werden (innerhalb eines Bytes) als 
z.B. bei MS C-Compiler (VS6). Ob das allerdings den Compilerherstellern 
überlassen wird, das weiß ich nicht.
1
struct bert
2
{
3
  int bit_a : 1;
4
  int bit_b : 1;
5
  int bits  : 30;
6
}

bei MS-C kommt beim setzen von bit_a ein 0x00000001 heraus. Bei den 
Compilern der Big Endian CPUs (die ich kenne) kommt 0x80000000 heraus.

Klaus Wachtler schrieb:
> BTW: hat 900ss was mit Ducati zu tun?

Ja, aber Bj. 81. Die haben noch einen schönen Sound. Da fallen die 
morschen Äste aus den Bäumen, wenn du durch einen Wald fährst ;-)

von Rolf M. (rmagnus)


Lesenswert?

> Portabler oder ISO-konformer ist meine Zeigervariante
> auch nicht.

Doch.  Naja, portabel ist es ja sowieso nicht, aber unions sind da nur 
noch ein weiterer Faktor, den man beachten muß.
ISO-konform ist es aber im Gegensatz zu den unions.

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.