16. Modularität und Abstraktion

Slides:



Advertisements
Ähnliche Präsentationen
der Universität Oldenburg
Advertisements

Imperative Programmierung
Prof. Dr. S. Albers Prof.Dr.Th Ottmann
Zusammenfassung der Vorwoche
7. Natürliche Binärbäume
Kapitel 5. Stacks und Queues
Pascal-Datentypen Skalare Typen Zeiger- Typen Strukturierte Typen
Kapitel 3: Listen Lineare Liste: endliche Folge von Elementen eines Grundtyps (n>=0), leere Liste falls n=0 Listenelemente besitzen.
10. Grundlagen imperativer Programmiersprachen
12. Iteration und Rekursion
Synonyme: Stapel, Keller, LIFO-Liste usw.
der Universität Oldenburg
DINAMISCHE STRUKTUREN FACHBEGRIFFE 1. DER POINTERDER POINTER 2. DER BUFFERDER BUFFER 3. DER KNOTENDER KNOTEN DIE EINFACHVERKETTETE LISTE DEFINITION DEFINITION.
Gliederung Motivation / Grundlagen Sortierverfahren
Java: Objektorientierte Programmierung
Java: Dynamische Datentypen
WS Algorithmentheorie 13 - Kürzeste (billigste) Wege Prof. Dr. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (13 – Offenes Hashing) Prof. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (06 - Anwendungen von Stapeln und Schlangen) Prof. Th. Ottmann.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (27 – Kürzeste Wege) Prof. Th. Ottmann.
1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (21 – Kürzeste Wege) T. Lauer.
Vorlesung Informatik 2 Algorithmen und Datenstrukturen (05 – Elementare Datenstrukturen) Prof. Th. Ottmann.
Informatik II, SS 2008 Algorithmen und Datenstrukturen Vorlesung 6 Prof. Dr. Thomas Ottmann Algorithmen & Datenstrukturen, Institut für Informatik Fakultät.
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 7 Claudio Moraga, Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 12 Claudio Moraga, Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS 99/00 Gisbert Dittrich FBI Unido
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I Kapitel 10 Claudio Moraga; Gisbert Dittrich FBI Unido
6 Folgen (Teil II - Datenstrukturen und Algorithmen)
Imperative Programmierung
PRJ 2007/1 Stefan Dissmann Motivation Problem: gleiche Datenstrukturen werden für verschiedene Objekte gebraucht: z.B. Listen von Studierenden, Kunden,
PKJ 2005/1 Stefan Dissmann Rückblick auf 2005 Was zuletzt in 2005 vorgestellt wurde: Klassen mit Attributen, Methoden und Konstruktoren Referenzen auf.
Programmierung 1 - Repetitorium WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage:
DVG Klassen und Objekte
Weiteres Programm Studium des Breitendurchlaufs Hierzu
Einführung in die Programmierung Datensammlung
Kapitel 2: Datenstrukturen
Stacks Referat im Fach Basisinformationstechnologien von Venelina Koleva.
Einfach verkettete Listen (OOP)
PRJ 2007/1 Stefan Dissmann Verkettete datenstruktur: Liste Problem: Liste, die eine beliebige Zahl von Elementen verwaltet Operationen: Erzeugen, Anfügen,
Abteilung für Telekooperation Übung Softwareentwicklung 1 für Wirtschaftsinformatik Dr. Wieland Schwinger
Eine Implementierung einer effiziente externe geordnete (!) lineare Liste Operationen: Search(x) Insert(x) Delete(x)
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
BIT – Schaßan – WS 02/03 Basisinformationstechnologie HK-Medien Teil 1, 11.Sitzung WS 02/03.
Grundlagen der Programmierung
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fakultät.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fakultät.
1.6 Die Datenstruktur Stapel Ein Stapel (Stack) ist ein Sonderfall einer Liste. Die Elemente werden nach dem Prinzip LIFO (Last In First Out) angefügt.
Einfach und doppelt verkettete Listen in JAVA by Jens Weibler
Institut für Wirtschaftsinformatik – Software Engineering, JKU Linz 1 Thomas Hilpold: Algorithmen und Datenstrukturen SS 2005 Mag.Th. Hilpold u. Dr. A.Stritzinger.
Grundlagen Wissenschaftlichen Arbeitens Hilal Tekoglu
MODULA-2.
Agenda für heute, 18. Mai, 2006 Strukturierung von Programmen: ProzedurenStrukturierung von Programmen: Prozeduren Strukturierung von Programmen: Units.
Agenda für heute, 12. Mai, 2005 ProzedurenProzeduren Funktionsprozeduren Prozedurparameter Lokale und globale Variablen Datentypen: Ordinaltypen.
Kapitel 5: Von Datenstrukturen zu Abstrakten Datentypen
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
2 Datenabstraktion Geheimnisprinzip:
Algorithmen und Datenstrukturen 1 SS 2002
Kapitel 5Strukturen Information aus der realen Welt werden in einem informationsverarbeitenden System als Daten abgelegt. Diese stellen also eine (vereinfachte)
Extended Pascal ( Erweitreung von Pascal) Name: Mehmet CELIK Matr :
The Programming Language Pascal
Extended Pascal Erweiterung von Pascal shadi Behzadipour shadi Shadi behzadipour.
Programmiersprachen II Fortsetzung Datenstrukturen Prof. Dr. Reiner Güttler Fachbereich GIS HTW.
Tutorium Software-Engineering SS14 Florian Manghofer.
Schlange und Stapel.
GRUNDLAGEN WISSENSCHAFTLICHEN ARBEITENS MODULA-2 SONAY SUBAYAZ
1. Die rekursive Datenstruktur Liste 1.6 Die Datenstruktur Stapel
 Präsentation transkript:

