Hallo zusammen,
ich programmiere nicht mit dem gcc sondern mit MPLab und dem Hi-Tech
Pic16 C-Compiler. Aber ich denke und hoffe, dass ihr mir weiterhelfen
könnt. Ich habe ein Struct wie folgt definiert:
struct DATA{
short value1;
short value2;
short value3;
short value4;
} Werte;
nun kann ich ja über das Makro offsetof die Position eines Elements im
Struct herausfinden. Dies funktioniert auch mit folgendem Quelltext:
offsetof(struct DATA, value2);
Nun stellen die Werte value1, value2,... unterschiedliche Werte dar,
welche in einem Menü verändert werden können. Dazu gibt es einen Zeiger
auf den zum aktuell ausgewählten Menüpunkt zugehörigen Wert. Also der
Wert welcher im ausgewählten Menüpunkt geändert werden kann wird über
einen Zeiger angesprochen bspw.:
short *pointer = &Werte.value2;
in der Menüfunktion wird jetzt der Wert des Pointers verändert. Nun
möchte ich die Position im Struct des Wertes herausfinden, auf welchen
der Pointer zeigt. Dazu habe ich folgendes ausprobiert nur leider
funktioniert das nicht:
offsetof(struct DATA, *pointer);
Der Compiler bringt mir die Fehlermeldung "Zeiger erforderlich"
Kann mir hier bitte jemand weiterhelfen??? Habe ich einen Denkfehler
oder geht das einfach nicht? Gibt es einen anderen Weg???
Vielen Dank schon im Vorraus!!!
Flo
Das scheint eher eine Aufgabe für ein Array statt ein struct zu sein.
Fragender schrieb:> offsetof(struct DATA, *pointer);>> Der Compiler bringt mir die Fehlermeldung "Zeiger erforderlich"
Das zweite Argument für das Makro muss der Name eines Elements sein. So
geht das nicht.
Um nur die Differenz zweier Zeiger zu erhalten, muss man sie voneinander
abziehen (so weit, so offensichtlich). Allerdings erhält man die
Differenz in Einheiten der Datenobjekte, auf die gezeigt wird. Wenn die
Differenz in Bytes gewünscht wird, muss man beide Zeiger nach char*
casten.
Mit Arrays ist alles viel einfacher:
Vielen Dank!
Habe aber leider nicht gesagt, dass im Struct nicht nur shorts, sondern
auch andere Datentypen sind. Deshalb doch leider Struct. Mit einem Array
habe ich es zuvor implementiert und das hat auch funktioniert. Dann
müsste es doch aber folgendermaßen funktionieren:
unsigned char *offset = (unsigned char)pointer - &(unsigned
char)Werte
Flo
Die Frage ist immer noch: WOZU?
Etwas derartiges hab ich in 30 Jahren noch nie benötigt.
(Mit scheint nämlich, du zäumst das Pferd von der falschen Seite auf)
Fragender schrieb:> Habe aber leider nicht gesagt, dass im Struct nicht nur shorts, sondern> auch andere Datentypen sind. Deshalb doch leider Struct. Mit einem Array> habe ich es zuvor implementiert und das hat auch funktioniert.
Man kann ein Array auch als Element von einem struct definieren…
Fragender schrieb:> Dann> müsste es doch aber folgendermaßen funktionieren:>> unsigned char *offset = (unsigned char)pointer - &(unsigned> char)Werte
Das funktioniert überhaupt nicht.
Und ich habe in meinem Beispiel die Variable nicht offset, sondern index
benannt — aus dem Grund, dass es den Index ins Array ergibt und nicht
den Byte-Offset. Wenn du den willst, musst du den Index einfach mit der
Elementgröße, hier "sizeof (short)", multiplizieren.
Verwende ein Pointer als pointer, und nicht deren Inhalt !!!.
Dein falscher Code:
offsetof(struct DATA, *pointer);
sollte lauten
offsetof(struct DATA, pointer);
Wenn du überlegst warum, wirst du warscheinlich auch erraten wieso.
Chris schrieb:> Verwende ein Pointer als pointer, und nicht deren Inhalt !!!.> Dein falscher Code:> offsetof(struct DATA, *pointer);>> sollte lauten> offsetof(struct DATA, pointer);
Das funktioniert genauso wenig, pointer ist kein Name eines Elements von
struct DATA.
Stimmt, sorry.
Wenn pointer ein member von Werte ist, kannst du ptrdiff anstelle von
offsetoff verwenden, sofern definiert. Ansonsten einfach
#define ptrdiff(x,y) (((unsigned int)&x)-(unsigned int)&y)
Ansonsten, geht nicht.
Dass das ganze merkwürdig ausschaut und weshalb man soetwas eigentlich
nicht verwenden sollte lasse ich mir gerne auch erklären, verstehe zwar
nicht warum aber naja. In meinem Fall macht es aber Sinn, da es weniger
Speicherplatz benötigt (habs getestet) und auch einfacher erweiterbar
ist!!!
Habe das Problem übrigens folgendermaßen gelöst und es funktioniert:
unsigned char offset = (unsigned char*)pointer - (unsigned char*)&Werte
Vielen Dank an alle!!!
Flo