init typedef , structure , bitfield c code

Gast #4807997
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.
Persönliche Seite #4808009
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.
Gast #4808025
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 ?
Gast #4808030
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);
Gast #4808082
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
   {
   ^
Persönliche Seite #4808084
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
Gast #4808092
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
Gast #4808099
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 ?
Gast #4808118
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 ?
Gast #4808127
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!
Persönliche Seite #4808140
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.
Gast #4808245
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]
Gast #4808323
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.
Gast #4808358
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.
Gast #4808368
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
Persönliche Seite #4808372
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ß.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren