Hallo, ich habe folgende Struktur: typedef struct { unsigned char status; unsigned char value; }object_struct; Im Programm verwende ich dann folgendes Array: object_struct i_object[12]; Nun die eigentliche Frage: Ist es möglich für value quasi abwechseld char und z.B. int (also 1Byte bzw. 2Byte)zu verwenden? Wenn ich alle nach dem "größten" ausrichte, habe ich ja Speicher verschenkt. Welches Arrayelement dann den char oder int Wert hat ist mir vorher bekannt. Oder muss ich das ganz anderes anfangen? Jan
Jan schrieb: > Hallo, > > ich habe folgende Struktur: > > typedef struct > { > unsigned char status; > unsigned char value; > }object_struct; > > Im Programm verwende ich dann folgendes Array: > > object_struct i_object[12]; > > Nun die eigentliche Frage: > Ist es möglich für value quasi abwechseld char und z.B. int (also 1Byte > bzw. 2Byte)zu verwenden? nein > Welches Arrayelement dann den char oder int Wert hat ist mir vorher > bekannt. Was jetzt? wilde Mischung oder tatsächlich abwechselnd? > Oder muss ich das ganz anderes anfangen? Musst du wohl. Wobei du dich als erstes fragen musst, warum eigentlich die values nicht immer den gleichen Datentyp haben.
Hallo, also nicht wirklich abwechseld. Aber zur Laufzeit finden keine Änderungen statt. Ich kann ja alle für alle value int verwenden. Nur möchte ich gern den Speicher sparen. Wie könnte man sowas realisieren? Jan
> Wie könnte man sowas realisieren?
Das bisher unbeschriebene Konzept ändern :-)
Jan schrieb: > Hallo, > > also nicht wirklich abwechseld. Aber zur Laufzeit finden keine > Änderungen statt. > Ich kann ja alle für alle value int verwenden. Nur möchte ich gern den > Speicher sparen. Deine 12 da oben. Sind die real? Das heißt, wir reden im Maximum über 11 gesparte Bytes. Das sind schon sehr enge Vorgaben und man muss aufpassen, dass man durch die 'Optimierung' nicht mehr Speicher verprasselt als man in den tatsächlichen Daten spart. Wenn du zb in die Struct noch ein Typflag mit aufnimmst, ist es schon vorbei mit der Speicherersparnis (aussr du bringst es als Bit im status unter)
Wenn ein System dahinter steckt (gerade/ungerade), ginge es vlt. so:
1 | typedef struct |
2 | {
|
3 | unsigned char ucStatus; |
4 | unsigned char ucValue; |
5 | } tsEven; |
6 | |
7 | typedef struct |
8 | {
|
9 | unsigned char ucStatus; |
10 | unsigned short usValue; |
11 | } tsOdd; |
12 | |
13 | typedef struct |
14 | {
|
15 | tsEven stEven; |
16 | tsOdd stOdd; |
17 | } tsAlternate; |
18 | |
19 | tsAlternate stAlternate[12/2]; |
Wenn nicht, geht's nur mit Verschwendung. Entweder immer den größeren Typ (short oder int oder was auch immer), oder eine union definieren:
1 | typedef struct |
2 | {
|
3 | unsigned char ucStatus; |
4 | union
|
5 | {
|
6 | unsigned char ucValue; |
7 | unsigned short usValue; |
8 | } u; // (je nach Compiler auch ohne Namen) |
9 | } tsEgal; |
10 | |
11 | tsEgal stEgal[12]; |
Besser (ist ja ein Array von Strukturen): tsEgal astEgal[12]; (Nur wegen des Wiedererkennungswertes.)
Hallo, danke erst mal für die Beiträge. Die Arraygröße von 12 ist ein Beispiel, sie kann zwischen 8 und 24 liegen. Die Abfolge der value breite ist nicht abwechseld, bzw. zu berechnen. @ Karl heinz Buchegger Das stimmt, in dem Fall ist die ersparnis nicht sehr groß, aber in bestimmten Fällen werden dort auch 4Byte Werte. Ich bin nicht unbedingt auf diese Struktur / das Array angeweisen, wenn das nur anders zu lösen ist. Jan
Wie siehts mit Anforderungen an die Performanz aus? Würde auch eine implizit einfach verkettete Liste reichen? Falls Du vom z.B. 'status' zwei (für 4 struct-Größen) oder drei Bits (für acht) erübrigen kannst, dann wäre das platzsparend möglich - auf Kosten der Performanz wie gesagt. HTH
Braucht der 'status' denn alle 8 Bits? Reichen dem 'value' vielleicht 10 bis 15 Bits? Dann könnte man folgendes machen:
1 | typedef struct |
2 | {
|
3 | unsigned short uStatus:2, // 2 Bit für Status |
4 | uValue:14; // 14 Bit für Wert |
5 | } tsEgal; |
6 | |
7 | tsEgal astEgal[12]; |
Um die Bitverknispelungen kümmert sich der Compiler, ein Eintrag wäre dann ganze 2 Byte groß.
>
1 | > typedef struct |
2 | > { |
3 | > unsigned short uStatus:2, // 2 Bit für Status |
4 | > uValue:14; // 14 Bit für Wert |
5 | > } tsEgal; |
6 | >
|
> > Um die Bitverknispelungen kümmert sich der Compiler, ein Eintrag wäre > dann ganze 2 Byte groß. Man erkauft sich die RAM Ersparnis also mit wesentlich höherer Programmspeicherverschrendung.
So schlimm ist der Aufwand dann auch nicht. Wenn man Value entsprechend der Endianity ausrichtet, ist es beim Lesen ein zusätzliches AND, nur beim Schreiben dann ein Read-modify-write - ggf. nicht mehr atomar, wenn das überhaupt eine Rolle spielen sollte. Falls im Status nur einzelne Bits vertreten sind (die man auf diese Weise auch noch übersichtlich aufschlüsseln könnte), wäre es dafür auch egal. Das Ganze ist dafür evtl. auch nur einmal im Code vorhanden. Und meistens hat man ja auch ein Ungleichgewicht zwischen RAM und ROM. Die Frage bleibt, ob das jetzt des Rätsels Lösung ist ...
df1as schrieb: > So schlimm ist der Aufwand dann auch nicht. Wenn man Value entsprechend > der Endianity ausrichtet, ist es beim Lesen ein zusätzliches AND, nur > beim Schreiben dann ein Read-modify-write - ggf. nicht mehr atomar, Und benötigt möglicherweise shifts, was bei Architekturen ohne barrelshifter in loops oder mehreren einzelnen shift Instruktionen ausartet. Wenn man so knapp an RAM ist, dass man 4 bytes mit aller Gewalt rausoptimieren muss, dann sollte man den nächstgrößeren Controller wählen.
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.