Forum: Mikrocontroller und Digitale Elektronik init typedef , structure , bitfield c code


von bitsetzer (Gast)


Lesenswert?

1
#include <stdio.h>
2
#include <stdlib.h>
3
4
5
typedef struct bitfields3 {
6
  unsigned char a : 1;
7
  unsigned char b : 1;
8
  unsigned char c : 1;
9
} bitfields3_t;
10
11
12
typedef struct bitfields8 {
13
  unsigned char a : 1;
14
  unsigned char b : 1;
15
  unsigned char c : 1;
16
17
        // TEST
18
  unsigned char d : 1;
19
  unsigned char e : 1;
20
  unsigned char f : 1;
21
  unsigned char g : 1;
22
  unsigned char h : 1;
23
} bitfields8_t;
24
25
26
void main ( void ) {
27
28
bitfields3_t mask3;
29
bitfields8_t mask8;
30
31
32
mask3.a = 1;
33
mask3.b = 0;
34
mask3.c = 0;
35
36
37
mask8.a = 1;
38
mask8.b = 0;
39
mask8.c = 0;
40
mask8.d = 0;
41
mask8.e = 0;
42
mask8.f = 0;
43
mask8.g = 0;
44
mask8.h = 0;
45
46
47
printf("Mask3: %d a:%d  b:%d  c:%d\n", mask3, mask3.a, mask3.b, mask3.c);
48
printf("Mask8: %d a:%d  b:%d  c:%d\n", mask8, mask8.a, mask8.b, mask8.c);
49
50
mask3.a = 0;
51
mask3.b = 0;
52
mask3.c = 1;
53
54
55
mask8.a = 0;
56
mask8.b = 0;
57
mask8.c = 1;
58
mask8.d = 0;
59
mask8.e = 0;
60
mask8.f = 0;
61
mask8.g = 0;
62
mask8.h = 0;
63
64
printf("Mask3: %d a:%d  b:%d  c:%d\n", mask3, mask3.a, mask3.b, mask3.c);
65
printf("Mask8: %d a:%d  b:%d  c:%d\n", mask8, mask8.a, mask8.b, mask8.c);
66
67
68
// test sizeof struct:
69
printf ("Groesse struct  (3) : %d\n", sizeof(struct bitfields3) );
70
printf ("Groesse struct  (8) : %d\n", sizeof(struct bitfields8) );
71
72
// test sizeof type
73
printf ("Groesse typedef (3) : %d\n", sizeof(bitfields3_t) );
74
printf ("Groesse typedef (8) : %d\n", sizeof(bitfields8_t) );
75
76
}

sizeof stimmt bei struct und type (1)

Wo liegt aber mein Denkfehler für die vorgesehene Wert Ausgabe?

Ich möchte gerne bei bitfields3 (3 BIT) 1 0 0 bzw 0 0 1
die Ausgabe mit Format %d   4 bzw 1 haben


Frage:
Wie initialisiere ich das 3 bit struct bzw den 3 bit type mit 0?


ein Versuch, ein weiteres struct / type anzulegen und auch die 
restlichen 5 bits zu initialisieren belegen, bringt nicht das gewünschte 
Ergebnis:

Ich hätte erwartet bei bitfields8 (8 BIT)
1 0 0 0 0 0 0 0 bzw 0 0 0 0 0 0 0 1

die Ausgabe mit Format %d   128 bzw 1 haben


Der Versuch dient mir auch zu verstehen, wie die Bits zu setzen sind
für LSB und MSB.

Danke schon mal für die Erklärung was ich falsch mache und für einen 
Tip.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

bitsetzer schrieb:
> Ich möchte gerne bei bitfields3 (3 BIT) 1 0 0 bzw 0 0 1 die Ausgabe mit
> Format %d   4 bzw 1 haben

Du möchtest, daß die einzelnen Bits im Bitfeld in den Wert eines Bits 
innerhalb eines Bytes/ints/wasauchimmer übersetzt werden?

Das kannst Du -- mit Portabilitätsproblemen -- durch Gebrauch einer 
union mit einem int erreichen,

d.h.
1
typedef union
2
{
3
  int wert;
4
  {
5
    int a:1;
6
    int b:1;
7
    int c:1;
8
  };
9
} meinkram_t;
10
11
meinram_t meinkram;
12
13
meinkram.a = 0;
14
meinkram.b = 0;
15
meinkram.c = 1;
16
17
printf("meinkram %d", meinkram.wert);


