Kapitel 5 Strukturen
Information aus der realen Welt werden in einem informationsverarbeitenden
System als Daten abgelegt. Diese stellen also eine (vereinfachte) Abstraktion
der Wirklichkeit dar und spiegeln in vielen Fällen die Strukturen der Wirklichkeit
wider.
In diesem Kapitel wird ein Überblick über die wichtigsten abstrakten
Datenstrukturen gegeben, wobei dieser Begriff zum Begriff des „Datentyps“
erweitert wird.
Anmerkung: Dieses Kapitel abstrahiert die Objekte mit denen Sie in „Einführung
in die Programmierung“ umgehen. Dort werden diese abstrakten Objekte
konkret für Java vorgestellt.
Inhalt
1.
2.
3.
4.
Datenstrukturen - Datentypen
Datentypen: Ein Überblick
Konkrete Datentypen
Abstrakte Datentypen
5.1
Datenstrukturen - Datentypen
In der Literatur wird meist der Begriff „Datenstruktur“ verwendet. In diesem
Unterkapitel soll der Unterschied zwischen diesem Begriff und dem Begriff des
„Datentyps“ erläutert werden.
Inhalt
1. Datenstrukturen
2. Datentypen
3. Variablen eines Datentyps
5.1.1 Datenstrukturen
In der Informatik werden Objekte der realen oder abstrakten Welt erfasst
Bei der Erfassung beschränkt man sich möglichst auf die für den weiteren Transport
/ Speicherung/Verarbeitung/Umsetzung notwendige Information
Zur internen Repräsentation werden diese Objekte abstrahiert
Zur Abstraktion gehört die Erkennung von Strukturen - zunächst im Sinne einer
Aggregation.
Also
Aus welchen Teilobjekten bestehen Objekte ?
In welchem Verhältnis stehen die Teilobjekte zueinander ?
Welches sind die „atomaren“ Teilobjekte ?
es existieren noch weitere strukturelle Beziehungen (z.B. Vererbung)
Anschließend werden diese Objekte typisiert.
Typisierung ist die Einteilung von abstrakten internen Objekten in Gruppen mit
gleichen oder ähnlichen Eigenschaften.
5.1.2 Datentypen
Typen sind also nicht die intern repräsentierten Objekte, sondern beschreiben
die Eigenschaft einer Gruppe von Objekten.
Zu diesen Eigenschaften gehören:
Struktur
Wertebereich
anwendbare Operatoren, Funktionen, Relationen
Beziehungen zu anderen Typen
interne Repräsentationsweise
…
Beispiel:
Imaginäre Zahlen
Einige Anmerkungen::
Der Begriff „Datentyp“ ist weitergehend als der Begriff „Datenstruktur“
In der Objektorientierten Programmierung wird statt „Datentyp“ auch der Begriff
„Klasse“ verwendet (Klassen beschreiben mehr Eigenschaften)
Konkrete Repräsentanten eines Datentyps werden (u.a) „Variable“ oder
- bei OO-Sprachen - „Instanz“ genannt
5.1.3 Variable eines Datentyps
Einen speziellen (rechnerinternen) Repräsentanten eines Datentyps bezeichnet
man als Variable. Die Festlegung, von welchem Datentyp eine Variable ist,
bezeichnet man als Variablendeklaration.
Die Zuordnung eines Typs „Typ“ an eine Variable X wird (zunächst) wie
folgt notiert:
var x : Typ;
Eine Variable hat alle Eigenschaften eines Datentyps.
Zusätzlich dazu hat eine Variable:
einen konkreten Wert.
Der Wert muss aus dem Wertebereich des Datentyps sein (oder undefiniert)
Die Zuweisung eines Wertes „Wert“ an eine Variable X sei (zunächst) wie folgt
notiert:
x = Wert;
einen konkreten Speicherplatz
Dieser Speicherplatz ist so dimensioniert, dass die Struktur der Variable
abgebildet werden kann
Dieser Speicherplatz wird (meist) implizit durch die Deklaration zugeordnet
Beispiel:
var x : Datentyp; // x ist vom Typ: „Datentyp“
x = 531;
// Zuweisung von 531 an X
5.2
Datentypen: Überblick
Nachdem sich nun der Begriff des „Datentyps“ als Oberbegriff der
„Datenstruktur“ erwiesen hat, konzentrieren wir uns im Rest des Kapitels auf
wichtige Datentypen.
In diesem Unterkapitel wird ein Klassifikationssystem für die in der Informatik
verwendeten Datentypen aufgestellt und kurz erläutert
Inhalt
1. Klassifikation der Datentypen
2. Erläuterung der Klassifikation
5.2.1 Klassifikation der Datentypen
Datentypen
Konkrete
Einfache
Abstrakte
Pointer(Zeiger)
Idealisierte
Strukturierte
...
Ordinale
Boolean
(Wahrheitswert)
Integer
(Ganzzahl)
Real
(Fließkomma)
Char
(Zeichen)
Array
(Feld)
Record
Union
(Verbund) (Variantenverb.)
...
Enumeration
(Aufzählung)
5.2.2 Erläuterung der Klassifikation
Idealisierte Datentypen
aus der Mathematik bekannte Datentypen: R, N, Z, ...
Variablen dieser Typen sind oft nicht endlich darstellbar (Bsp: 2)
In einem Computer-Algebra-System symbolisch darstellbar (Bsp: 2^( 1/2))
Konkrete Datentypen
in einem Rechner von Hard- oder Software bereitgestellte Datentypen
entweder vordefiniert oder durch den Benutzer definierbar
Abstrakte Datentypen
verbergen ihren inneren Aufbau vor dem Benutzer
bestehen aus beliebigen Strukturen über konkrete/idealisierte Datentypen, sowie aus
Zugriffsfunktionen bzw. Prozeduren
Beispiel: Baum
13
insert (Element)
6
2
61
12
15
delete (Element)
79
search (Element)
5.3
Konkrete Datentypen
Die am häufigsten abstrahierten Objekte der realen Welt sind, zumindest was
die für eine weitere Verarbeitung notwendigen Informationen betrifft, einfach
strukturiert und lassen sich demnach mit konkreten Datentypen abbilden.
Dieses Unterkapitel gibt einen Überblick über alle konkreten Datentypen und
beschreibt diese.
Inhalt
1. Einfache Datentypen
2. Strukturierte Datentypen
3. Verweise
5.3.1 Einfache: Boolean (Wahrheitswert)
zur Darstellung von Wahrheitswerten
Wertebereich: true, false
intern in manchen Programmiersprachen als 1 bzw. 0 dargestellt
Operatoren: und, oder, nicht, Vergleiche, ...
Operatoren entsprechend der bool‘schen Algebra
oft auch allgemeine arithmetische Operationen möglich
Vorsicht vor Integer-Arithmetik mit Boolean-Variablen
Notation:
Beispiel:
var booleanVar : boolean;
var switch : boolean;
switch = false;
switch = not(switch);
switch = switch and not(switch);
switch = switch or not (switch);
//
//
//
//
=
=
=
=
0 „Bool-Literal“
not(0) = 1
1 and 0 = 0
0 or 1 = 1
Wir müssen uns gleich angewöhnen die „Dinge“ so zu bezeichnen, wie sie in der Informatik
bezeichnet werden:
Schlüsselwort var (Variablen)Bezeichner switch Schlüsselzeichen(-wort) :
(Typ)Bezeichner boolean Schlüsselzeichen(-wort);
Bezeichner switch Operator = (Boolean)Literal false Schlüsselzeichen(-wort);
5.3.1 Einfache: Integer (Ganzzahl)
zur Darstellung ganzer Zahlen mit oder ohne Vorzeichen
Wertebereich: Unterschiedlich
unsigned integer: Ganze Zahlen ohne Vorzeichen ( 0... 65535 )
oft 16 bit bzw. 32 bit als ‚short int‘ bzw. ‚long int‘ bezeichnet
Vorsicht:
16 bit Integer ist verdammt wenig ((± 32267)
Speicherplatz ist nicht mehr teuer benutzen Sie ‚long int‘
(Ausnahmen bestätigen die Regel)
Operatoren: Grundrechenarten, Vergleiche
Operatoren entsprechend der „klassischen“ Algebra
Notation:
Beispiel:
var integerVar : integer;
var
i =
i =
i =
i =
i :
1;
i +
i /
i +
integer;
32;´
17;
65535;
//
//
//
//
= 1 „Integer-Literal“
= 1 + 32 = 33
= 33 / 17 = 1 !
bei unsigned Int.: Fehler !
5.3.1 Einfache: Char (Zeichen)
zur Darstellung von Zeichen
Vorsicht:
Typischerweise wird die ASCII-Codierung zugrundegelegt,
kann aber auch Unicode sein
Wertebereich: Alle Zeichen
Intern codiert als ASCII oder - neuerdings immer öfter - als Unicode
ASCII: 8 Bit (7 benutzt), Unicode: 16 Bit
Intern oft als Integer repräsentiert
Operationen: Vergleich
oft auch allgemeine arithmetische Operationen möglich
Vorsicht vor Integer-Arithmetik mit char-Variablen
Notation:
Beispiel:
var charVar : char;
var symbol : char;
symbol = „A“;
symbol = symbol + 32;´
symbol = symbol - 128;
// = „A“ „Char-Literal“
// = „A“ + 32 = „a“
// = „a“ - 128 = Fehler
5.3.1 Einfache: Enum (Aufzählung)
zur Darstellung endlicher benutzerdefinierter Wertebereich
Es ist guter Stil, Mengen mit (garantiert) kleiner Mächtigkeit (<10) als Enum-Type zu
deklarieren, anstatt sie z.B. als Integer zu kodieren.
Intern werden Enum-Werte oft als Integer abgelegt
Operatoren: Vergleich
oft auch allgemeine arithmetische Operationen möglich
Vorsicht vor Integer-Arithmetik mit Enum-Variablen
Notation:
Beispiel:
var enumVar : enum { Wertemenge };
var ampelfarbe : enum {gruen,gelb,rot} ;
ampelfarbe = gruen;
// = gruen „Enum-Literal“
// Vorsicht: C++ erlaubt das
ampelfarbe = ampelfarbe +1 ; ´ // = gruen + 1 = gelb
ampelfarbe = ampelfarbe +1 ; ´ // = gelb + 1 = rot
ampelfarbe = ampelfarbe +1 ; ´ // = rot + 1 = Fehler !
5.3.1 Einfache: Real (Fließkomma)
zur näherungsweisen Darstellung reeller Zahlen
Wertebereich: Unterschiedliche Genauigkeiten und Wertebereiche
Wertebereich entspricht typischerweise der IEEE 754 Norm, also:
Float: 32 bit
Double: 64 bit
Operationen: Grundrechenarten, erweiterte Arithmetik, Vergleich
Notation: var realVar : real;
Beispiel: //--- Variable declaration -------------------------var pi, flaeche, radius : real;
// all real !
//--- Initialisation -------------------------------pi
= 3,141; // needs not to be more accurate
radius = 5;
// might be changed by user
//--- Computation of surface -----------------------flaeche = 2 * pi * (radius ^ 2);
// common formula
5.3.2 Strukturierte: Array (Feld)
Arrays sind eine Aggregationen von Daten des gleichen Typs
(des „Basistyps“) Aggregation := Zusammenfassung, Anhäufung, Angliederung
Die Grenzen des Arrays sind (meist) statisch bestimmt
Operation: Auswahl
Die Auswahl eines Datenelementes erfolgt über einen ganzzahligen Index über den
(Auswahl-)Operator „ [ ] “
Vorsicht: Zugriff außerhalb des deklarierten Bereiches führt zu Fehlern
Notation:
Beispiele
var arrayVar : array[min .. max] of Datentyp
Eindimensionales array:
Zweidimensionales array:
var Vektor : array[1..4] of real;
Operator
var m : array[1..3]
array[1..2]
var v : array[1..4]
v[3] = 5,03; v[4] =
m[1][2] = v[3] * 12
var Matrix : array[1..3] of
array[1..2] of real;
of
of real;
of real;
4,12;
- v[4];
5.3.2 Strukturierte: Record (Verbund)
Verbunde sind Aggregationen von Daten möglicherweise unter-schiedlichen
Typs
manchmal auch „structure“ oder „struct“ genannt
Operation: Auswahl
Die Auswahl erfolgt durch Angabe des Komponentennamens
(durch einen Punkt vom Variablennamen getrennt)
Notation:
var recordVar : record
{
komponent1 : type1;
...
};
Beispiel:
var d :
{
tag
monat
};
d.monat
d.tag
record
: Integer;
: Integer;
= 10;
= 20;
5.3.2 Strukturierte: Variant Record
(Variantenverb.)
Verbunde, deren Struktur mögliche Alternativen zulassen
manchmal auch „union“ genannt
lassen „Varianten“ eines Record-Types zu
Operation: Auswahl (wie bei records über Punkt-Operator)
Notation: var recVar :
record {
komponent1 : type_1;
...;
case variant (variant1,...) of {
variant1 : type_n;
...
}
TAGGED TYPE
}
Unterelement „variant“ implizit definiert bei „tagged type“
Nur ein Unterelement aus variant1, ... (sinnvoll) verwendbar
Beispiel:
var adam,eva : record {
name : array [1..20] of char;
case sex (m,f) of {
f: {IQ: integer};
m: {muscle: real}; // in cm
}
adam.sex
adam.muscle
eva.sex
eva.IQ
=
=
=
=
m;
20,5;
f;
132;
5.3.2 Strukturierte: Variant Record
var adam,eva : record
name
case
f:
m:
}
adam.sex
adam.muscle
eva.sex
eva.IQ
=
=
=
=
m;
20,5;
f;
132;
Umsetzung:
name
{
: array [1..20] of char;
sex (m,f) of {
{IQ: integer;}
{muscle: real;}}
sex IQ /
muscle
Variant Records mit „Untagged Types“ (z.B. C, C++ : Union)
struct {
char[20] name;
enum {m,f} sex; // ...
union {
int IQ;
real muscle;} // in cm
} adam, eva;
(2. Variante)
adam.sex
adam.muscle
eva.sex
eva.IQ
=
=
=
=
m;
20,5;
f;
132;
5.3.2 Vereinfachung der Notation („type“)
var Person : record { surname : array [1..20] of char;
forename : array [1..20] of char;
birthday : record { year : integer;
month : enum {jan,...};
day
: integer; };
};
var Akt_Datum : record { year : integer;
month : enum {jan,feb,...};
day
: integer; };
In (fast) allen Programmiersprachen ist es möglich, beliebig strukturierte
Datentypen neu zu bezeichnen und diese Typ-Bezeichner wie vordefinierte
Typen zu verwenden:
Notation:
Beispiel:
type NeuTyp : Typ;
type Datum : record { year : integer;
month : enum {jan,feb,...};
day
: integer; };
var Person: record {surname : array [1..20] of char;
forename : array [1..20] of char;
birthday : Datum };
var Akt_Datum: Datum;
5.3.3 Pointer (Zeiger, Verweis)
Zeiger-Datentypen sind durch folgende Eigenschaften gekennzeichnet:
Die Struktur ist identisch der eines Integer-Datentyp (also oft 16,32,... Bit)
Der Wertebereich ist der des Adressbereiches eines Rechnersystems,
der zusätzliche Wert „nil“ bezeichnet einen ungültigen Zeiger.
Operatoren sind:
Erzeugen eines Zeigers (Referenzierung &)
Zugriff auf verwiesenen Bereich (Dereferenzierung *)
Integer-Operatoren (Vorsicht !!!!)
Notation:
Beispiel:
var pointerVar : *Type;
var x : *Integer;
// Deklaration
var y,z : Integer;
// Deklarationen
y = 5; // Initialisierung der Variablen y
x = &y; // Referenzieren: x ist Zeiger auf y
x* = 2; // Derefenzierung: das worauf x zeigt
wird zu 2
z = y; // Variable z bekommt den Wert von
Variable y zugewiesen.
// z hat jetzt den Wert 2
5.3.3 Pointer: Beispiel
Vorsicht:: Werte oft undefiniert
Bsp.: x : *Integer; // Deklaration
y : Integer;
// Deklaration
1 2 3 4 5 6 7 8 9
23 24 25 26 27 28
Wortadressen
nil
0
...
y = 5; // Initialisierung der Variablen y
1 2 3 4 5 6 7 8 9
23 24 25 26 27 28
nil
5
...
x = &y; // Referenzieren: x ist Zeiger auf y
1 2 3 4 5 6 7 8 9
23 24 25 26 27 28
25
5
...
x* = 2; // Dereferenzierung: das worauf x zeigt
1 2 3 4 5 6 7 8 9
23 24 25 26 27 28
25
2
...
x = 2; // Zuweisung ohne Dereferenzierung !
1 2 3 4 5 6 7 8 9
23 24 25 26 27 28
2
2
...
5.3.3 Pointer: Dynamische Datentypen
Mit konkreten, d.h. einfachen und strukturierten Datentypen lassen sich nur
statische Struktur aufbauen
d.h. Strukturen, deren Speicherbedarf beliebig aber fest sind
Bem.: Die Beliebigkeit ist begrenzt durch die Gesamtspeicherkapazität
Mit Zeiger-Datentypen lassen sich Strukturen aufbauen, die sich dynamisch
auf- und abbauen lassen
d.h. Strukturen, deren Speicherbedarf sich dynamisch verändern kann
d.h. der Speicherplatz muss auch dynamisch organisiert werden.
Bem.: Auch hier ist die Beliebigkeit begrenzt durch die Gesamtspeicher-kapazität
Beispiel:
type knoten : record
{
symbol : char;
links : *knoten;
rechts : *knoten;
}
var wurzel : knoten
Huffman
(Bsp. aus Kap.2)
B
C
E
D
A
5.3.4 Beispiel: Kombinierte Datentypen
Um nun beliebig komplexe Strukturen der „realen“ Welt in einem Rechensystem
abbilden zu können, kann man die vorgestellten Datentypen beliebig
miteinander Kombinieren
Beispiel.:
type Person : record {
surname : array [1..20] of char;
forename : array [1..20] of char;
birthday : Date;
next
: *Person;
previous : *Person;
}
type Date
year :
month :
day
:
}
: record {
integer;
enum {jan,feb,...};
integer;
5.4
Abstrakte Datentypen
Grundsätzlich lassen sich alle Objekte der realen Welt ausschließlich mit Hilfe
einfacher Datentypen abbilden. Diese Abbildung ist aber meist „unnatürlich“,
weil sie die Struktur realer Objekte nicht ausreichend berücksichtigt. Abhilfe
schaffen hier strukturierte Datentypen, die allerdings grundsätzlich nur endliche
Objektmengen repräsentieren können. Hier schaffen Zeigertypen Abhilfe.
Kann man nun mit diesen Mitteln Strukturen realer Objekt natürlich abbilden, so
fehlen diesen abstrakten Datentypen einige der Eigenschaften, die konkreten
Datentypen von Datenstrukturen unterscheiden, dies sind insb.
Operationen und
Beziehungen zu anderen Typen.
Einen vertieften Einblick in die bunte Welt abstrakter Datentypen bietet die
Vorlesung des 2. Semesters
Datenstrukturen
5.5
Zusammenfassung des Kapitels
Datentypen
Konkrete
Einfache
Abstrakte
Pointer(Zeiger)
Idealisierte
Strukturierte
...
Ordinale
Real
(Fließkomma)
Array Record Union
(Feld) (Verbund) (Variantenverb.)
...
Enumeration
Boolean
Integer
Char
(Wahrheitswert) (Ganzzahl) (Zeichen) (Aufzählung)
Wir sind damit auch an die Grenzen dessen gelangt, was in dieser Vorlesung
über die „Statik“ von Objekten gesagt werden soll und wenden uns einem noch
spannenderem Themenbereich zu ;-)