Reihenfolge der Variablen in einem struct
-
Hallo,
kann ich davon ausgehen, dass der Compiler die Reihenfolge der Variablen in einem struct so übersetzt wie ich sie hinschreibe?
Mein Anwendungsfall:struct time { int jahr; int monat; int tag; int stunde; int minute; int sekunde; };
Nun möchte ich wissen ob ein Objekt vom Typ time kleiner ist als ein anderes Objekt vom selben Typ. Das würde so aussehen:
if (t1->jahr < t2->jahr) return true; if (t1->jahr > t2->jahr) return false; if (t1->monat < t2->monat) return true; if (t1->monat > t2->monat) return false; if (t1->tag < t2->tag) return true; if (t1->tag > t2->tag) return false; if (t1->stunde < t2->stunde) return true; if (t1->stunde > t2->stunde) return false; if (t1->minute < t2->minute) return true; if (t1->minute > t2->minute) return false; if (t1->sekunde < t2->sekunde) return true; if (t1->sekunde > t2->sekunde) return false;
Viel einfacher hingegen wäre es, wenn ich einen Pointer auf den Anfang der Structs benutze und die Vergleiche dann einfach über deren Inhalte (der Pointer) durchführe. Hierfür muss ich jedoch sicherstellen, dass zuerst der Vergleich mit jahr erfolgt und nicht mit sekunde. Kann ich das so implementieren?
int *pt1 = (int*)t1; int *pt2 = (int*)t2; int i = 0; for (i = 0; i < 6; i++) { if (*pt1 < *pt2) return true; if (*pt1 > *pt2) return false; pt1++; pt2++; }
-
ZzetT schrieb:
kann ich davon ausgehen, dass der Compiler die Reihenfolge der Variablen in einem struct so übersetzt wie ich sie hinschreibe?
Ja, spielt aber keine Rolle, denn
ZzetT schrieb:
Viel einfacher hingegen wäre es, wenn ich einen Pointer auf den Anfang der Structs benutze und die Vergleiche dann einfach über deren Inhalte (der Pointer) durchführe. Hierfür muss ich jedoch sicherstellen, dass zuerst der Vergleich mit jahr erfolgt und nicht mit sekunde. Kann ich das so implementieren?
Nein. Die Elemente müssen nicht direkt hintereinander im Speicher liegen.
-
Ja, spielt aber keine Rolle, weil
Ja, wenn ich es so wie in meinem ersten geposteten Code implementiere, dann spielt es keine Rolle, aber wenn ich es mit Pointern machen würde schon.
Das heißt es führt an diesen vielen (redundanten) if-Bedingungen kein Weg vorbei?
-
Hallo,
ZzetT schrieb:
Das heißt es führt an diesen vielen (redundanten) if-Bedingungen kein Weg vorbei?
sind die Zeiten im time_t Format, so brauchst du nur einen Vergleich.
Gruß,
B.B.
-
Wenn du garantieren willst, dass die Daten hintereinader im Speicher liegen, dann nutze einfach ein Array.
#define TIME_YEAR 0 #define TIME_MON 1 #define TIME_DAY 2 #define TIME_HOUR 3 #define TIME_MIN 4 #define TIME_SEC 5 int Time[6];
Du kannst somit über das Array iterieren und trotzdem mit Time[TIME_MON] ohne Verlust des Lesbarkeit auf den Monat zugreifen.
Sollte es sich nicht um deine eigene Struktur handeln, so kannst du sie noch immer in eine eigene konvertieren. Entweder du kopierst alle Werte oder du nutzt Zeiger.
-
ich würde eher so machen:
enum wasauchimmer { TIME_YEAR = 0, TIME_MON, TIME_DAY, TIME_HOUR, TIME_MIN, TIME_SEC, TIME_TOTAL }; int Time[TIME_TOTAL];
da kann man nachträglich etwas ohne Probleme hinzufügen, Reihenfolge ändern, usw. ohne sich Gedanken um den tatsächlichen Wert machen zu müssen.
-
supertux schrieb:
ich würde eher so machen:
enum wasauchimmer { TIME_YEAR = 0, TIME_MON, TIME_DAY, TIME_HOUR, TIME_MIN, TIME_SEC, TIME_TOTAL }; int Time[TIME_TOTAL];
da kann man nachträglich etwas ohne Probleme hinzufügen, Reihenfolge ändern, usw. ohne sich Gedanken um den tatsächlichen Wert machen zu müssen.
wasauchimmer ist redundant,
"= 0" ist redundant.
-
Hallo ZzetT,
Speicher dir im struct den time_t Wert.
Damit lässt es sich viel einfacher rechnen,
wie du ja schon festgestellt hast.
Auch benötigst du weniger Platz ...Das gleiche Problem wirst du auch an anderen Stellen bekommen,
wenn du rechnen willst.Der time_t Wert kann recht flott für Ausgaben (Bildschirm, ..) umgerechnet werden, hier ist die Performance eh nicht soo relevant
(Der User liest langsamer).Auch in Dateien würde ich, so denn das kein User Interface ist ist den time_t Wert abspeichern.
Nun zur eigentlichen Frage:
kann ich davon ausgehen, dass der Compiler die Reihenfolge der Variablen in einem struct so übersetzt wie ich sie hinschreibe?
Ja, das ist so,
du kannst auch mit pack Anweisungen (struct allignment)
dafür sorgen dass zweifelsfrei keine 'Lücken'
zwischen den Variablen mit undefiniertem Inhalt entstehen.
Die Pack Anweisungen sind Compiler spezifisch,
ich kennen keinen Compiler der das nicht unterstützt.Beispiel MSVC6.0:
#pragma pack(push, 1) struct time { int jahr; int monat; int tag; int stunde; int minute; int sekunde; }; #pragma pack(pop)
Wobei in deinem Fall sowieso keine Lücken entstehen sollten.
Lass dir mal sizeof (struct time) ausgeben.
Sollte auf einem 32 'bitter' 24 Bytes haben.Gruß Frank
-
Kann ich die Variante ein Array zu benutzen mit einem struct kombinieren indem ich union verwende?
union { struct { int jahr; int monat; int tag; } time; int feld[3]; } timeunion;
-
Hallo ZzetT
"Kann ich die Variante ein Array zu benutzen mit einem struct kombinieren indem ich union verwende? "
Ja, kannst du ..
Aber noch einfacher ist der Zugriff dann so:
(Annahme: long hat 32bit, little endian, intel format)union { struct { char filler; char tag; char monat; char jahr; } time; long aslong; } timeunion;
Gruß Frank