Hi, ich möchte in einer struktur: typedef struct { uint8_t * feld1[10]; uint8_t * feld2[10]; ... uint8_t * feld8[10]; uint8_t feld1_ok :1, feld2_ok :1, ... feld3_ok :1; }felder; gern eine weitere Variable vom typ 8 bit unterbringen die adresstechnisch genau an der stelle liegt wo auch die 8 einzelnen ok-Bits liegen. typedef struct { uint8_t * feld1[10]; uint8_t * feld2[10]; ... uint8_t * feld8[10]; union { uint8_t feld1_ok :1, feld2_ok :1, ... feld8_ok :1; uint8_t alle; }; }felder; wird nicht angemekkert aber funktioniert trotzdem nicht, habe ich das mit der union falsch verstanden, muss ich zuvor einen typen machen, oder kann ich das auch so in einem lösen? Wenn ich dies geraffel einer Funktion übergebe, also darauf zeige: felder datensatz; felder * p_datensatz; p_datensatz=&datensatz; dann sollte ich doch so *p_datensatz->feld1[0]='A'; p_datensatz->feld1_ok=1; zugreifen können. Was habe ich vergessen? Gruß, H.
Das Union wird schon falsch deklariert. Du hast ihm keinen Namen gegeben. Ein Union verhält sich im ersten Moment wie ein struct, nur das es nur eine der möglichen Variablen speichern kann. Du müsstest es also wie folgt verändern:
1 | typedef struct |
2 | {
|
3 | uint8_t * feld1[10]; |
4 | uint8_t * feld2[10]; |
5 | ...
|
6 | uint8_t * feld8[10]; |
7 | union my union |
8 | {
|
9 | uint8_t feld1_ok :1, |
10 | feld2_ok :1, |
11 | ...
|
12 | feld8_ok :1; |
13 | };
|
14 | }felder; |
Ansprechen dann wie folgt:
1 | p_datensatz->my_union_feld1_ok = 1; |
Hatte einen Tippfehler
1 | p_datensatz->my_union.feld1_ok = 1; |
Aber ich denke mal nicht das es sich so verhalten wird wie du denkst. Schließlich hast du nicht alle ok felder im union zur Verfügung.
hey, bin gerad hier: http://cboard.cprogramming.com/c-programming/102978-union-struct-bit-fields.html 1)das mit deinem Underline im Zugriff ist unverständlich!? 2)der Name beim Struct steht aber nach der geschweiften klammer bei der union nicht? Gruß, H.
Hannes schrieb: > wird nicht angemekkert aber funktioniert trotzdem nicht, habe ich das > mit der union falsch verstanden, muss ich zuvor einen typen machen, oder > kann ich das auch so in einem lösen? du musst zunächst die 8 Bit mittels einer Struktur zusammenfassen, ehe du dann mittels union, zu der Struktur dann einen uint8_t parallel legen kannst. In einer union werden ALLE Elemente, egal wieviele, übereinander gelegt.
Es sei darauf hingewiesen, dass die einschlägigen C-Standards bezüglich Bitfeldern festlegen, dass nichts festgelegt ist :-)
hmm... teste gerad ein wenig rum... warum muss ich die bitfeld bits denn noch mit einem struct zusammenfassen bevor ich sie über das Byte legen kann, sie sind doch schon in einem byte? H.
Es gibt keine Sonderbehandlung von Bits in unions. Sie sind alternativ zu jedem anderen Eintrag innerhalb der union; also auch zu anderen Bits. Deswegen musst Du sie zusammenfassen, wenn sie insgesamt alternativ zu anderen Elementen der union sein sollen.
ich habe das mal alles nachgepflegt: typedef struct { uint8_t * feld1[10]; uint8_t * feld2[10]; ... uint8_t * feld8[10]; union { struct { uint8_t feld1 :1, feld2 :1, ... feld8 :1; }bit; uint8_t alle; }ok; }felder; Zugriff mache ich so: felder datensatz; felder * p_datensatz; p_datensatz=&datensatz; *p_datensatz->feld1[0]='A'; p_datensatz->ok.bit.feld1=1; p_datensatz->ok.alle=0xFF; Das scheint zu funktionieren, ich mache das gerade im MS Studio, dort erscheinen die Bits dann als 32 bit variablen dargestellt deren bits dann alle auf 1 gehen. Da man in dem Fall die Adresse nicht sehen kann bin ich nicht 100%ig sicher, das die bits und die "gesamt" variable auch wirklich übereinander liegen und das Bitfeld auch greift. Habe ich es denn richtig umgesetzt? gibt es eine Möglichkeit das .bit. aus der Zugriffstruktur heraus zu bekommen? Ich würde die Ebene gern sparen. Gruß und vielen Dank bis hierher, H.
Hannes schrieb: > gibt es eine Möglichkeit das .bit. aus der Zugriffstruktur heraus zu > bekommen? Ich würde die Ebene gern sparen. Der gcc erlaubt auch anonyme unions; wenn es nicht portabel sein muß (was es ja faktisch gar nicht ist), geht es auch ohne.
>Da man in dem Fall die Adresse nicht sehen kann >bin ich nicht 100%ig sicher, das die bits und die "gesamt" variable auch >wirklich übereinander liegen und das Bitfeld auch greift. Nun, das ist ja genau die interpretation von "union". Alle Einträge liegen an der selben Adresse! Aber Du kannst selbstverständlich auch die Adresse nachprüfen. & p_datensatz->ok.bit und & p_datensatz->ok.alle müssen das selbe ergeben. >gibt es eine Möglichkeit das .bit. aus der Zugriffstruktur heraus zu >bekommen? Ich würde die Ebene gern sparen. Nein. Ist das wirklich beabsichtig, das Du Vektoren von Zeigern anlegst? uint8_t * feld1[10]; Ich frage weil Du den nicht alloziierten Vektorelementen dann Zeichen zuweist. Oder fehlt die Alloziierung nur in Deinem Zitat?
>>Ist das wirklich beabsichtig, das Du Vektoren von Zeigern anlegst?<< nein, da habe ich mich versehen. Es sind strings, Felder von chars. Ist mir beim erstellen des Beispiels da rein gerutscht... >>& p_datensatz->ok.bit<< töffel, daran habe ich nicht gedacht. Hab das in der Zwischenzeit anders nachgewiesen, aber so ists natürlich noch einfacher, danke :-) Dann habe ich alles was ich brauche, danke. H. Ps.: die Anspielung auf die -nicht kompatibilität- ist doch auf die MSB LSB Geschichte bei Bitfeldern bezogen, oder? Dann stimmt die Aussage meiner Meinung nach nur dann wenn man der Bitcodierung der Variablen "alle" keine Wertung in Bezug auf die einzelnen Bits bei der Zuweisung eines Wertes beipflichtet. Sie wird nur zum resetten aller Bits benutzt. Wenn man diese Struktur zudem nicht über eine Systemunabhängige Schnittstelle wie Ethernet oder ähnliches an ein anderes System mit selbiger Struktur im code übermittelt, erwarte ich damit keine Probleme.
>Ps.: die Anspielung auf die -nicht kompatibilität- ist doch auf die MSB
LSB Geschichte bei Bitfeldern bezogen, oder?
Das bezog sich auf die Sprachkompatibilität. In C sind anonyme
Strukturen nicht möglich. In C++ allerdings schon. Da der GCC beides
kann lässt er, falls Du nicht ausdrücklich z.B. C99 festgelegt hast auch
anonyme Strukturen in C zu.
Was die Zuordnung von Bits des Bitfeldes zu Bits des alternativen uint8
betrifft, so ist im Sprachstandard nichts zugesichert. Das ist soweit
richtig, hat aber nichts damit zu tun ob anonyme Strukturen zulässig
sind oder nicht. Deswegen sind solche Dinge nicht "transportabel" (das
ist hier der korrekte Begriff im Ggs. zu kompatibel).
Dennoch ist das Verhalten eines Compilers auf einer Maschine in der
Regel konsistent implementiert. D.h. das er die Bits immer in der selben
Reihenfolge anordnet.
Sorry. "Transportabel" ist eigentlich auch nicht ganz üblich. "Portabel" ist hier besser. Ist beides das selbe, aber was anderes als "Kompatibel".
Huch schrieb: > Was die Zuordnung von Bits des Bitfeldes zu Bits des alternativen uint8 > betrifft, so ist im Sprachstandard nichts zugesichert. Und für unions ist dort festgelegt, daß man auf gar keinen Fall ein anderes Element lesen darf als das, das man zuletzt geschrieben hat.
Sofern ich mich erinnern kann werden, selbst wenn man nur 1 Bit verwendet, dennoch als kleinste Einheit sizeof(int) reserviert. Die restlichen Bit des Byte "liegen brach". Was die Verwendung von Bitfeldern mit geringer Größe meiner Meinung nach obsolet macht. Aus C von A bis Z von Jürgen Wolf struct robo { unsigned int sensor1:1; unsigned int sensor2:1; unsigned int sensor3:1; unsigned int schalter:1; unsigned int Ausgabe:4; } Roboter1; Jetzt benötigt die Struktur im Grunde nur noch acht Bits (ein Byte). Wenn Sie allerdings mit sizeof prüfen, werden Sie feststellen, dass dieses Bitfeld trotzdem vier Byte belegt. Dies liegt daran, dass das kleinstmögliche Rechnerwort, das der Compiler für ein Bitfeld reserviert, sizeof(int) groß ist. Die restlichen drei Bytes in diesem Beispiel sind praktisch leer. Gleiches gilt hierbei natürlich auch, wenn Sie beispielsweise ein Bitfeld mit 40 Bits (fünf Bytes) erstellen. Hier muss der Compiler ein weiteres Rechnerwort (sizeof(int)) reservieren, sodass das fünfte Byte am Anfang des nächsten Rechnerworts liegt und somit insgesamt 8 Bytes benötigt werden. Quelle: http://openbook.galileocomputing.de/c_von_a_bis_z/015_c_strukturen_013.htm#mj2f57db5965c2ac0ab2c8d3d97f038272 Gruß Marco
Marco Ullrich schrieb: > Sofern ich mich erinnern kann werden, selbst wenn man nur 1 Bit > verwendet, dennoch als kleinste Einheit sizeof(int) reserviert. Ja, wenn du als Typ für die Elemente int angibst. Abhängig vom Compiler sind aber durchaus auch kleinere Typen erlaubt (ein Compiler muß mindestens mit bool, int und unsigned int umgehen können, darf aber auch beliebige andere Integertypen unterstützen). Folgendes Programm gibt bei mir
1 | 1 |
aus:
1 | #include <stdio.h> |
2 | |
3 | struct bitfield |
4 | {
|
5 | unsigned char a : 1; |
6 | unsigned char b : 2; |
7 | unsigned char c : 3; |
8 | };
|
9 | |
10 | int main() |
11 | {
|
12 | printf("%d\n", sizeof(struct bitfield)); |
13 | }
|
Da sowieso so ziemlich alle Eigenschaften von Bitfeldern höchst compilerspezifisch sind, macht es auch nichts mehr aus, wenn man sich auch darauf verläßt, daß das so geht.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.