16. Modularität und Abstraktion von-Neumann-Rechner zunächst binär programmiert: Daraus wurde ein Oktal- oder Sedezimal-Code: Darin enthaltene Befehlscodes wurden durch Operator-Symbole vereinfacht: Anstelle der Speicheradressen traten symbolische Marken und Bezeichner: Die Formulierung von Ausdrücken im Programm wurde zugelassen: ARGUM = ARGUM + 1 Durch Abstraktion von Berechnungsvorschriften entstanden Funktionen und Prozeduren 0000 1010 0000 0000 0011 1100 1000 1010 0000 0011 0000 0000 0000 0000 0000 0001 0000 1011 0000 0000 0011 1100 1000 1010 0A00 3C8A 0300 0001 0B00 3C8A LDA 3C8A AAD 0001 SPA 3C8A MARK1 = LDA ARGUM ADD 1 SPA ARGUM

Abstraktion in Modula-2 Dienst-Modul in zwei Teile gegliedert: • Schnittstelle („Definition Module“) und • Implementierung („Implementation Module“). Verknüpfung von Modulen durch Importieren der Bezeichner aus Schnittstelle Vorteile: Schnittstellenprüfung ohne Kenntnis der Implementierung Neuimplementierung der in der Schnittstelle deklarierten Prozeduren zieht keine Änderung des importierenden Moduls nach sich, auch keine Neuübersetzung. Bei den Prozeduren ist eine höhere Abstraktion erreicht, den ihre Realisierung ist unsichtbar. Die Bearbeitung und Übersetzung ist jeweils auf relativ kleine, überschaubare und leicht zu handhabende Einheiten begrenzt. aussagekräftige Bezeichner ausführliche Kommentare in den Schnittstellen, die die Funktion der Prozeduren beschreiben, auch für Fehler- und Sonderfälle. Nachteil: Konsistenz schwerer zu erreichen. Daher sind besonders wichtig:

Modularisierung von Modula-2-Programmen Die Verwendung von Objekten aus anderen Modulen in einer Schnittstelle erfordert deren Import. Deren Gültigkeit beschränkt sich allerdings auf die Schnittstelle selbst. Werden diese Objekte auch in der Implementierung benutzt, so müssen sie dort erneut importiert werden. • Die erste Regel gilt nur für Importe aus anderen Modulen, nicht für Konstanten, Typen und Variablen, die in der zugehörigen Schnittstelle deklariert sind. Diese dürfen nicht in der Implementierung desselben Moduls erneut deklariert werden. Nur die Prozedurköpfe werden wiederholt. Ein zyklischer Import (Beispiel: die Schnittstelle eines Moduls M2 importiert aus Modul M1 und umgekehrt) zwischen Schnittstellen ist nicht möglich. Wohl erlaubt ist hingegen, daß die Implementierungen gegenseitig aus den Schnittstellen importieren. Import einzelner Objekte: FROM Modul1 IMPORT a,b,c; (* a,b und c muessen in der Schnittstelle von Modul1 deklariert sein *) Verwendung: ...; a := b + c; .... Import des ganzen Moduls: IMPORT Modul1; Verwendung einzelner Objekte: ...; Modul1.a := Modul1.b + Modul1.c; ...

