init typedef , structure , bitfield c code

Gast #4807997
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
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
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
µ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
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
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
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
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
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
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
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
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
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
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
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
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

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.