... irgendwie will mir aber der der Sinn des ganzen nicht so recht 
einfallen.

von bitsetzer (Gast)


Lesenswert?

Rufus Τ. F. schrieb:

> bitsetzer schrieb:
>> Ich möchte gerne bei bitfields3 (3 BIT) 1 0 0 bzw 0 0 1 die Ausgabe mit
>> Format %d   4 bzw 1 haben
>
> Du möchtest, daß die einzelnen Bits im Bitfeld in den Wert eines Bits
> innerhalb eines Bytes/ints/wasauchimmer übersetzt werden?

Ja - ausreichen würde mir erstmal Bytes ( char ) .

>
> Das kannst Du -- mit Portabilitätsproblemen -- durch Gebrauch einer
> union mit einem int erreichen,
>
> d.h.
> typedef union
> {
>   int wert;
>   {
>     int a:1;
>     int b:1;
>     int c:1;
>   };
> } meinkram_t;
>
> meinram_t meinkram;
>
> meinkram.a = 0;
> meinkram.b = 0;
> meinkram.c = 1;
>
> printf("meinkram %d", meinkram.wert);
>

übersetzt er jetzt nicht auf anhieb, aber ich denke ich kann dir folgen, 
was du meinst.

meinkram.wert ändere ich mal zu meinkram
oder muss ich meinkram.wert noch definieren?


> ... irgendwie will mir aber der der Sinn des ganzen nicht so recht
> einfallen.

Spiele mit dem Bitsetzen rum.
Wenn ein Type nur 3 bit hat, wie initialiesiere ich den mit 0 ?

von bitsetzer (Gast)


Lesenswert?

µc.c:91:9: error: 'meinkram_t' has no member named 'a'
 meinkram.a = 0;
         ^
µc.c:92:9: error: 'meinkram_t' has no member named 'b'
 meinkram.b = 0;
         ^
µc.c:93:9: error: 'meinkram_t' has no member named 'c'
 meinkram.c = 1;
1
typedef union
2
{
3
  int wert;
4
  {
5
    int a:1;
6
    int b:1;
7
    int c:1;
8
  };
9
} meinkram_t;
10
11
meinkram_t meinkram;
12
13
meinkram.a = 0;
14
meinkram.b = 0;
15
meinkram.c = 1;
16
17
// vorerst kommentiert
18
// printf("meinkram %d", meinkram.wert);

von Klaus Skibowski (Gast)


Lesenswert?