Modularisierung von Doppelkette Schnittstelle: DEFINITION MODULE EinfuegenUndLoeschen; (* Programm 1a *) TYPE ZeigTyp = POINTER TO ZeigRec; ZeigRec = RECORD Key : CARDINAL; Prev, Next : ZeigTyp; END (* RECORD *); VAR Anker : ZeigTyp; PROCEDURE Einfuegen (Nr: CARDINAL); (* fuegt neues Element Nr in die geordnete Liste ein. *) PROCEDURE Loeschen (Nr: CARDINAL); (* loescht Element Nr in Liste (muss vorhanden sein) *) END EinfuegenUndLoeschen.

Implementierung IMPLEMENTATION MODULE EinfuegenUndLoeschen; FROM Storage IMPORT (* PROC *) ALLOCATE, DEALLOCATE; PROCEDURE Einfuegen (Nr: CARDINAL); (* fuegt neues Element in die geordnete Liste ein *) VAR Hilf1 : ZeigTyp; BEGIN (* Einfuegen *) Hilf1 := Anker^.Next; WHILE (Hilf1^.Key < Nr) AND (Hilf1 <> Anker) DO Hilf1 := Hilf1^.Next; (* Nachfolger des neuen Elem. ...*) END (* WHILE *); (* ... oder Kettenende suchen *) WITH Hilf1^ DO (* der Nachfolger des neuen Elementes *) ALLOCATE (Prev^.Next, SIZE (ZeigRec)); (* neues Element einfuegen *) WITH Prev^.Next^ DO Key:= Nr; Next:= Hilf1; Prev:= Hilf1^.Prev; END (* WITH *); (* neues Element definiert *) Prev := Prev^.Next; (* neuen Vorgaenger anhaengen *) END (* WITH *); END Einfuegen;

PROCEDURE Loeschen (Nr: CARDINAL); (* loescht Element in Liste. Element mit Key = Nr muss vorhanden sein. *) VAR Hilf1 : ZeigTyp; BEGIN (* Loeschen *) Hilf1 := Anker^.Next; WHILE Hilf1^.Key # Nr DO Hilf1 := Hilf1^.Next; (* suchen *) END; WITH Hilf1^ DO Prev^.Next := Next; Next^.Prev := Prev; END (* WITH *); DEALLOCATE (Hilf1, SIZE (ZeigRec)); (* Element ist geloescht *) END Loeschen; BEGIN (* EinfuegenUndLoeschen *) (* Kette mit fliegendem Anker initialisieren *) ALLOCATE (Anker, SIZE (ZeigRec)); WITH Anker^ DO Key := 0; Next := Anker; Prev := Anker; END EinfuegenUndLoeschen.

Test-Modul MODULE DoppelKette; (* Programm 1c *) FROM InOut IMPORT (* PROC *) WriteCard, WriteLn; FROM EinfuegenUndLoeschen IMPORT (* TYPE *) ZeigTyp, ZeigRec, (* VAR *) Anker, (* PROC *) Einfuegen, Loeschen; PROCEDURE ZeigKette; VAR Hilf1 : ZeigTyp; BEGIN (* ZeigKette *) Hilf1 := Anker^.Next; WHILE Hilf1 # Anker DO WriteCard (Hilf1^.Key, 3); Hilf1 := Hilf1^.Next; END (* WHILE *); WriteLn; END ZeigKette; BEGIN (* DoppelKette *) Einfuegen(7); Einfuegen(1); Einfuegen(4); Einfuegen(5); Einfuegen(9); ZeigKette; Loeschen (1); Loeschen (9); Loeschen (5); ZeigKette; END DoppelKette.

Datenkapselung Bei vollständiger Datenkapselung darf keine Variable exportiert werden Dienst-Modul Kunden-Modul Schnittstelle Import Anbindung an Dienstmodul durch Prozeduraufrufe Konstanten- und Typdefinitionen Prozedurdeklarationen Implementierung VAR gekapselte Datenstruktur Prozedurdefinitionen interne Daten und Prozeduren BEGIN Initialisierung END

