Info 16 (Zuweisungso..

Werbung
Zuweisungsorientierte Programmierung.
Wesentliches Element Funktionaler Programmierung ist den Wert einer Funktion zu
berechnen und an das aufrufende Programm zurückzugeben. Übergibt man einer Funktion
Parameter, so bleiben diese unverändert. Bei der Berechnung werden neue Objekte erzeugt.
Beispiel:
Einfügen in Listen (funktional) l = [1;2;4] Anwendung der Funktion insertSort(3,l) ergibt:
lneu = [1;2;3;4]
Dabei werden l und lneu durch die Inhalte verschiedener Speicherbereiche repräsentiert.
Anderes Beispiel: der schrittweise Aufbau einer 4- elementigen Liste produziert auch die
Listen [] [a], [a;b], [a;b;c].
Unmittelbar speichereffizienter ist es hier, das jeweils nächste Element unmittelbar an die
vorhandene Repräsentation der Liste im Speicher anzuhängen).
Ein solches direktes Operieren auf „Elementen“(„hier konnt ich leider nicht die Schrift
entziffern„) ist das Kernkonzept der etsich damit zuweisungsorientierten Programmierung.
Sprachkonzept unterscheidet sich damit fundamental vom Funktionalen und baut direkt auf
Architektur der von- Neumann- Maschine mit linearen Speicher auf.
Die Inhalte des Speichers kennzeichnen also den Zustand der Berechnung. Das Programm
bzw. seine Einzelschritte ändern diesen Zustand: jeweils letzter Berechnungszustand ist
Eingangszustand für die nächste Berechnung. Im Unterschied zur funktionalen
Programmierung wird auf den Objekten selbst operiert.
u 1
v 2
w 3
incr u
u 2
v 2
w 3
Bei funktionaler Programmierung würde eine weitere Speicherzelle mit dem Wert 2 belegt
werden.
Realisierung des Konzepts „Zuweisung“.
Mit einer Zuweisung wird einer Variablen v das Resultat eines Ausdrucks E zugewiesen.
Syntax: <var_name> <zuweisungsop><E>
Beispiel:
Pascal v:= 17/3;
v:= v + 1;
C
v:=17/3;
v = v+1;
In Ocaml ist C- artige Zuweisung nicht möglich, denn der syntaktisch Korrekte Ausdruck
let rec v = v+1;; entspricht einer nicht terminierenden rekursiven Funktion. Möchte man in
OCAML mit Variablen in o.g. Sinne arbeiten, so muss ausgedrückt werden, dass der
„Funktionsname“ die Adresse einer Speicherzelle (bzw. der Verweis auf einem
Speicherbereich ist). Dies geschieht mittels Referenzen (Zeiger, Pointer). Referenz ist ein
Verweis auf einer Adresse eines Speicherbereichs der von- Neumann- Maschinen.
Deklaration einer Variablen in OCAML:
let v = ref 1;;
Gleichzeitig Vereinbarung von v als Zeiger und Belegung der Zelle, auf die v verweist, mit
dem Wert 1.
Syntax: let <name> = ref <expression> ;;
Der Typ wird aus <expression> ermittelt.
Zuweisung in OCAML:
Die Pascal Zuweisung v := v+1; lautet in OCAML v:= !v + 1;
Weiterer Begriff: Prozeduren (vs. Funktionen).
Im imperativen Sprachen arbeitet man häufig mit Prozeduren, also Sequenzen von
Anweisungen, die eine Variablen Belegung modifizieren, jedoch im Gegensatz zu
Funktionen keinen Wert zurückliefern.
Beispiel: (In Pascal)
function ggT (a,b: Integer) : Integer;
procedure druck_ggT(a,b: Integer);
Man kann Prozeduren als Funktionen auffassen die den Zustand der Berechnung (der
Maschine) ändern, aber keinen Rückgabewert produzieren.
OCAML: Da hier eine Funktion stets einen Wert zurückgeben muss, wird definiert, dass eine
Prozedur das Element „()“ ^= ‚unit’ zurückgibt. (So wie void in Java).
Strukturierte Datentypen: Records und Produktsorten.
Häufig möchte man Datentypen konstruieren, die Teildaten zu einer inhaltlichen
zusammenhängenden Einheit zusammenfassen. Dazu verwendet man Records. Vereinbarung
solcher Records.
a) in Pascal:
type <record_name> „ = record“
{ <element_name>“,“<type>“;“}*
„end;“
b) in Ocaml:
type <record_name> „ = {„
<dokument_name> „ ; “ <type>“;“
…
„};;“
Pascal: ZÜ
JAVA: TÜ.
Beispiel in Ocaml:
type c
complex = { real: float; imag: float}
Erzeugung: let c = {real = 2.0; imag = 30 }
Zugriff über Punktnotation: c.real ergibt 2.0
Zusatzbemerkung:
Records sind in OCAML zunächst nicht variabel, soll dies der Fall sein, so müssen
Teilelemente als „mutable“ Attribute werden.
type punkt = { mutable x: float;
mutable y: float};;
Zuweisung tatsächlicher Werte:
let p1 {mutable x = 1.0,…
Zuweisung: p1.x  3.0
Weitere Bemerkung: Eine Referenz in OCAML wird aufgefasst als ein Record mit
einem einzigem Element, welches mutable ist, also:
type ’a ref = { mutable content ’a};;
Dynamische Datenstrukturen :
Mit Hilfe von Records lassen sich die aus der funktionalen Programmierung bekanten
rekursiven Sorten (Listen, Bäume,…) zuweisungsorientiert in imperativen
Programmiersprachen nachempfinden.
Kernstücke sind Records, die rekursive Struktur haben.
Beispiel: für Liste von Ganzzahlen
1
4
Referenzen
6
nil
Inhalt
Record besteht aus zwei Teilen: Erste Konnpunkte enthält das eigentliche Element
(‚Nutzinfo’); zweite Komponente enthält Referenz auf weiteren Record desselben Typen, der
hier das nächste Listenelement darstellt.
Für die Liste ergeben sich also folgende Typdefinitionen;
type Lref = Nil | Ref of lnode
and Lnode = { mutable valu : int;
mutable next: Lref};;
Im folgenden Formatierung der Standardoperation für die uns von dem funktionalen
Sequenzen her beannten Operationen first, last append.
Herunterladen