typedef union
{
  int wert; <-- probier es mal ohne das ;
  {

von bitsetzer (Gast)


Lesenswert?

Klaus Skibowski schrieb:
> typedef union
> {
>   int wert; <-- probier es mal ohne das ;
>   {
1
typedef union
2
{
3
  int wert
4
  {
5
    int a:1;
6
    int b:1;
7
    int c:1;
8
  } ;
9
10
} meinkram_t;
11
12
 meinkram_t meinkram;
13
14
//  meinkram.wert.a = 0;
15
//  meinkram.wert.b = 0;
16
//  meinkram.wert.c = 1;
17
18
// printf("meinkram %d", meinkram.wert);

µc.c:102:3: error: expected ':', ',', ';', '}' or '__attribute__' before 
'{' token
   {
   ^

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ich habe das ganze nicht durch einen Compiler gejagt, und dabei 
offensichtlich etwas übersehen.
1
typedef union
2
{
3
  int wert;
4
  struct {
5
    int a:1;
6
    int b:1;
7
    int c:1;
8
  };
9
} meinkram_t;
10
11
meinkram_t meinkram;
12
13
meinkram.a = 0;
14
meinkram.b = 0;
15
meinkram.c = 1;
16
17
printf("meinkram %d", meinkram.wert);

Dem (jetzt anonymen) Bitfeld fehlte das Schlüsselwort struct.

Wird meinkram als automatische Variable auf dem Stack angelegt, wird es 
aber zu merkwürdigen Effekten kommen. Zwar werden die drei 
Strukturelemente des Bitfelds hier beschrieben, aber die (verborgenen) 
restlichen Bits der Struktur bleiben uninitialisiert, so daß bei der 
Ausgabe von meinkram.wert merkwürdige Werte ausgegeben werden.

Das lässt sich mit
1
    memset(&meinkram, 0, sizeof (meinkram));

vor dem Beschreiben der Elemente des Bitfelds umgehen.


Das lässt sich compilieren, siehe hier:

https://goo.gl/84n5We

von bitsetzer (Gast)


Lesenswert?

Rufus Τ. F. schrieb:

Ich teste das gleich danke!

..
> Wird meinkram als automatische Variable auf dem Stack angelegt, wird es
> aber zu merkwürdigen Effekten kommen. Zwar werden die drei
> Strukturelemente des Bitfelds hier beschrieben,

genau

> aber die (verborgenen)
> restlichen Bits der Struktur bleiben uninitialisiert,

um das geht es Rufus!
Wie kann man diese auf 0 setzen?

> so daß bei der
> Ausgabe von meinkram.wert merkwürdige Werte ausgegeben werden.

Genau so ist es!

>
> Das lässt sich mit    memset(&meinkram, 0, sizeof (meinkram));
>
> vor dem Beschreiben der Elemente des Bitfelds umgehen.

Teste ich gleich

von bitsetzer (Gast)


Lesenswert?

ohne
1
 memset(&meinkram, 0, sizeof (meinkram));

C:\bits>µc.exe
Mask3: 2130567169 a:-1  b:0  c:0
Mask8: 2686721 a:-1  b:0  c:0
Mask3: 2130567172 a:0  b:0  c:-1
Mask8: 2686724 a:0  b:0  c:-1
Groesse struct  (3) : 4
Groesse struct  (8) : 4
Groesse typedef (3) : 4
Groesse typedef (8) : 4
meinkram 4194436

mit
1
 memset(&meinkram, 0, sizeof (meinkram));


C:\bits>gcc µc.c -o µc.exe
µc.c: In function 'main':
µc.c:115:1: warning: incompatible implicit declaration of built-in 
function 'memset' [enabled by def
 memset(&meinkram, 0, sizeof (meinkram));
 ^

C:\bits>µc.exe
Mask3: 2130567169 a:-1  b:0  c:0
Mask8: 2686721 a:-1  b:0  c:0
Mask3: 2130567172 a:0  b:0  c:-1
Mask8: 2686724 a:0  b:0  c:-1
Groesse struct  (3) : 4
Groesse struct  (8) : 4
Groesse typedef (3) : 4
Groesse typedef (8) : 4
meinkram 4
C:\bits>

Genau dieses Ergebnis wollte ich haben!
Die anderen ( Mask3, Mask8 ) sind unvorhergesehen,
ich werde diese auch einmal miz memset vor dem beschreiben
testen.


Vielen Dank Rufus, muss das erst mal genauer ansehen
um es besser zu verstehen. Wo liegt das Geheimnis?
Union ?

von bitsetzer (Gast)


Lesenswert?

1
#include <stdio.h>
2
#include <stdlib.h>
3
4
5
typedef struct bitfields3 {
6
  /*unsigned char*/ int a : 1;
7
  /*unsigned char*/ int b : 1;
8
  /*unsigned char*/ int c : 1;
9
} bitfields3_t;
10
11
12
typedef struct bitfields8 {
13
  /*unsigned char*/ int a : 1;
14
  /*unsigned char*/ int b : 1;
15
  /*unsigned char*/ int c : 1;
16
17
        // TEST
18
  /*unsigned char*/ int d : 1;
19
  /*unsigned char*/ int e : 1;
20
  /*unsigned char*/ int f : 1;
21
  /*unsigned char*/ int g : 1;
22
  /*unsigned char*/ int h : 1;
23
} bitfields8_t;
24
25
26
void main ( void ) {
27
28
bitfields3_t mask3;
29
bitfields8_t mask8;
30
31
32
// Test ohne memset:
33
// beabsichtigt : 0 0 0 0 0 0 0 1
34
mask3.a = 1;  // ( b0 )
35
mask3.b = 0;  // ( b1 )
36
mask3.c = 0;  // ( b2 )
37
38
39
// Test ohne memset:
40
// beabsichtigt 0 0 0 0 0 1 0 0
41
mask8.a = 0;  // ( b0 )
42
mask8.b = 0;  // ( b1 )
43
mask8.c = 1;  // ( b2 )
44
mask8.d = 0;  
45
mask8.e = 0;
46
mask8.f = 0;
47
mask8.g = 0;
48
mask8.h = 0;
49
50
51
printf("Mask3: %i a:%d  b:%d  c:%d\n", mask3, mask3.a, mask3.b, mask3.c);
52
printf("Mask8: %i a:%d  b:%d  c:%d\n", mask8, mask8.a, mask8.b, mask8.c);
53
54
55
56
57
// danke Rufus! das fehlte bei mir.
58
memset(&mask3, 0, sizeof (mask3));
59
60
// 0 0 0 0 0 0 0 1
61
mask3.a = 1;  // ( b0 )
62
mask3.b = 0;  // ( b1 )
63
mask3.c = 0;  // ( b2 )
64
65
66
// danke Rufus! das fehlte bei mir.
67
memset(&mask8, 0, sizeof (mask8));
68
69
// 0 0 0 0 0 1 0 0
70
mask8.a = 0;  // ( b0 )
71
mask8.b = 0;  // ( b1 )
72
mask8.c = 1;  // ( b2 )
73
mask8.d = 0;
74
mask8.e = 0;
75
mask8.f = 0;
76
mask8.g = 0;
77
mask8.h = 0;
78
79
printf("Mask3: %i a:%d  b:%d  c:%d\n", mask3, mask3.a, mask3.b, mask3.c);
80
printf("Mask8: %i a:%d  b:%d  c:%d\n", mask8, mask8.a, mask8.b, mask8.c);
81
82
83
// test sizeof struct:
84
printf ("Groesse struct  (3) : %d\n", sizeof(struct bitfields3) );
85
printf ("Groesse struct  (8) : %d\n", sizeof(struct bitfields8) );
86
87
// test sizeof type
88
printf ("Groesse typedef (3) : %d\n", sizeof(bitfields3_t) );
89
printf ("Groesse typedef (8) : %d\n", sizeof(bitfields8_t) );
90
91
92
93
// rufus mit union :
94
95
typedef union
96
{
97
  int wert;
98
  struct {
99
    int a:1;
100
    int b:1;
101
    int c:1;
102
  };
103
} meinkram_t;
104
105
meinkram_t meinkram;
106
107
memset(&meinkram, 0, sizeof (meinkram));
108
109
meinkram.a = 0;
110
meinkram.b = 0;
111
meinkram.c = 1;
112
113
printf("meinkram %d", meinkram.wert);
114
115
}

1
C:\bits>gcc µc.c -o µc.exe
2
µc.c: In function 'main':
3
µc.c:58:1: warning: incompatible implicit declaration of built-in function 'memset' [enabled by default]
4
 memset(&mask3, 0, sizeof (mask3));
5
 ^
6
7
C:\bits>µc.exe
8
Mask3: 2130567169 a:-1  b:0  c:0       // willkur andere bits
9
Mask8: 2686724 a:0  b:0  c:-1          // willkur andere bits
10
Mask3: 1 a:-1  b:0  c:0                // memset ok, a: -1 ??
11
Mask8: 4 a:0  b:0  c:-1                // memset ok, c: -1 ??
12
Groesse struct  (3) : 4
13
Groesse struct  (8) : 4
14
Groesse typedef (3) : 4
15
Groesse typedef (8) : 4
16
meinkram 4
17
C:\bits>

Eine Frage noch:
Warum  erscheint ein Bit (a:-1) (c:-1) als negativ ?

von bitsetzer (Gast)


Lesenswert?

Kann man sagen, dass immer der erste Eintrag das LSB Bit ist,
example:
meinkram.a  BIT0 ( LSB ) ist
und dann nach oben geht (MSB) ?
1
meinkram.a = 0;  // BIT0
2
meinkram.b = 0;  // BIT1
3
meinkram.c = 1;  // BIT2

Danke!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du machst Dir das Leben unnötig schwer.

Bitfelder sind dafür da, damit man sich eben nicht mit der Wertigkeit 
einzelner Bits beschäftigen muss.

Wenn Du das willst, brauchst Du keine Bitfelder.
1
int x;
2
3
x = (1 << 2);
4
5
printf("%d\n", x);
6
7
x += (1 << 4);
8
9
printf("%d\n", x);


Lies Dir mal in Deinem C-Buch das Kapitel über Bitmanipulation durch.

von Carl D. (jcw2)


Lesenswert?

bitsetzer schrieb:
> Eine Frage noch:
> Warum  erscheint ein Bit (a:-1) (c:-1) als negativ ?

Welche Werte kann wohl ein int mit 1Bit Breite annehmen?

0 und -1

Falls du 0 und 1 haben willst, das wäre unsigned.

von bitsetzer (Gast)


Lesenswert?

Jetzt ist es viel klarer, vielen Dank.

Ausgegangen war der Gedanke von so einem Define, über das ich mir den 
Kopf zerbrochen habe, wie man solche defines für Bitmanipulation / 
setzen zu nutze machen kann.

Hätte da jemand ein Beispiel?
1
#define auto_map [5:3]

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

bitsetzer schrieb:
> #define auto_map [5:3]

Das ist kein C.

von bitsetzer (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> bitsetzer schrieb:
>> #define auto_map [5:3]
>
> Das ist kein C.

HA - und ich depp hab mir den Kopf zerbrochen!
Irretiert von "Python has C style bit manipulation operators"
aus diesem Fundus:
http://stackoverflow.com/questions/147713/how-do-i-manipulate-bits-in-python/150411#150411

wollte ich mir wahrscheinlich diesen Vector
1
b = BitVector(0)
2
 b[3:0]   = 0xD
3
 b[7:4]   = 0xE
4
 b[11:8]  = 0xA
5
 b[15:12] = 0xD

in C einreden,
oh Mann, danke Rufus!
Das war zuviel Wald heute - der "Ausgangs" Baum war irgendwie 
verschwunden.

Jetzt bin ich erleichtert.

von bitsetzer (Gast)


Lesenswert?

Quer gefragt, gibt es sowas für C auch?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ich kenne Python nicht, aber das sieht mir irgendwie nach einem Bitfeld 
aus.
1
struct
2
{
3
  unsigned int a:4;
4
  unsigned int b:4;
5
  unsigned int c:4;
6
  unsigned int d:4;
7
} x;
8
9
x.a = 0xD;
10
x.b = 0xE;
11
x.c = 0xA;
12
x.d = 0xD;

: Bearbeitet durch User
von bitsetzer (Gast)


Lesenswert?

1
struct
2
{
3
  unsigned int a:4;
4
  unsigned int b:4;
5
  unsigned int c:4;
6
  unsigned int d:4;
7
} x;
8
9
x.a = 0xD;
10
x.b = 0xE;
11
x.c = 0xA;
12
x.d = 0xD;
13
14
printf("0xD : %d\n", x.a);
15
printf("0xE : %d\n", x.b);
16
printf("0xA : %d\n", x.c);
17
printf("0xD : %d\n", x.d);
18
19
printf("Size of unsigned int: %d\n", sizeof(unsigned int));
20
printf("Size of struct x    : %d\n", sizeof(x));



Ausgabe:
1
0xD : 13
2
0xE : 14
3
0xA : 10
4
0xD : 13
5
Size of unsigned int: 4
6
Size of struct x    : 4

Perfect! Du hast was gut bei mir.
Genau so brauch ich das auch.

Mal nachgefragt, warum braucht man hier jetzt kein memset?
Das Size vom x verstehe ich nur bedingt.

von bitsetzer (Gast)


Lesenswert?

Nur mal als Test:
1
truct
2
{
3
  unsigned int a;
4
  unsigned int b;
5
  unsigned int c;
6
  unsigned int d;
7
} x;
8
9
x.a = 0xD;
10
x.b = 0xE;
11
x.c = 0xA;
12
x.d = 0xD;
13
14
printf("0xD : %d\n", x.a);
15
printf("0xE : %d\n", x.b);
16
printf("0xA : %d\n", x.c);
17
printf("0xD : %d\n", x.d);
18
19
printf("Size of unsigned int: %d\n", sizeof(unsigned int));
20
printf("Size of struct x    : %d\n", sizeof(x));



1
0xD : 13
2
0xE : 14
3
0xA : 10
4
0xD : 13
5
Size of unsigned int: 4
6
Size of struct x    : 16

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

bitsetzer schrieb:
> Mal nachgefragt, warum braucht man hier jetzt kein memset?

Ob man es braucht oder nicht kommt auf den Gebrauch des Bitfelds an.
Wenns auf dem Stack angelegt wird, werden die "Lücken" im Bitfeld nicht 
initialisiert. Da Du aber auch nicht das Bitfeld als gesamtes, sondern 
nur die definierten Teilelemente ausgibst, kann Dir das aber auch egal 
sein.

> Das Size vom x verstehe ich nur bedingt.

Ein Bitfeld ist üblicherweise so groß wie ein (unsigned) int oder ein 
vielfaches davon. Da Du ein 32-Bit-System einsetzt, ist sizeof int bei 
Dir 4, und damit auch das Bitfeld 4 Bytes groß.

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.