Schnittstelle DEFINITION MODULE KettenKapsel; (* Programm 2a *) (* Besser strukturierte Variante des Programms 1 *) PROCEDURE Einfuegen (Nr: CARDINAL); (* fuegt neues Element in die geordnete Liste ein. *) PROCEDURE Loeschen (Nr: CARDINAL); (* loescht Elem. in Liste. Element mit Key = Nr muss vorhanden sein *) PROCEDURE ZeigKette; (* zeigt den aktuellen Stand der Kette auf dem Bildschirm *) END KettenKapsel.

Implementierung IMPLEMENTATION MODULE KettenKapsel; (* Programm 2b *) FROM Storage IMPORT (* PROC *) ALLOCATE, DEALLOCATE; FROM InOut IMPORT (* PROC *) WriteCard, WriteLn; TYPE ZeigTyp = POINTER TO ZeigRec; TYPE ZeigRec = RECORD Key : CARDINAL; Prev, Next : ZeigTyp; END (* RECORD *); VAR Anker : ZeigTyp; PROCEDURE Einfuegen (Nr: CARDINAL); ... wie oben in Programm 1b ... END Einfuegen; PROCEDURE Loeschen (Nr: CARDINAL); END Loeschen; PROCEDURE ZeigKette; ... wie oben in Programm 1c ... END ZeigKette; BEGIN (* KettenKapsel *) ... Initialisierung wie oben in Programm 1b ... END KettenKapsel.

Test-Modul MODULE DoppelKette; (* Programm 2c *) (* Version mit Kapselung der Daten *) FROM KettenKapsel IMPORT (* PROC *) Einfuegen, Loeschen, ZeigKette; BEGIN (* DoppelKette *) ... Hauptprogramm wie in Programm 1c ... END DoppelKette. ZeigTyp, ZeigRec und Anker sind private Informationen der Implementierung. Sie sind anderen Modulen nicht bekannt Vorteile: Datenstrukturen vor Fehlinterpretationen geschützt, Mißbrauch ist erschwert, gekapselte Datenstruktur kann ohne Auswirkung auf andere Module geändert werden Das Prinzip der Datenkapselung wurde 1972 von David Parnas unter der Bezeichnung information hiding eingeführt.

Beispiel Warteschlange DEFINITION MODULE SchlKapsel; (* Programm 4a *) (* Demonstr. Kapselung: FIFO-Speicher fuer CARDINAL-Zahlen *) PROCEDURE Bringen (Eintrag : CARDINAL); (* wenn istVoll vorher TRUE war, keine Wirkung; sonst wird Eintrag der Schlange zugefuegt *) PROCEDURE Holen (VAR Eintrag : CARDINAL); (* wenn istLeer vorher TRUE war, keine Wirkung; sonst wird Par. Eintrag mit dem aeltesten Eintrag der Schlange besetzt, und dieser wird aus der Schlange entfernt *) PROCEDURE istLeer (): BOOLEAN; (* TRUE, genau wenn Schlange kein Element enthaelt *) PROCEDURE istVoll (): BOOLEAN; (* TRUE, genau wenn Schlange kein Element mehr aufnehmen kann *) END Schlkapsel.

Implementierung IMPLEMENTATION MODULE SchlKapsel; (* Programm 4b *) (* Demonstr. der Kapselung: FIFO-Speicher fuer CARDINAL-Zahlen Version mit Ringpuffer *) CONST MaxElemente = 100; Feldlaenge = MaxElemente+1; (* Minim. 1 Platz bleibt frei *) TYPE SchlIndTyp = [0 .. Feldlaenge-1]; VAR Schlange : ARRAY SchlIndTyp OF CARDINAL; (* die gekapselte *) AnfangVoll, AnfangLeer: SchlIndTyp; (* Datenstruktur *) PROCEDURE Nachfolger (Arg: SchlIndTyp) : SchlIndTyp; (* intern ,zyklische Nachfolgefunktion *) BEGIN (* Nachfolger *) RETURN (Arg + 1) MOD Feldlaenge END Nachfolger; PROCEDURE Bringen (Eintrag : CARDINAL); BEGIN (* Bringen *) IF NOT istVoll () THEN Schlange [AnfangLeer] := Eintrag; AnfangLeer := Nachfolger (AnfangLeer); END (* IF *); END Bringen;

