Kadaj Geschrieben 13. Juni 2012 Teilen Geschrieben 13. Juni 2012 Hallochen, ich bin grad dabei mir Unions zu verinnerlichen, meine Quelle möchte ich lieber nicht Preis geben^^. Ich bin nicht sicher ob ich überhaupt verstanden habe worum es geht. Ich leg eine union mit dem Schlüsselwort union an, erstmal alles wie bei einem struct. Der Unterschied ist, dass ich immer nur auf ein Element in dem union zugreifen kann, nämlich das erste, auf das ich zugreife bzw. das erste, welches ich initialisiere. Damit spaare ich genau den Speicherplatz ein, den alle andere Elemente im union belegen würden ein. Soweit richtig? Als Beispiel also: ... union data { int Zahl; char Name[24]; char Nachname[24]; char Ort[32]; }; ... int main() { union data test; test.Zahl = 1; ...[/PHP] Somit habe ich eine Variable test vom Typ union data mit dem Sinn mir einen int zu speichern. Nun die alles entscheidene Frage: Wozu braucht man unions, bei denen man nur auf ein Element zugreifen kann, da man doch anstelle von [PHP] union data test; test.Zahl = 1; einfach folgendes schreiben kann: int test = 1;[/PHP] Immerhin ist das in meinen Augen nicht weniger nützlich, als die Variantre mit den unions, außerdem muss man bei unions auch wegen undefinierten Verhalten aufpassen. Kann mir bitte jemand das Licht anknipsen, was mir zur Erleuchtung verhilft? Gruß Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 13. Juni 2012 Teilen Geschrieben 13. Juni 2012 Der Unterschied ist, dass ich immer nur auf ein Element in dem union zugreifen kann, nämlich das erste, auf das ich zugreife bzw. das erste, welches ich initialisiere.Nein. Schreibend darfst du zugreifen, wie du möchstest. Lesen darfst du allerdings nur das Element, das du zuletzt geschrieben hast. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kadaj Geschrieben 13. Juni 2012 Autor Teilen Geschrieben 13. Juni 2012 Danke, das ging nicht ganz aus meinem Buch hervor. Welche praktischen Anwendungen sind denn damit sinnvoll? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 13. Juni 2012 Teilen Geschrieben 13. Juni 2012 Welche praktischen Anwendungen sind denn damit sinnvoll?In C kann man damit Speicherplatz sparen, wenn man von mehreren möglichen Daten immer nur eins speichern muss. In C++ benutzt man Unions praktisch gar nicht. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
metux Geschrieben 14. Juni 2012 Teilen Geschrieben 14. Juni 2012 Unions dienen hauptsächlich zur Abbildung von Variantentypen (die in C sonst nicht direkt unterstützt werden). Bietet sich vorallem dann an, wenn eine Struktur zur Laufzeit verschiedene Varianten von Inhalten aufnehmen kann. Natürlich muß man irgendwie sicherstellen, daß man den jeweils richtigen member anspricht, zB. indem man die aktuelle Variante irgendwo anders her bezieht. Gängige Anwendungsfälle sind Parser für Packets oder Binärfiles. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kadaj Geschrieben 14. Juni 2012 Autor Teilen Geschrieben 14. Juni 2012 In C sind mir unions tatsächlich noch nicht über den Weg gelaufen. Warum unions Speicherplatz spaaren, nur weil man nur das letzte Element, was man geschrieben hat, auch lesen kann, leuchtet mir immernoch nicht ganz ein, immerhin benötigen die Elemente, die ich ein paar Schritte zuvor gespeichert habe auch Speicherplatz. Scheinbar reicht mein Wissen noch nicht ganz aus um das nachvollziehen zu können. Parser für Packets oder Binärfiles sind dann doch schon etwas höherer Stoff. Vielleicht kommt die Erkenntniss ja mit den nächsten Seiten^^ Danke, euch beiden! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lilith2k3 Geschrieben 15. Juni 2012 Teilen Geschrieben 15. Juni 2012 Stell Dir einfach eine Tabellenkalkulation wie Calc, Excel oder was Dir sonst noch so einfällt, vor. Eine einzelne Zelle läßt sich mit Ganzzahlen, mit Fließkommazahlen oder bspw. mit Text befüllen. Im Vorfeld weißt du als Entwickler nicht, was drin landet; dann bieten Dir Unions die Möglichkeit, Platzhalter einzusetzen: »Naja, bei einem Int brauche ich mindestens den Speicher für ein Wort; sollte ich dann Text ablegen wollen, ist für jedes ASCII-Zeichen ein Byte an Speicher vorzusehen. Davon Maximal 256«. So weiß man, dass zwischen einem Wort und 256 Byte an Speicher maximal belegt werden. Werden nur Ints in die Zelle gepackt, spart man sich den restlichen Speicher. Kommt nur Text rein, braucht man die vollen 256 Byte. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Guybrush Threepwood Geschrieben 15. Juni 2012 Teilen Geschrieben 15. Juni 2012 Nein. Schreibend darfst du zugreifen, wie du möchstest. Lesen darfst du allerdings nur das Element, das du zuletzt geschrieben hast. Also das wäre mir neu und würde auch den einzigen mir bekannten Anwendungsfall dafür zunichte machen. Nämlich das einfache konvertieren von Daten in andere Formate indem man je nach Bedarf mal auf das entsprechende Element zugreift. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
metux Geschrieben 15. Juni 2012 Teilen Geschrieben 15. Juni 2012 Warum unions Speicherplatz spaaren, nur weil man nur das letzte Element, was man geschrieben hat, auch lesen kann, leuchtet mir immernoch nicht ganz ein, immerhin benötigen die Elemente, die ich ein paar Schritte zuvor gespeichert habe auch Speicherplatz. Nein, die verschiedenen Elemente werden auf dem gleichen Speicherbereich dargestellt. Du mußt Dir natürlich durch entsprechend Logik sicherstellen, daß jeweils das richtige Element (mit dem richtigen Typ) verwendet wird. Stell Dir zB. mal vor, Du hast eine Datenstruktur, von der es 3 Untertypen gibt (ein konkrete Instanz hat stets genau einen Untertypen A, B oder C). Dann könnte das in C so aussehen: struct FOO { char type; union { struct { int x; int y; ... } variant_a; struct { long a; char* foo; ... } variant_b; struct { DIR* cwd; char* foo; long x; ... } variant_c; } variants; }; Bei der Allokation speicherst Du dann die Variante im Feld "type", und bei jedem Zugriff wird anhand dessen unterschieden, welcher Untertyp nun angesprochen wird, zB: switch (myfoo.type) { case 'A': printf("Type A: %d, %d\n", myfoo.variants.variant_a.x, myfoo.variants.variant_a.y); break; case 'B': .... } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kadaj Geschrieben 16. Juni 2012 Autor Teilen Geschrieben 16. Juni 2012 Stell Dir einfach eine Tabellenkalkulation wie Calc, Excel oder was Dir sonst noch so einfällt, vor. Eine einzelne Zelle läßt sich mit Ganzzahlen, mit Fließkommazahlen oder bspw. mit Text befüllen. Im Vorfeld weißt du als Entwickler nicht, was drin landet; dann bieten Dir Unions die Möglichkeit, Platzhalter einzusetzen Ah, langsam kommt Licht in die Geschichte! Also spaare ich nur Speicherplatz solange ich noch nicht alles beschrieben habe? Eine Tabelle ist ein gutes Beispiel, Also wächst der Speicher um genau das, was ich in alle "Zellen" schreibe. Wenn ich in alle Zellen die maximale Zeichenlänge reingeschrieben hätte, hätte ich also die selbe größe, die ich bei einem struct hätte, wenn ich kein ohne malloc bzw new arbeiten würde und gleich den vollen Arbeitsspeicher aushebe, wenn ich eine Variable von dieser Struktur anlege. Ist das nicht das selbe, wie ein struct, bei dem ich alle Elemente erst mit new allociere, beim Löschen mit delete freigebe oder beim Ändern mit realloc neu allociere? So wie ich das verstanden habe, würde ich damit das selbe erreichen. Bei der Allokation speicherst Du dann die Variante im Feld "type", und bei jedem Zugriff wird anhand dessen unterschieden, welcher Untertyp nun angesprochen wird Wenn ich das richtig verstanden habe ( was sehr unwahrscheinlich ist^^ ), dann würde mich das wieder auf mein Anfangsproblem zurückbringen. Bevor ich genau eine Variante speichere, kann ich doch gleich genau diese anlegen. Oder meinst du ( wenn ich das mit der "Tabelle" richtig verstanden habe), dass die Elemente, die sich auch noch in der union befinden und vielleicht später deklariert werden, auch erst später allociert werden? Was mich aber auch wieder zu der Frage bringen würde, ob das nicht das selbe sei, wie ein struct mit malloc und free etc. Also an eurer Stelle würde ich an mir verzweifeln^^ Danke für die Hilfe! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 16. Juni 2012 Teilen Geschrieben 16. Juni 2012 Ah, langsam kommt Licht in die Geschichte! Also spaare ich nur Speicherplatz solange ich noch nicht alles beschrieben habe?Nein, das hast du falsch verstanden. Eine Union entspricht einer Tabellenzelle. In einer Zelle kann eine Zahl oder ein Text oder eine Formel stehen, aber immer nur eins davon. Alle Elemente einer Struct stehen hintereinander im Speicher. Alle Elemente einer Union stehen an derselben Stelle im Speicher. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lilith2k3 Geschrieben 16. Juni 2012 Teilen Geschrieben 16. Juni 2012 Ah, langsam kommt Licht in die Geschichte! Also spaare ich nur Speicherplatz solange ich noch nicht alles beschrieben habe? Eine Tabelle ist ein gutes Beispiel, Also wächst der Speicher um genau das, was ich in alle "Zellen" schreibe. Wenn ich in alle Zellen die maximale Zeichenlänge reingeschrieben hätte, hätte ich also die selbe größe, die ich bei einem struct hätte, wenn ich kein ohne malloc bzw new arbeiten würde und gleich den vollen Arbeitsspeicher aushebe, wenn ich eine Variable von dieser Struktur anlege Yop! Ist das nicht das selbe, wie ein struct, bei dem ich alle Elemente erst mit new allociere, beim Löschen mit delete freigebe oder beim Ändern mit realloc neu allociere? So wie ich das verstanden habe, würde ich damit das selbe erreichen. Nope. Nicht so wirklich. Mit dem Union legst Du ja auch fest, wie das, was im Union enthalten ist, interpretiert wird. Beispiel: 1) Int 2) double 3) Char-Array[256] Wenn ich ein struct anlege reserviere ich ja schon für die Pointer auf die entsprechenden Bereiche einen Speicherplatz. Im Union reserviert man dagegen nur den Speicherplatz, den das längste Element einnimmt. So wie ich das verstanden habe, würde ich damit das selbe erreichen. Wie aus dem vorigen klar sein sollte: Nope. dass die Elemente, die sich auch noch in der union befinden und vielleicht später deklariert werden, auch erst später allociert werden? Es wird nur maximal der Wert des längsten Elementes reserviert, der in die Union reinkommt. Beispiel: Ein dem Union analoges Struct enthielte 3 Pointer. Dann wären das unter einer 64Bit Maschine 8 Bytes pro Pointer also 24 Bytes, die schonmal reserviert werden. Was also wesentlich mehr ist, als der Speicher, der nur für ein Int reserviert wird. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Kadaj Geschrieben 16. Juni 2012 Autor Teilen Geschrieben 16. Juni 2012 Ah, nun hab ich es :-) Das war das Stichwort. Bei Zellen weiß ich ja vorher nicht was reingeschrieben wird und bei einigen Tausend Zellen kann man unmöglich jede einzeln anlegen. Nein. Schreibend darfst du zugreifen, wie du möchstest. Lesen darfst du allerdings nur das Element, das du zuletzt geschrieben hast. Nun verstehe ich sogar, was du mir damit sagen wolltest ;-) Es wird nur maximal der Wert des längsten Elementes reserviert, der in die Union reinkommt. Also, heißt das, der Typ/das Element, welches für das übergebene Element/Zeichenkette etc. den wenigsten Speicher benötigt? Danke, dass ihr mich nicht aufgegeben habt^^ Gruß Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lilith2k3 Geschrieben 16. Juni 2012 Teilen Geschrieben 16. Juni 2012 Also, heißt das, der Typ/das Element, welches für das übergebene Element/Zeichenkette etc. den wenigsten Speicher benötigt? Bei einem int, eben ein Wort und bei den vollen 256 Byte Text eben die vollen 256 Byte. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.