EinVerbund (englischobject composition) ist einDatentyp, der aus einem oder mehreren Datentypen zusammengesetzt wurde. Die Komponenten eines Verbunds können wiederum Verbünde sein, wodurch auch komplexeDatenstrukturen definiert werden können.
Die Komponenten/Elemente eines Verbunds werden normalerweise nacheinander im Speicher angeordnet (beispielsweise alsstruct in derProgrammiersprache C bzw. alsrecord inPascal). Eine Ausnahme stellenUnions dar. Auch in anderenProgrammiersprachen (siehe unten) wird dieser Datentyp zum Teil unterschiedlich bezeichnet.
In den ProgrammiersprachenC undC++ werden Verbünde (engl. auchcomposite types) alsStruktur bezeichnet und mit dem Schlüsselwortstruct (kurz für engl.structure ‚Struktur‘) deklariert. Die einzelnen Komponenten einer Struktur, die sog.members ‚Mitglieder‘ dürfen dabei beliebige einfache Datentypen, Felder konstanter Größe oder einZeiger auf dieselbe Struktur sein.
Im Gegensatz zurunion überlappen sich die Speicherbereiche der einzelnen Strukturmitglieder nicht.
#include<stdio.h>structPerson{intPersonalnummer;intAlter;charName[20];};structPerson*Person_anhand_Personalnummer(int);intmain(void){structPerson*person=Person_anhand_Personalnummer(12345);printf("Personalnummer: %i, Alter: %i\n",person->Personalnummer,person->Alter);}
Hat man einenZeiger auf die Struktur, dann wird, wie gezeigt, auf einzelne Members am einfachsten mithilfe des Pfeils-> zugegriffen, bspw.person->Alter. Der Pfeil (engl.arrow) ist eine Kurzschreibweise für(*person).Alter mit dem Stern* als Dereferenzierungsoperator (engl.dereference operator) und dem Punkt. als Selektor (engl.object selector).
Eine Struktur kann größer sein als die Summe der einzelnen Datentypgrößen, da derCompiler die einzelnen Attribute im Speicher an bestimmten Adressenausrichten kann. Die Anordnung der Struktur im Speicher ist nach der Übersetzung festgelegt und kann nicht mehr verändert werden.
In C können Strukturen lediglichVariablen,Zeiger,Arrays und andere Strukturen enthalten, während Strukturen in C++ die zusätzliche Fähigkeit besitzen,Unterprogramme – sogenannteMethoden – zu beinhalten, zu denen auchKonstruktoren undDestruktoren gehören.[1] Dies lässt sich in C nur teilweise über Funktionszeiger realisieren, die auch Teil von Strukturen sein können.
In C++ dienen die Schlüsselwörterpublic undprivate dazu, die Zugriffsrechte auf Attribute und Methoden in Strukturen und Klassen zu regeln. Der einzige Unterschied hier ist, dass ohne explizite Angabe die Attribute von Strukturen standardmäßigpublic (Zugriff von außen erlaubt), die einer Klasseprivate (Zugriff nur von innerhalb der Klasse oder durchFriend-Funktionen) sind.[2]
Ein Verbund (in Pascal mitrecord bezeichnet) vom DatentypPerson für die beiden InstanzenMustermann1 undMustermann2 könnte inComponent Pascal zum Beispiel folgendermaßen definiert und verwendet werden, und nur Instanzen desselben Datentyps sind in dieser Programmiersprachezuweisungskompatibel:
MODULEPersonen;IMPORTDates;TYPEPerson=RECORDVorname,Name,Wohnort:ARRAY256OFCHAR;Geburtstag:Dates.Date;END;VARMustermann1,Mustermann2:Person;BEGINMustermann1.Vorname:="Hans";Mustermann1.Name:="Mustermann";Mustermann1.Wohnort:="Musterstadt";Mustermann1.Geburtstag.day:=1;Mustermann1.Geburtstag.month:=1;Mustermann1.Geburtstag.year:=1900;Mustermann2:=Mustermann1;(* Zwei Variablen vom selben Datentyp sind zuweisungskompatibel *)ENDPersonen.
Der importierte imModulDates definierte DatentypDates.Date ist wiederum ein Verbund mit den ganzzahligen Elementenday (Tag),month (Monat) undyear (Jahr).
InSwift werden Verbünde wie auch in C alsstruct definiert. Dabei wird jedoch festgelegt, dass Instanzen des Verbunds stets auf dem Stack gespeichert werden. Wird eine Instanz A einesstructs an eine andere Instanz B geschrieben, so erfolgt dies durch Kopieren des gesamten Speicherinhalts der Instanz A in den für die Instanz B reservierten Speicherbereich. Das Gleiche passiert beim Aufruf einer Funktion, die für einen Parameter ein struct als Typ vorsieht (siehe:Wertparameter).
Demgegenüber werdenKlassen in Swift (definiert über das Keywordclass) immer auf demHeap abgelegt und innerhalb der Variable stets alsReferenz auf diesen Speicherbereich auf dem Heap geführt. Wird eine Variable A als Instanz einer Klasse einer Variablen B als Instanz derselben Klasse zugewiesen, so wird lediglich die Referenz kopiert.
InCobol wird der Datentyp Verbund‚Datengruppe‘ (auchGruppen-Variable odergroup item) genannt. Eine Datengruppe wird mit ihrem Bezeichner deklariert und ist der Überbegriff bzw. die Zusammenfassung für die ihrhierarchisch untergeordneten Datentypen – die selbst wieder Datengruppen sein können. Sie hat selbst keine Formatspezifikation (PIC-Klausel). Über dieOCCURS-Klausel kann auch eine Datengruppe als Tabelle (=Array) deklariert werden, ggf. auch mehrstufig.
In den die Datengruppe ansprechenden Befehlen wird die Gesamtheit der ihr untergeordneten Felder als ein (1)Datenfeld im PIC-X-Characterformat und in der Gesamtlänge aller Einzelfelder behandelt. Bei einemMOVE-Befehl etwa findet also keine individuelle formatspezifische Verarbeitung der Einzelfelder statt, auch keine Formatkonvertierung.
Über dieREDEFINES-Klausel kann eine Datengruppe eine andere Datengruppe 'redefinieren', wodurch beide Datengruppen denselben Speicherplatz benutzen. Angewendet wird dies beispielsweise für die Verarbeitung unterschiedlicher Eingabedaten, alternativ in der einen oder in der anderen Datenstruktur. Dies entspricht dem Konstrukt UNION in anderen Programmiersprachen.
Bei sog.Unions beginnen alle Komponenten an der gleichenSpeicheradresse, d. h., ihre Speicherbereiche überlappen sich ganz oder zumindest teilweise. Eine Union belegt dabei mindestens so viel Speicher, wie ihre größte Komponente.
Unions sind in verschiedenen Programmiersprachen entweder als tagged-Unions oder untagged-Unions implementiert.
Eine tagged-Union ordnet jeder Komponente einen Tag zu. Beim Schreiben einer Komponente wird der Tag dieser Komponente in der Union-Variable gespeichert. Bei Lesezugriffen auf die Komponente einer Union wird der Tag der zu lesenden Komponente mit dem Tag der letzten geschriebenen Komponente verglichen. Unterscheiden sich die Tags, ist ein Typfehler festgestellt. Somit sind tagged-Unionstypsicher.
Untagged-Unions verwenden keine Tags und sind deswegen typunsicher. D. h., es liegt in der Verantwortung des Programmierers, ob der letzte Schreibzugriff einer Union die gleiche Komponente verändert hat, die auch der darauf folgende Lesezugriff ausliest. Neben unbeabsichtigten Typfehlern bei der Verwendung von untagged-Unions existieren aber auch Anwendungsfälle für dieSeiteneffekte von untagged-Unions. Beispielsweise eine Union aus einerIEEE-Gleitkommazahl und einerstruct, deren Komponenten den Zugriff auf Vorzeichen, Mantisse und Exponent erlauben.
#include<stdio.h>#include<math.h>#include<inttypes.h>unionFloat64Components{doubleFloat64;struct{uint64_tMantissa52:52;uint64_tExponent11:11;uint64_tSign1:1;};};voidmain(){unionFloat64Componentspi;pi.Float64=3.1415926535897932384626433832795;printf("%20.16f %13I64X %03I64X %01I64X (%20.16f)\n",pi.Float64,pi.Mantissa52,pi.Exponent11,pi.Sign1,(pi.Sign1?-1:+1)*(1.0+pi.Mantissa52/4503599627370496.0)*pow(2,pi.Exponent11-1023));}
Output
3.1415926535897931 921FB54442D18 400 0 ( 3.1415926535897931)
Beispiel der Deklaration einer Union inHaskell:
dataTreea=Br(Treea)(Treea)|Leafa|Nil
Tree ist ein algebraischer Datentyp. Br, Leaf und Nil sind die Konstruktoren.
Unions in Pascal heißenvariante Teile.[3] Das folgende Beispiel macht einen Chunknamen, wie er z. B. inPNG vorkommt, wahlweise als vorzeichenlose 32-Bit-Ganzzahl (Cardinal) oder alsZeichenkette ansprechbar:
typeTChunkname=recordcaseBooleanofFalse:(Int:Cardinal);True:(Str:array[0..3]ofAnsiChar);end;
Anmerkungen:
Bei Variablen, nicht jedoch Feldern von Datentypen, kann man in einigen Dialekten wie Delphi hinter dem Datentyp das Schlüsselwortabsolute gefolgt vom Bezeichner einer anderen Variablen angeben, um deren Speicher mitzuverwenden.[4] So entsteht eine Art Ad-Hoc-Union. Andere Dialekte erlauben auch die Angabe einer Speicheradresse.
Alle Pascal-Datentypen belegen immer eine Größe in ganzen Bytes. Da auch die Felder in einer Union immer die volle Größe ihrer Datentypen einnehmen, ist das Zerlegen einer IEEE-754-Gleitkommazahl wie im C-Beispiel oben mit Unions alleine nicht möglich.