Implementierung, Fortsetzung PROCEDURE Holen (VAR Eintrag : CARDINAL); BEGIN (* Holen *) IF NOT istLeer () THEN Eintrag := Schlange [AnfangVoll]; AnfangVoll := Nachfolger (AnfangVoll); END (* IF *); END Holen; PROCEDURE istLeer () : BOOLEAN; BEGIN (* istLeer *) RETURN AnfangVoll = AnfangLeer END istLeer; PROCEDURE istVoll () : BOOLEAN; BEGIN (* istVoll *) RETURN Nachfolger (AnfangLeer) = AnfangVoll END istVoll; BEGIN (* Initialisierung *) AnfangVoll := 0; AnfangLeer := 0; END SchlKapsel.

Testmodul MODULE KapselTest; (* Programm 4c *) FROM SchlKapsel IMPORT (* PROC *) Bringen, Holen, istLeer, istVoll; FROM InOut IMPORT (* PROC *) ReadCard, Write, WriteLn, WriteCard, WriteString; PROCEDURE WriteB (Value: BOOLEAN); (* Ausgabe von Wahrheitswerten *) BEGIN (* WriteB *) IF Value THEN Write ('T'); ELSE Write ('F'); END; END WriteB; VAR Wert : CARDINAL; BEGIN (* KapselTest *) WriteString ('*** Start Test-Programm f. SchlKapsel ***'); WriteLn; WriteLn; WriteString ('Gib Zahl ohne Vorzeichen,'); WriteString (' 0 fuer Ausgabe, 999 fuer Ende'); WriteLn; WriteLn;

Testmodul, Fortsetzung LOOP (* jeweils Ein- oder Ausgabe eines Wertes *) Write ('>'); ReadCard (Wert); Write (' '); IF Wert = 999 THEN EXIT (* Abbruchbedingung *) ELSIF Wert = 0 THEN (* Wert aus Schlange holen *) IF istLeer () THEN WriteString (' Schlange ist leer'); ELSE Holen (Wert); WriteCard (Wert, 4); WriteString (' istLeer = '); WriteB (istLeer ()); END (* IF istLeer () *); ELSE (* Wert in Schlange setzen *) IF istVoll () THEN WriteString (' Schlange ist voll'); Bringen (Wert); WriteString (' istVoll = '); WriteB (istVoll ()); END (* IF istVoll () *); END (* IF *); WriteLn; END (* LOOP *); WriteString ('*** Ende Test ***'); WriteLn; END KapselTest.

Abstrakte Datentypen (ADT) Ein Datentyp ist ein Schema, aus dem Variablen gebildet werden können. Ein Abstrakter Datentyp ist ein Schema zur Bildung geschützter Variablen im Sinne der Kapselung. Er besteht aus • dem Namen des Typs, dessen innere Struktur nicht sichtbar ist, und • der Menge der zulässigen Operationen auf Objekten dieses Typs. Ein ADT ist nicht ein einzelnes Objekt, sondern ein Typ, von dem es beliebig viele Variablen geben kann. Die Initialisierung erfolgt jeweils einzeln. Schnittstelle Anbindung an Dienstmodul durch Prozeduraufrufe TYPE pT; (* privater Typ *) Prozedurdeklarationen (auch Initialisierungsprozedur) Import: privater Typ Prozeduren Kunden-Modul Implementierung TYPE pT = ...; Prozedurdefinitionen interne Daten und Prozeduren (* keine Initialisierung *) END

Charakteristika von ADTs • Der Typ, auf den sich die Operationen des ADT beziehen, wird in der Schnittstelle deklariert, nicht aber definiert. Es handelt sich hierbei um einen opaken oder privaten Typ. Die Kunden-Module importieren den opaken Typ samt den Prozeduren und legen Variablen an. Die Initialisierung der Variablen bedarf einer eigenen Prozedur. Alle Operationen müssen durch das Modul ausgeführt werden, das den ADT exportiert. Die betreffenden Variablen werden als Parameter übergeben. Vorteile: Durch die Kapselung der Datenstrukturen sind Fehlinterpretationen vermindert und ist Mißbrauch erschwert. Die Datenstruktur ist ohne Auswirkungen auf andere Module änderbar. Die Zahl der Variablen, die aus einem ADT gebildet werden, bleibt offen. Nachteile: Die Datenzugriffe sind im allgemeinen etwas weniger effizient.

