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.
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
typedefunion
2
{
3
intwert;
4
{
5
inta:1;
6
intb:1;
7
intc:1;
8
};
9
}meinkram_t;
10
11
meinram_tmeinkram;
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.
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 ?
µ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;
Ich habe das ganze nicht durch einen Compiler gejagt, und dabei
offensichtlich etwas übersehen.
1
typedefunion
2
{
3
intwert;
4
struct{
5
inta:1;
6
intb:1;
7
intc:1;
8
};
9
}meinkram_t;
10
11
meinkram_tmeinkram;
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
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
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 ?
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
intx;
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.
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.
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?
printf("Size of unsigned int: %d\n",sizeof(unsignedint));
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.
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ß.