ADT Stack für CARDINAL Ein Stack (Keller) ist eine variable Datenstruktur zur Verwaltung von Elementen des gleichen Typs nach dem LIFO-Prinzip (last in first out). Anschaulich: lineare Liste, bei der Einfügen, Löschen und Abfrage nur an einem Ende ausgeführt werden. Definierte Operationen: • Push (Element): Einfügen eines neuen (dann obersten) Elementes, • Pop(): Entfernen des obersten Elementes, • Top(): Abfrage des obersten Elementes, • Empty(): Abfrage, ob der Stack leer ist.

Schnittstelle DEFINITION MODULE ADTStack; (* Programm 6a *) (* Demonstration eines ADTs: LIFO-Speicher fuer CARDINAL-Zahlen *) TYPE StackTyp; (* ein privater (opaker) Typ *) PROCEDURE Push (VAR Stack : StackTyp; Eintrag : CARDINAL); (* Speichern des uebergebenen Wertes als oberstes Stackelement *) PROCEDURE Pop ( VAR Stack : StackTyp; VAR istLeer : BOOLEAN ) : CARDINAL; (* Abfrage und Entfernen des obersten Stackelementes: wenn istLeer FALSE, wird Wert des obersten Stackelements geliefert und Element geloescht; sonst keine Wirkung und Wert ist 0. *) PROCEDURE Top ( VAR Stack : StackTyp; (* Abfrage des obersten Stackelementes:wenn istLeer FALSE, wird Wert des obersten Stackelementes geliefert, sonst 0. *) PROCEDURE Empty (Stack : StackTyp): BOOLEAN; (* TRUE, genau wenn der Stack leer ist *) PROCEDURE Initial (VAR Stack : StackTyp); (* Initialisierung des Stacks *) PROCEDURE Delete (VAR Stack : StackTyp); (* Loeschen des Stacks, d.h. Loeschen aller Elemente *) END ADTStack.

Implementierung IMPLEMENTATION MODULE ADTStack; (* Programm 6b *) (* Demonstration eines ADTs: LIFO-Speicher fuer CARDINAL-Zahlen *) FROM Storage IMPORT (* PROC *) ALLOCATE, DEALLOCATE; TYPE StackTyp = POINTER TO ElementTyp; ElementTyp = RECORD Wert : CARDINAL; Nachfolger : StackTyp; END (* RECORD *); PROCEDURE Push (VAR Stack : StackTyp; Eintrag : CARDINAL); VAR NeuElement : StackTyp; BEGIN (* Push *) (* Neuen Eintrag als 1. Element einfuegen *) ALLOCATE (NeuElement, SIZE (ElementTyp)); WITH NeuElement^ DO Wert := Eintrag; Nachfolger := Stack; END (* WITH *); Stack := NeuElement; END Push;

PROCEDURE Pop (VAR Stack : StackTyp; VAR istLeer : BOOLEAN ) : CARDINAL; VAR Eintrag : CARDINAL; Hilf : StackTyp; BEGIN (* Pop *) (* Erstes Element lesen und loeschen *) istLeer := Empty(Stack); IF istLeer THEN Eintrag := 0; ELSE Eintrag := Stack^.Wert; Hilf := Stack; Stack := Stack^.Nachfolger; DEALLOCATE (Hilf, SIZE (ElementTyp)); END; RETURN Eintrag END Pop; PROCEDURE Top (VAR Stack : StackTyp; VAR Eintrag : CARDINAL; BEGIN (* Top *) (* Erstes Element lesen *) ELSE Eintrag := Stack^.Wert; END Top;

Implementierung, 3 PROCEDURE Empty (Stack : StackTyp): BOOLEAN; BEGIN (* Empty *) RETURN (Stack = NIL) END Empty; PROCEDURE Initial (VAR Stack : StackTyp); BEGIN (* Initial *) Stack := NIL; END Initial; PROCEDURE Delete (VAR Stack : StackTyp); VAR Hilf : StackTyp; BEGIN (* Delete *) WHILE Stack # NIL DO Hilf := Stack; Stack := Stack^.Nachfolger; DEALLOCATE (Hilf, SIZE (ElementTyp)); END (* WHILE *); END Delete; END ADTStack.