31.01.2013 Aufrufe

Einführung und erste Hilfe zur Programmiersprache Turbo - Pascal

Einführung und erste Hilfe zur Programmiersprache Turbo - Pascal

Einführung und erste Hilfe zur Programmiersprache Turbo - Pascal

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

PASCAL-READER VERSION 2.3<br />

25 Seiten Datum :<br />

<strong>Einführung</strong> <strong>und</strong> <strong>erste</strong> <strong>Hilfe</strong><br />

<strong>zur</strong> <strong>Programmiersprache</strong><br />

<strong>Turbo</strong> - <strong>Pascal</strong><br />

Inhaltsverzeichnis :<br />

1 ) Entstehung von <strong>Pascal</strong><br />

2 ) Übersicht <strong>Programmiersprache</strong>n<br />

3 ) Bedienungshinweise zu <strong>Turbo</strong>-<strong>Pascal</strong> 6.0 / 7.0<br />

4 ) Stufen der Programmentwicklung<br />

5 ) Sinnbilder für Struktogramme <strong>und</strong> PAP<br />

6 ) Aufbau eines <strong>Pascal</strong>-Programms <strong>und</strong> Datentypen<br />

7 ) wichtige <strong>Pascal</strong>-Befehle <strong>und</strong> Kontrollstrukturen<br />

8 ) Standard- Ein- Ausgabe- Funktionen<br />

9 ) Beispielentwurf für ein lineares Programm<br />

10 ) Regeln für die Dokumentation von Programmen<br />

11 ) Übungsaufgaben für lineare Programme<br />

12 ) Unterprogramme / Prozeduren<br />

13 ) Unterprogramme / Funktionen<br />

14 ) Unterprogrammsammlungen / Units<br />

15 ) Wiederholungsstrukturen<br />

16 ) Übungsaufgaben <strong>zur</strong> Schleifenprogrammierung<br />

17 ) Programmierung über die parallele Schnittstelle<br />

18 ) Verzweigungen<br />

19 ) Übungsaufgaben zu Verzweigungen<br />

20 ) Programm mit Loops <strong>und</strong> Verzweigungen Beispiellösung / Teil 1<br />

21 ) Programm mit Loops <strong>und</strong> Verzweigungen Beispiellösung / Teil 2<br />

22 ) Zusammengesetzte Datentypen : Array / Felder<br />

23 ) Records / Verb<strong>und</strong><br />

24 ) Mengen ( SET )<br />

25 ) Eigene Datentypen ( TYPE )<br />

Literatur zum Einstieg :<br />

1] Gregor Kuhlmann : <strong>Programmiersprache</strong> <strong>Turbo</strong>-<strong>Pascal</strong>; Eine strukturierte <strong>Einführung</strong>,<br />

rororo Computer Nr. 8148 ; Preis ca. 13.- €<br />

2] Peter Niehoff : Informatik - Datenverarbeitung . mit <strong>Pascal</strong>, Verlag Handwerk <strong>und</strong> Technik,<br />

Hamburg; Preis ca. 13.- €<br />

3] Reinhard Schuberth : Technologie , Eine <strong>Einführung</strong> für technische Ausbildungsrichtungen – mit<br />

<strong>Pascal</strong> Verlag Handwerk & Technik 2711 , Hamburg 1993, Preis ca. 13.- €<br />

4] D. Häberle : <strong>Pascal</strong> für gewerbliche Schulen; 2. Auflage 1994, Verlag : Europa-Lehrmittel,<br />

Düsseldorf, Preis ca. 16.- €<br />

5] Das erweiterte Online-Exemplar des Readers finden Sie unter : http://www.muenster.de/~m_frost<br />

13.07.02<br />

0-Inhalt


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

GESCHICHTE<br />

<strong>Programmiersprache</strong> <strong>Turbo</strong>-<strong>Pascal</strong> 1)<br />

1/25 Datum :<br />

Blaise <strong>Pascal</strong>, der französische Religionsphilosoph, Mathematiker <strong>und</strong> Physiker wurde am 19. Juni<br />

1623 in Clermont-Ferrand als Sohn eines Steuerfachmanns geboren. Er starb 1662. Um seinem Vater<br />

bei Steuerberechnungen zu helfen, konstruierte er die <strong>erste</strong> Rechenmaschine , die <strong>Pascal</strong>ine,<br />

nach deren Prinzip in Zukunft alle weiteren gebaut wurden.<br />

Die <strong>Programmiersprache</strong> hat ihren Ursprung in der Sprache <strong>Pascal</strong>, die 1972<br />

von Niclas Wirth als "Universitätssprache" entworfen wurde, also als eine <strong>Programmiersprache</strong>,<br />

die den Studenten das Erlernen des Programmierens erleichtern<br />

sollte.<br />

Niklaus Wirth wurde im Februar 1934 in Winterthur, Schweiz geboren. Nach<br />

seiner Prüfung als Elektronik-Ingenieur am Federal Institute of Technology<br />

(ETH) in Zürich ( 1959 ) arbeitete er zunächst an der Laval University in Canada<br />

( 1960 ) <strong>und</strong> an der University of California in Berkeley ( 1963 ). Bevor er<br />

wieder <strong>zur</strong>ück an die Universität von Zürich <strong>zur</strong>ückkehrte war er Assistenz-<br />

Professor für Computerwissenschaften an der Stanford University (1963 -<br />

1967) wo er <strong>Pascal</strong> entwickelte.<br />

Der Name ist akademisch nach Blaise <strong>Pascal</strong> ausgewählt worden, dem bekannten Mathematiker <strong>und</strong><br />

Philosophen. Zu Ehren dieses bedeutenden Genies <strong>und</strong> einem der Vorväter des Computers hat<br />

Nikolaus Wirth, Professor für Informatik an der ETH Zürich, seine zu Beginn der 70er Jahre aus<br />

"Algol 60" entwickelte <strong>Programmiersprache</strong> <strong>zur</strong> Unterstützung der strukturierten Programmierung<br />

"<strong>Pascal</strong>" genannt. Diese Bezeichnung wurde dann von Borland später übernommen.<br />

1 ] Made in Borland® Copyright© 1994-2002 Borland Software Corporation<br />

11.07.02<br />

1-geschichte


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

PROGRAMMIERSPRACHEN<br />

2/25 Datum :<br />

Übersicht <strong>Programmiersprache</strong>n<br />

Um einen Computer zu programmieren, muss ein gemeinsamer Kode gef<strong>und</strong>en werden, auf dessen Basis man<br />

mit der Maschine kommuniziert Je mehr man sich der Sprache des Rechners nähert, um so schwieriger <strong>und</strong><br />

umständlicher wird die Kommunikation. Man unterscheidet heute 5 verschiedene Generationen:<br />

1) Programme in MASCHINENSPRACHE bestehen aus Maschinenbefehlen, die als Folge von Nullen <strong>und</strong><br />

Einsen im Computer dargestellt werden. Die umständliche Eingabe Tausender von einzelnen Bits wird häufig<br />

abgekürzt durch die Eingabe der äquivalenten Hexadezimalzahlen z.B. 63 B1 0C statt 0110 0011 1011<br />

0001 0000 1100 usw. Bei Fehleingaben wird die Fehlersuche sehr zeitaufwendig <strong>und</strong> schwierig. Maschinensprachen<br />

gelten immer nur für Mikroprozessoren des gleichen Typs.<br />

2) <strong>Programmiersprache</strong>n, bei denen die Bitkombinationen der Maschinenbefehle durch ein leicht zu merkendes<br />

Symbolwort ( Mnemonics ) ausgedrückt werden, nennt man ASSEMBLER. Auch solche Assemblersprachen<br />

gelten immer nur für einen einzigen Mikroprozessortyp.<br />

3) Höhere oder PROBLEMORIENTIERTE PROGRAMMIERSPRACHEN erlauben es die Anweisungen für den<br />

Computer so zu beschreiben, dass man keine Maschinenbefehle verwenden muss. Man ist dadurch unabhängig<br />

vom Mikroprozessortyp <strong>und</strong> die Programme können auf jedem Rechner ablaufen.<br />

4) Sprachen der 4. Generation nennt man DESKRIPTIVE PROGRAMMIERSPRACHEN. Hier gibt der Anwender<br />

nur noch den Verarbeitungsbefehl ein, ohne dass er den Lösungsweg in Form eines Algorithmus beschreiben<br />

muss. Diese Sprachen sind immer auf ein bestimmtes Anwendungsgebiet zugeschnitten; z.B.<br />

SQL für relationale Datenbanken oder ADF, CSP, DMS (IBM) , Natural ,Oracle usw.<br />

5) Im Bereich der Künstlichen Intelligenz findet man <strong>Programmiersprache</strong>n <strong>zur</strong> Erstellung von Expertensystemen.<br />

Hierunter fallen OBJEKTORIENTIERTE PROGRAMMIERSPRACHEN wie z.B. Java, Delphi, C++<br />

oder Visual Basic. Auch funktionale Sprachen wie LISP, logische Sprachen wie Prolog <strong>und</strong> alle neuen Makro-Sprachen<br />

zählt man <strong>zur</strong> 5. Generation. Hier programmiert man keine Befehle, sondern man gibt an, was<br />

mit Objekten passieren soll, wenn bestimmte Ereignisse ( events ) im Programmablauf aktiviert werden. Die<br />

Objekte können Dialogelemente sein, Befehlsschaltflächen, Kontrollkästen, Bildlaufleisten usw.<br />

Maschinensprache Assembler Problemorientierte Sprachen<br />

Dualkode Hexadezimalkode Mnemonics z.B. BASIC z.B. PASCAL<br />

0011 1110<br />

0000 0011<br />

3E<br />

03<br />

MVI A, 03h<br />

oder LD A, 03h<br />

Assembler<br />

10 LET A = 3 A := 3;<br />

Objektkode<br />

Interpreter<br />

Compiler<br />

Quellkode<br />

( Übersetzungsprogramme )<br />

Einzelne Programmieranweisungen in einer höheren <strong>Programmiersprache</strong> können eine Menge von Maschinenbefehlen<br />

auslösen, die der Programmierer im einzelnen gar nicht kennt. Welche Befehle jeweils ausgelöst<br />

werden, teilt ein Übersetzungsprogramm dem Computer mit. Vor dem Programmieren ist daher unbedingt ein<br />

Übersetzungsprogramm in den RAM zu laden! Dabei unterscheidet man drei Gr<strong>und</strong>versionen :<br />

1) ASSEMBLER Leider hat sich für das Übersetzungsprogramm von Assemblersprache in Maschinensprache<br />

ebenfalls das Fachwort Assembler eingebürgert.<br />

2) INTERPRETER Dies sind Übersetzer, die nach dem Start eines Quellprogramms jeweils eine einzige Anweisung<br />

in Maschinenbefehle übersetzen <strong>und</strong> sofort ausführen. Erst dann wird die nächste<br />

Anweisung bearbeitet. Vorteil : Man kann ein Programm bis zu Fehl<strong>erste</strong>lle im Quelltext<br />

testen. Nachteil: Da immer nur eine Zeile übersetzt wird, liegt das Programm nie komplett<br />

übersetzt vor. Man muss bei jedem Start den Quelltext neu übersetzen, was sehr lange<br />

dauert. Der Interpreter muss ständig im Speicher verbleiben.<br />

3) COMPILER Sie übersetzen ein komplettes Quelltextprogramm auf einmal in Maschinensprache <strong>und</strong><br />

legen das Ergebnis entweder auf Diskette oder im RAM als Maschinenspracheprogramm<br />

ab. Vorteil : Sie brauchen das Programm nur ein einziges mal zu übersetzen; anschließend<br />

läuft es in Maschinensprache sehr schnell ab. Nachteil : Ein Maschinenspracheprogramm<br />

ist nicht mehr ohne weiteres zu verändern. Außerdem - <strong>und</strong> das ist das Problem - übersetzt<br />

ein Compiler Ihr Programm nur dann, wenn es fertig durchdacht ist <strong>und</strong> fehlerfrei<br />

vorliegt. Testen von Programmteilen ist nur bedingt möglich.<br />

11.07.02<br />

2-sprachen


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

<strong>Turbo</strong>-<strong>Pascal</strong> starten <strong>und</strong> beenden<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

BEDIENUNGSHINWEISE<br />

3/25 Datum :<br />

Sie können den Compiler ganz einfach starten, indem Sie von der Betriebssystemebene aus im entsprechenden<br />

Pfad die Startdatei TURBO.EXE aufrufen. Nach kurzer Zeit meldet sich <strong>Turbo</strong>-<strong>Pascal</strong> mit dem Einschaltbild <strong>und</strong><br />

wartet auf Ihre weiteren Eingaben. Wird während des Ladevorgangs der Fehler gemeldet: „cannot create swap<br />

file“, so kann <strong>Pascal</strong> seine Auslagerungsdatei ( swap file ) nicht öffnen. Das liegt daran, dass Sie den Schreibschutz<br />

an Ihrer Diskette aktiviert haben oder im aktuellen Pfad keine Schreibrechte im Netzwerk besitzen.<br />

Beenden Sie <strong>Turbo</strong>-<strong>Pascal</strong> nie (!) , indem Sie einfach den Rechner ausschalten oder einen Reset auslösen, denn<br />

<strong>Pascal</strong> schließt dann die temporären Dateien nicht ordnungsgemäß. Auf Ihrer Diskette häufen sich dann Dateien,<br />

die etwa folgendermaßen aussehen : tp0dde7f.$$$ oder td2ed929.$$$. Verlassen Sie den Compiler immer nur<br />

über das Menue FILE mit dem Menuepunkt EXIT.<br />

Programme laden <strong>und</strong> speichern<br />

Über das Pull Down Menue FILE können Sie entweder alte Programme bearbeiten ( OPEN ) oder völlig neue<br />

Programme entwerfen ( NEW ). Dazu müssen Sie aber angeben, in welchem Pfad auf Ihrer Diskette oder der<br />

Festplatte das Programm gesucht werden soll. Stellen Sie dies im Menuepunkt CHANGE DIR vorher ein.<br />

Zum Speichern Ihres Quelltextes bietet das Pull Down Menue zwei Varianten. Mit SAVE wird der Quelltext unter<br />

dem Namen gespeichert, der im Rahmen des blauen Bildschirms oben aktuell eingeblendet ist; das ist meist<br />

noname00.pas. Mit dem anderen Menuepunkt SAVE AS .. können Sie vor dem Speichern den Programmnamen<br />

ändern. Der Pfad in dem der Quellkode abgelegt wird entspricht dem, unter welchem auch gelesen wurde.<br />

Programme compilieren <strong>und</strong> starten<br />

Ihre fertigen Programme übersetzen Sie in Maschinensprache mit dem Kommando COMPILE im Menue<br />

COMPILE. In Abhängigkeit von dem Schalter DESTINATION ( Zielort ) wird der Objektkode entweder im RAM<br />

abgelegt ( memory ) oder auf dem Datenträger ( disk ) gespeichert. Wo auf der Diskette oder der Festplatte Ihr<br />

Programm landet, hängt davon ab, welche Zielpfade Sie vorher eingestellt haben. Ihrer Wahl treffen Sie unter<br />

dem Menuepunkt OPTIONS <strong>und</strong> DIRECTORIES. Dort werden die Pfade für die EXE-Dateien vorgegeben. Sie<br />

können natürlich Ihr Programm nur dann erfolgreich compilieren lassen, wenn der Quelltext völlig fehlerfrei vorliegt.<br />

Treten Fehler auf, so stellt <strong>Pascal</strong> den Cursor an die Stelle des Quelltextes, wo die Übersetzung aufgr<strong>und</strong><br />

eines Syntaxfehlers abgebrochen hat.<br />

Das Kommando RUN startet das Programm für den Normalbetrieb, wobei das Startkommando bereits den Compileraufruf<br />

enthält. Sie sollten ein Programm aber nie starten, bevor Sie es nicht abgesichert haben. Hängt sich<br />

Ihr Programm aufgr<strong>und</strong> eines Logikfehlers auf, so bleibt nur der Neustart des Rechners <strong>und</strong> Ihr Programm im<br />

RAM des PC ist unwiderruflich verloren. Sie müssen dann alles noch einmal neu schreiben.<br />

Programme eingeben <strong>und</strong> bearbeiten<br />

Diesen Vorgang nennt man Editieren. Demzufolge erreichen Sie die wichtigsten Bearbeitungsfunktionen auch<br />

über den Menuepunkt EDIT. Sie können zuvor markierte Textteile in eine Ablage ( CLIPBOARD ) legen ( CUT ),<br />

sie hinein kopieren ( COPY ), sie wieder aus der Ablage entnehmen ( PASTE ) oder sie in der Ablage löschen<br />

( DELETE ). Solche Blockoperationen erleichtern die tägliche Arbeit beim Eintippen von Quelltexten ungemein.<br />

Wollen Sie einen Buchstaben oder mehrere überschreiben <strong>und</strong> nicht einfügen, so müssen Sie mit der Taste INS<br />

( Einfügen ) zwischen dem Überschreibmodus <strong>und</strong> dem Einfügemodus wechseln. Den eingestellten Modus ( die<br />

Betriebsart ) erkennen Sie an der Form des Cursors. Können Sie keine Leerzeilen mit RETURN mehr einfügen,<br />

so sind Sie mit Sicherheit im Überschreibmodus <strong>und</strong> müssen zum Einfügemodus wechseln.<br />

-----------------------------------------------------------------------------------------<br />

Beachten Sie bitte :<br />

1) Stellen Sie zunächst alle Quell- <strong>und</strong> Zielpfade exakt ein; Sie finden sonst Ihre Programme schlecht wieder !<br />

2) Speichern Sie Ihr Programm ca. alle 10 min als Sicherungskopie ab; es könnte der Strom ausfallen !<br />

3) Sichern Sie Ihre Programme auch auf Ihrer Diskette. Auf der Festplatte C: oder D: sind die Daten nicht sicher.<br />

4) Speichern Sie Ihr Programm vor dem <strong>erste</strong>n Probelauf ab. Es könnte sich unwiderruflich „aufhängen“.<br />

11.07.02<br />

3-bedienung


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

PROGRAMMENTWURF<br />

Stufen der Programmentwicklung<br />

4/25 Datum :<br />

Der Weg von der Problemerkennung bis <strong>zur</strong> Lösung mittels Computer ist unter Umständen sehr lang<br />

<strong>und</strong> beschwerlich. Dabei liegen die Hauptprobleme weniger in der Programmierung als vielmehr darin,<br />

dass der Anwender das Problem <strong>und</strong> die Problemlösung nicht genau genug beschreiben kann.<br />

Ungefähre Vorstellungen führen gr<strong>und</strong>sätzlich dazu, dass man sich verzettelt. Es hilft also nichts,<br />

wenn man sofort beginnt, mit seinen „Wurstfingern“ wild auf der Tastatur zu klappern bevor man nicht<br />

nachgedacht hat. Da der <strong>Pascal</strong>-Compiler unerbittlich ist, wenn Sie nicht planen, bin ich es auch <strong>und</strong><br />

helfe nur, wenn die Vorarbeiten zum Programm sauber <strong>und</strong> eindeutig sind.<br />

PROGRAMMENTWICKLUNG<br />

1) Lastenheft / Pflichtenheft<br />

- die Aufgabenstellung wird in einem ganzen Satz schriftlich u. grammatisch exakt beschrieben.<br />

- einzuhaltende Bedingungen werden geklärt, gewünschte Ergebnisse werden konkret definiert.<br />

2) Problemanalyse<br />

- welche Daten werden eingegeben, welche werden ausgegeben ?<br />

- welche Variablen <strong>und</strong> welche Konstanten liegen vor ? Wie sollen sie heißen ?<br />

- welcher Art sind diese Variablen <strong>und</strong> in welcher Form sollen sie verwendet werden ?<br />

- welcher Algorithmus kann das Problem lösen ? ( Oft hilft eine Skizze weiter ! )<br />

3) Programmstrukturierung ( d.h. graphische Darstellung der Vorgehensweise )<br />

- mit <strong>Hilfe</strong> eines Programmablaufplans PAP ( DIN 66001 )<br />

- mit <strong>Hilfe</strong> eines Struktogramms nach den Herren Nassi <strong>und</strong> Shneiderman ( DIN 66261 )<br />

4) Codierung<br />

- Umsetzen der Algorithmen in eine Folge von Anweisungen ( Quelltext schreiben )<br />

- Einstellen der Pfade <strong>zur</strong> definierten Abspeicherung<br />

- Abspeichern des Programmentwurfs als Sicherungskopie<br />

5) Programmtest<br />

- Übersetzen des Quelltextes in den Maschinenkode ( Objektkode )<br />

- Prüfung auf Codierfehler / Syntaxfehler<br />

- Prüfung auf logische Fehler durch Testläufe<br />

- Testläufe, um die Grenzen des Programms zu erkennen<br />

- Abspeichern des getesteten, fertigen Programms<br />

6) Programmdokumentation<br />

- graphisches Einrücken der Anweisungen mit richtiger Schreibweise<br />

- Angaben zu Ort, Zeit, Version, Autor usw. im Quelltext<br />

- kurzer Kommentar mit Programmbeschreibung <strong>und</strong> Leistungsgrenzen<br />

- Kommentare <strong>zur</strong> Erläuterung von Variablen <strong>und</strong> Konstanten<br />

- Abspeichern des fertigen, kommentierten Programms<br />

Bei umfangreichen <strong>und</strong> komplexen Problemen zerlegt man die Gesamtaufgabe stufenweise in immer<br />

kleinere Teilprobleme, die dann einzeln nach der genannten Vorgehensweise bearbeitet werden<br />

( Top Down Entwurf ). Solche in sich abgeschlossene <strong>und</strong> fertige Programmteile nennt man Module<br />

<strong>und</strong> fügt sie später durch Unterprogrammtechnik zusammen. Größere Unterprogrammsammlungen<br />

nennt man bei <strong>Turbo</strong>-<strong>Pascal</strong> UNITS.<br />

11.07.02<br />

4-prgentwurf


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

SINNBILDER FÜR STRUKTOGRAMME UND PAP’S<br />

Sinnbilder für Programmablaufpläne <strong>und</strong> Struktogramme :<br />

5/25 Datum :<br />

Die Programmdokumentation ist eine notwendige Voraussetzung <strong>zur</strong> Entwicklung <strong>und</strong> Wartung eines<br />

Programmes. Vor allem müssen die Programme grafisch dargestellt werden, weil nur so ein Überblick<br />

möglich ist. Speziell dafür verwendet man genormte Sinnbilder nach DIN 66261( Struktogramme nach<br />

Nassi <strong>und</strong> Shneiderman ) oder auch DIN 66001 ( Programmablaufplan ) .<br />

Sinnbilder für Programmablaufpläne<br />

Sinnbild Benennung<br />

Operation allgemein<br />

Unterprogrammaufruf<br />

Ein- bzw Ausgabe<br />

Verzweigung<br />

Übergangsstelle<br />

Grenzstelle<br />

Ablauflinien<br />

Schleifenbegrenzung<br />

für zählergesteuerte<br />

Wiederholungen<br />

Elem ente von Struktogram m en<br />

Sinnbild B enennung<br />

A nw eisung 1<br />

Anw eisung 2<br />

A nw eisung 3<br />

A nw eisung 1<br />

A nw eisung 1<br />

A nw eisung 1<br />

A nw eisung 2<br />

w iederhole bis ..<br />

w iederhole solange<br />

A nw eisung 1<br />

A nw eisung 2<br />

Bedingung<br />

nein ja<br />

Anw eisung<br />

Fall<br />

Bedingung<br />

1 2 3 4..<br />

Folgeblock<br />

fü r W e rtzuw e isungen,<br />

Rechenoperationen<br />

<strong>und</strong> B ildschirm b e fe h le<br />

( n icht genorm t )<br />

( n icht genorm t )<br />

W iederholungsstruktur<br />

m it Endebedingung<br />

W iederholungsstruktur<br />

m it A nfangsbedingung<br />

a) einseitig<br />

b) zw eise itig<br />

m ehrfach<br />

A ufruf U -Prg a) Funktion<br />

b) Prozedur<br />

Bei umfangreichen Programmen mit vielen Programmverzweigungen erweist sich das Struktogramm<br />

als vorteilhaft. Es ist übersichtlicher. Das liegt auch daran, dass für Programmablaufpläne keine Symbolik<br />

genormt ist, mit der man eine Mehrfachverzweigung skizzieren kann.<br />

Nicht nur für das Hauptprogramm müssen Ablaufpläne gezeichnet werden, sondern für jedes<br />

Unterprogramm zusätzlich. Das heißt, ein Programm mit z.B. 5 Unterprogrammen basiert auf<br />

der Gr<strong>und</strong>lage von 6 Ablaufplänen.<br />

11.07.02<br />

5-strukto


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

AUFBAU EINES PROGRAMMS<br />

6/25 Datum :<br />

Aufbau eines Programms<br />

Jedes <strong>Pascal</strong>-Programm muss nach bestimmten Regeln ( Syntax ) aufgebaut werden. Es besteht<br />

immer aus drei Teilen :<br />

1) - dem Programmkopf<br />

2) - dem Vereinbarungsteil ( Deklarationsteil )<br />

3) - dem Anweisungsteil ( Hauptprogramm )<br />

Programmkopf :<br />

Er wird immer eingeleitet mit dem Schlüsselwort PROGRAM. Dahinter folgt nach einem Leerzeichen<br />

( blank ) der Name des Programms. Er darf aus bis zu 127 Zeichen bestehen, mit Ausnahme von<br />

Leerzeichen. In manchen <strong>Pascal</strong> - Dialekten folgt nun die Angabe der benötigten Standard-Ein- <strong>und</strong><br />

Ausgabeperipherie ( Tastatur <strong>und</strong> Bildschirm ). Allgemein gilt also :<br />

PROGRAM Name (input , output) ;<br />

Vereinbarungsteil :<br />

Damit alle benötigten Speicherplätze vom Programm richtig adressiert <strong>und</strong> wiedergef<strong>und</strong>en werden,<br />

müssen sie eingerichtet ( deklariert ) werden. In <strong>Turbo</strong>-<strong>Pascal</strong> vereinbart man :<br />

- Programmbibliotheken USES - Variable VAR<br />

- Konstanten CONST - Funktionen FUNCTION<br />

- Unterprogramme PROCEDURE - eigene Datentypen TYPE<br />

- Sprungadressen LABEL<br />

Damit der Rechner auch weiß, wie groß der vorzusehende Speicherplatz sein muss, wird hinter den<br />

deklarierten Speicherplätzen <strong>und</strong> einem Doppelpunkt der sogenannte Datentyp angegeben. Hier zunächst<br />

die einfachen Datentypen von <strong>Turbo</strong> - <strong>Pascal</strong> :<br />

1) numerische Datentypen<br />

BYTE kleine positive ganze Zahl 0 .. 255 ( 1 Byte )<br />

SHORTINT kurze ganze Zahl -128 .. +127 ( 1 Byte )<br />

WORD positive ganze Zahl 0 .. 65535 ( 2 Byte )<br />

INTEGER ganze Zahl -32768 .. +32767 ( 2 Byte )<br />

LONGINT große ganze Zahl -2147483648 .. +2147486647 ( 4 Byte )<br />

REAL reelwertige Zahl -2,9 • 10 39 .. +1,7 • 10 38 ( 6 Byte )<br />

Die reellen Zahlentypen SINGLE, DOUBLE, EXTENDED <strong>und</strong> COMP können mit dem Compilerbefehl<br />

{ $N+ } eingeschaltet werden, wenn ein mathematischer Coprozessor vorhanden ist.<br />

Diese Compilerdirektive { $N+ } steht dann unmittelbar vor dem einleitenden Schlüsselwort<br />

PROGRAM.<br />

2) ein einzelnes Zeichen CHAR alle 256 Zeichen des ASCII - Zeichensatzes ( 1 Byte )<br />

3) Wahrheitswert BOOLEAN für zwei Wahrheitswerte : true / false ( 1 Byte )<br />

Aus diesen einfachen Datentypen lassen sich dann, zum Abspeichern von Namen beispielsweise,<br />

auch größere Datentypen ( strukturierte Datentypen ) zusammensetzen.<br />

a) STRING[n] Zeichenkette mit n Daten vom Datentyp CHAR<br />

ARRAY[n.. m] Folge von n bis m Elementen mit jeweils gleichem Datentyp einfacher Art<br />

RECORD Verb<strong>und</strong> von Datenfeldern verschiedener Datentypen<br />

FILE nichttypisierte Datei, die unstrukturiert ist<br />

b) SET of Untermenge eines Gr<strong>und</strong>mengentyps der einfachen Datentypen<br />

Anweisungsteil :<br />

Hier folgen nun die eigentlichen <strong>Pascal</strong>-Anweisungen <strong>zur</strong> Eingabe, Verarbeitung <strong>und</strong> Ausgabe. Die<br />

Anweisungen werden mit BEGIN <strong>und</strong> END. ( mit Punkt ! ) umklammert.<br />

11.07.02<br />

6-prgaufbau


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

STANDARD-PASCAL-BEFEHLE<br />

7/25 Datum :<br />

<strong>Pascal</strong> - Schlüsselwörter<br />

Programmkopf<br />

PROGRAM < .. >; Kopfzeile mit Namen des Programms<br />

USES < .. >; Einbinden von externen Programmunits z.B. CRT, DOS;<br />

[ CRT = cathode ray tube ( Elektronenstrahlröhre ) ]<br />

Vereinbarungsteil CONST ... Konstantenvereinbarung<br />

( Deklarationsteil ) VAR ... Variablenvereinbarung<br />

LABEL ... Sprungadressen ( möglichst nie verwenden !!! )<br />

PROCEDURE ... Unterprogramme mit Namen <strong>und</strong> evtl. Parameterliste<br />

FUNCTION ... Subroutinen mit Ergebnislieferung an eine Variable<br />

TYPE ... Vereinbarung eigener Datentypen z.B. vom Typ Monat<br />

Anweisungsteil<br />

Kontrollstrukturen BEGIN ... END; Anweisungsklammern. Das letzte END schließt mit einem "•"<br />

das Hauptprogramm ab.<br />

IF .. THEN einseitige bedingte Anweisung<br />

IF .. THEN .. ELSE zweiseitige bedingte Anweisung<br />

CASE .. OF .. ELSE mehrseitige bedingte Anweisung<br />

REPEAT .. UNTIL .. Schleife mit Austrittsbedingung ( post check loop )<br />

WHILE .. DO .. Schleife mit Eintrittsbedingung ( pre check loop )<br />

FOR .. TO .. DO .. zählergesteuerte Schleife aufwärts<br />

FOR..DOWNTO.. DO zählergesteuerte Schleife abwärts<br />

INLINE(Maschinencode) Einbinden einzelner Maschinensprachebefehle<br />

Standardprozeduren Write ( .. ); Ausgabeanweisung ohne Zeilenvorschub<br />

WriteLn ( .. ); Ausgabeanweisung mit Zeilenvorschub <strong>und</strong> "Wagenrücklauf"<br />

Read( n ); Eingabe mit Return<br />

ReadLn( n ); Eingabe mit Return <strong>und</strong> anschließendem Zeilenvorschub<br />

Nur in Verbindung n := ReadKey; Eingabe nur eines einzigen ASCII-Zeichens ohne Return<br />

mit der Unit CRT ! ClrScr; Bildschirm löschen<br />

GotoXY(x,y); Cursor an die Bildschirmposition x,y positionieren<br />

TextColor( n ); Textfarbe verändern<br />

ClrEol; löscht den Rest der Zeile ab der Cursorposition<br />

Standardfunktionen y := Sqr ( n ); Quadratfunktion<br />

y := Sqrt ( n ); Wurzelfunktion ( square root )<br />

y := Exp( n ); Exponentialfunktion <strong>zur</strong> Basis e ( e = 2,718281.. )<br />

y := Sin( n ); Sinusfunktion ( Ergebnisse liegen im Bogenmaß vor ! )<br />

y := Cos( n ); Cosinusfunktion .. ebenfalls im Bogenmaß<br />

y := ArcTan( n ); Umkehrfunktion des Tangens ( n in rad ! )<br />

y := Trunc( n ); Nachkommastellen abschneiden<br />

y := Ro<strong>und</strong>( n ); Wert r<strong>und</strong>en<br />

y := Abs( n ); Absolutbetrag ( Vorzeichen spielen keine Rolle mehr )<br />

y := Ln ( n ); Logarithmus naturalis ( Basis = e )<br />

y := Succ ( n ); logischer Nachfolger wird ermittelt ( nur für Ordinalzahlen )<br />

y := Pred ( n ); logischer Vorgänger<br />

y := UpCase ( n ); Buchstaben in Großbuchstaben umwandeln<br />

y := Random( n ); ergibt eine Zufallszahl zwischen 0 <strong>und</strong> der genannten Grenze n<br />

Operatoren DIV ( n ); Division ohne Rest<br />

MOD ( n ); Modulodivision ( Rest bei ganzzahliger Division )<br />

SHL; SHR Binärzahlen im Register links/rechts schieben ( shift left/right )<br />

AND, OR, NOT logische Gr<strong>und</strong>operatoren<br />

XOR logische Exclusiv-Oder Verknüpfung<br />

Standardvariable Port [ Adresse ] := n; Ein Byte n über einen Schnittstellenport ausgeben<br />

X := Port [ Adresse ]; Ein Byte über eine Schnittstelle in eine Variable X einlesen<br />

11.07.02<br />

7-befehle


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

STANDARD-EIN-, AUSGABE- FUNKTIONEN<br />

8/25 Datum :<br />

<strong>Turbo</strong>-<strong>Pascal</strong> hat bereits eine Reihe von Prozeduren ( <strong>und</strong> Funktionen ) vordefiniert. Sie sind in der Unit<br />

SYSTEM abgelegt <strong>und</strong> gehören zum Standard-Sprachumfang. Mit anderen Worten : Diese Unterprogramme<br />

stehen Ihnen in jedem Programm standardmäßig <strong>zur</strong> Verfügung <strong>und</strong> können sofort eingesetzt werden. Die wichtigsten<br />

sind die Ein- <strong>und</strong> Ausgabebefehle :<br />

Eingabe Ausgabe<br />

Read ReadLn Write WriteLn<br />

Daten werden<br />

über die Tastatur<br />

eingelesen <strong>und</strong> in<br />

eine oder mehrere<br />

Variablen geschrieben.<br />

Daten werden über die Tastatur<br />

eingelesen <strong>und</strong> in eine oder mehrere<br />

Variablen geschrieben. Anschließend<br />

erfolgt ein "Wagenrücklauf"<br />

<strong>und</strong> ein "Zeilenvorschub"<br />

Daten werden an<br />

der aktuellen Cursorpositionunmittelbar<br />

auf den Bildschirm<br />

geschrieben.<br />

Daten werden an der Cursorposition<br />

unmittelbar auf den Bildschirm<br />

geschrieben. Anschließend<br />

erfolgt ein "Wagenrücklauf"<br />

<strong>und</strong> ein "Zeilenvorschub"<br />

Die Ausgabeanweisung<br />

Das Schlüsselwort <strong>zur</strong> Ausgabe von Daten auf den Bildschirm lautet zunächst Write oder WriteLn. Dahinter<br />

wird in r<strong>und</strong>en Klammern angegeben, was ausgegeben werden soll. Und hier unterscheidet man gr<strong>und</strong>sätzlich<br />

drei Möglichkeiten :<br />

Ausgabe des Inhalts von<br />

Ausgabe von Textkonstanten<br />

Ausgabe zum Drucker<br />

Variablen oder Konstanten<br />

WriteLn ( ' Text ' ); WriteLn ( Variable ); WriteLn ( Lst, ' Text ' );<br />

Achten Sie darauf, dass Sie Texte zwischen Hochkommata setzen müssen, um sie von den Namen der deklarierten<br />

Variablen <strong>und</strong> Konstanten abzugrenzen. Jeder Befehl schließt übrigens am Ende der Zeile mit einem<br />

Semikolon ab. Wenn Sie in einer Anweisung mehrere Elemente gleichzeitig ausgeben wollen, so müssen Sie<br />

die einzelnen Komponenten in der Ausgabeanweisung durch Kommata trennen. Im folgenden Beispiel wird der<br />

Text "Die Entfernung beträgt :", der Inhalt der Variablen Länge <strong>und</strong> der Text "km" zusammen hintereinander<br />

ausgegeben. Beispiel : WriteLn ( ' Die Entfernung beträgt : ' , Laenge , ' km ' );<br />

Ausgabeformatierung<br />

Damit Gleitkommazahlen ( Realzahlen ) am Bildschirm nicht mit 10 Stellen hinter dem Komma <strong>und</strong> mit Exponent<br />

<strong>zur</strong> Basis 10 ausgegeben werden ( das ist die wissenschaftliche Schreibweise ), wird die Ausgabeanweisung<br />

durch Parameter ergänzt, die eine Fließkomma-Notation ermöglichen. Das heißt, Sie müssen hinter dem<br />

Variablennamen, jeweils durch Doppelpunkte getrennt, die Gesamtzahl aller gewünschten Stellen - inclusive<br />

Dezimalpunkt <strong>und</strong> Vorzeichen - <strong>und</strong> die Nach-Stellen hinter dem Dezimalpunkt angeben. Bei der formatierten<br />

Ausgabe werden der Variablen Leerzeichen vorangestellt, wenn die Gesamtstellenzahl größer als die Stellenzahl<br />

der Variablen ist. Damit wird ermöglicht, Werte für Tabellen dezimalpunktgenau am Bildschirm oder auf<br />

dem Drucker untereinander ausgeben zu lassen. Sehen Sie hier nun ein Beispiel mit Ergebnisausgabe auf dem<br />

Bildschirm für eine formatierte <strong>und</strong> eine nichtformatierte Ausgabe.<br />

Befehl Ergebnis<br />

nichtformatierte Ausgabe WriteLn ( Strom ); 1.3421645E-02<br />

formatierte Ausgabe WriteLn ( ' Ibe = ', Strom:5:1, ' mA' ); Ibe = 13.4 mA<br />

Die Eingabeanweisung<br />

Hier wird im Quelltext hinter dem Schlüsselwort Read oder ReadLn in Klammern der Variablenname angegeben,<br />

in der die Eingabe gespeichert werden soll. Also einfach : ReadLn ( Laenge ); <strong>und</strong> schon wird die Eingabe<br />

über die Tastatur in der zuvor deklarierten Variablen mit dem Namen Laenge abgespeichert. Mehrfacheingaben<br />

in einem Quelltextbefehl sind zwar möglich, aber nicht zu empfehlen.<br />

Besonderheiten bei der Eingabe<br />

• die Anweisung ReadLn; ohne folgende Klammer mit Variablenname wartet lediglich auf den Tastendruck<br />

der RETURN - bzw. ENTER Taste.<br />

• Reelwertige Zahlen werden mit Punkt statt mit Dezimalkomma eingegeben; also 27.12 statt 27,12 !<br />

• sehr große oder sehr kleine Zahlen werden sinnvoller weise als Exponentialzahlen eingegeben, wobei<br />

der Großbuchstabe E die Angabe der Basis 10 ersetzt. So wird z.B. statt 0.00000003 besser 3E-8 <strong>und</strong><br />

statt 6200000 besser 6.2E6 eingegeben.<br />

Tip :<br />

Durch Eingaben wie 999E32 oder 0.1E-32 lässt sich die Eingabe der beiden elektrotechnischen Grenzfälle<br />

Unendlich <strong>und</strong> Null simulieren, ohne eine -mathematisch nicht erlaubte- Division durch Null zu provozieren.<br />

11.07.02<br />

8-StEin- Ausgabe


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

BEISPIELLÖSUNG EVA-PRINZIP<br />

Entwicklung eines linearen Programms<br />

9/25 Datum :<br />

1) Lastenheft ; Pflichtenheft :<br />

In Amerika wird die Temperatur nicht in Grad Celsius, sondern in Grad Fahrenheit gemessen.<br />

Es gilt : 0 °C ≡ 32 °F; 100 °C ≡ 212 °F<br />

Entwickeln Sie ein Programm, das nach Eingabe des Temperaturwertes in Grad Celsius den<br />

zugehörigen Wert in Grad Fahrenheit auf dem Bildschirm sauber geordnet <strong>und</strong> lesbar ausgibt.<br />

2) Problemanalyse :<br />

a) Eingabevariable: T_Celsius ; Datentyp : kurze ganze Zahl, also SHORTINT;<br />

b) Ausgangsvariable T_Fahrenheit ; Datentyp : vermutlich reelwertig; also REAL<br />

c) Benötigt wird die Bildschirmbibliothek CRT ( cathode ray tube )<br />

d) Algorithmus :<br />

Während die Temperatur in Celsius um 100 Grad steigt, steigt Sie in Fahrenheit um 180 Grad<br />

212 °F - 32 °F = 180 °F ; d.h. das Verhältnis zwischen den Temperaturen beträgt 180/100<br />

oder gekürzt 9/5. Außerdem ist die Temperatur in Fahrenheit um 32°F konstant höher. Daraus<br />

ergibt sich der Algorithmus <strong>zur</strong> Umrechnung : T_Fahrenheit = 9 °F/5 °C • T_Celsius °C + 32 °F<br />

3) Programmstrukturierung<br />

a) Struktogramm b) Programmablaufplan<br />

Programm Fahrenheit<br />

Deklaration<br />

Beginn<br />

Bildschirm löschen<br />

Überschrift ausgeben<br />

Ende<br />

Eingabe des Celsiuswertes<br />

Berechnung des Fahrenheitswertes<br />

Ausgabe des Fahrenheitswertes<br />

Ausgabebildschirm fixieren<br />

4) Codierung ohne Programmdokumentation<br />

PROGRAM Fahrenheit;<br />

USES CRT;<br />

VAR T_Celsius : SHORTINT;<br />

T_Fahrenheit : REAL;<br />

BEGIN<br />

ClrScr;<br />

WriteLn(´Umrechnungsprogramm Grad Celsius in Grad Fahrenheit´);<br />

Write (´Bitte geben Sie die Temperatur in Grad Celsius ein :´);<br />

ReadLn ( T_Celsius );<br />

T_Fahrenheit := 9 / 5 * T_Celsius + 32;<br />

WriteLn(´Die Temperatur in Grad Fahrenheit beträgt : ´, T_Fahrenheit:6:2 ,´ °F´);<br />

ReadLn;<br />

END.<br />

Start<br />

Deklaration<br />

Bildsch. löschen<br />

Ausgabe<br />

Überschrift<br />

Eingabe<br />

T_Celsius<br />

Berechnung<br />

T_Fahrenheit<br />

Ausgabe<br />

T_Fahrenheit<br />

Bildschirm<br />

fixieren<br />

Ende<br />

11.07.02<br />

9-beispiel-eva


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

DOKUMENTATION<br />

10/25 Datum :<br />

10 Regeln für die Dokumentation:<br />

Sie alle werden folgende Situation kennen lernen : Das Programm läuft, Codierfehler gibt es keine mehr <strong>und</strong><br />

man ist fertig mit dem „Hacken“. Das Programm ist abgespeichert <strong>und</strong> man lehnt sich ruhig <strong>zur</strong>ück. Zwar ist der<br />

Quelltext noch in einem chaotischen Zustand, aber was soll’s, das Problem ist ja gelöst. Wie der Lehrer mit<br />

dem Programm klarkommt ist sowieso unwichtig. Sein Problem !<br />

Nach einigen Wochen aber benötigen Sie selbst Teile dieses Programms erneut. Zwar ist ihr altes Programm<br />

noch immer in chaotischem Zustand, aber kein Problem, es gibt ja Programmlistings über den Drucker, um den<br />

Überblick wieder zu bekommen. Der Programmablaufplan ist sowieso verschw<strong>und</strong>en <strong>und</strong> wenn nicht, dann<br />

weiß man nicht mehr zu welchem Programm er gehört. Darüber hinaus werden Sie sich fragen, welche Bedeutung<br />

die Variablen x, y <strong>und</strong> z damals hatten. Welche Taste war mit „ #69 “ gemeint ? Wieso ist an die Formel<br />

der Zusatz 2•π/180 angehängt worden ? Und so weiter ... Schließlich schreien Sie wieder nach dem Lehrer,<br />

der im hausgemachten Chaos zu retten versucht, was zu retten ist. Dies alles kostet Zeit, Papier <strong>und</strong> Nerven.<br />

Kurz <strong>und</strong> gut: Langsam aber sicher wächst das planlose Chaos<br />

Dies alles lässt sich vermeiden, wenn man sein Programm vernünftig dokumentiert. Schauen Sie sich deshalb<br />

das folgende Negativprogramm an. Obwohl es einfach ist, ist es dennoch schwer nachzuvollziehen.<br />

program test1; const x=60; var y,z :real; begin write(´gesamt´); readln(y); z:=100*x/y; write<br />

(´1/100KM´); writeln(z:10:2); end.<br />

1) Befehle für <strong>Pascal</strong> Kontrollstrukturen schreibt man ausschließlich in Großbuchstaben; ebenso wie<br />

die Schlüsselwörter für den Programmkopf <strong>und</strong> den Vereinbarungsteil. Auch Operatoren schreibt<br />

man komplett groß; z.B.: PROGRAM, IF .. THEN .. ELSE oder XOR .<br />

2) Bei Standardfunktionen <strong>und</strong> Standardprozeduren wird nur der <strong>erste</strong> Buchstabe groß geschrieben.<br />

Ausnahme bilden die aus zwei eigenen Wörtern zusammengesetzten Ausdrücke, bei denen jeweils<br />

der Anfangsbuchstabe alleine groß geschrieben wird; z.B.: ArcTan, WriteLn, KeyPressed<br />

oder ReadLn.<br />

3) Pro Zeile wird im Quelltext nur ein einziger Befehl notiert.<br />

4) Konstanten <strong>und</strong> Variablen erhalten eindeutige Bezeichnungen, die entweder genormt sind oder<br />

aus denen die Bedeutung klar hervorgeht. z.B. ist „ T “ nicht die Zeit, sondern die Periodendauer in<br />

Sek.<br />

5) Variablen <strong>und</strong> Konstanten werden im Quelltext mit Kommentaren versehen, aus denen z.B. die<br />

Einheiten <strong>und</strong> der Einheitenvorsatz deutlich werden. Kommentare stehen entweder zwischen geschweiften<br />

Klammen { .... } oder zwischen den kombinierten Zeichen (* .... *). Sie werden nicht mit<br />

kompiliert.<br />

6) Jedes Programm erhält einen Programmkopf als Kommentar, aus dem die Daten <strong>zur</strong> Ort, Zeit,<br />

Version <strong>und</strong> Autor; sowie <strong>zur</strong> verwendeten Hard- <strong>und</strong> Software hervorgehen. Darüber hinaus erhält<br />

der Programmkopf eine kurze Programmbeschreibung mit evtl. Besonderheiten als Hinweis.<br />

7) Zwischen den einzelnen Programmteilen sind Leerzeilen im Quelltext vorzusehen.<br />

8) Eingeklammerte Programmteile, z.B. Schleifenkörper oder Programmteile zwischen BEGIN <strong>und</strong><br />

END werden um zwei Spatien eingerückt. Erfolgt dort eine weitere Einklammerung, wird nochmals<br />

um zwei Spatien eingerückt <strong>und</strong> so weiter. Mit Beendigung der Klammer entfällt das Einrücken.<br />

9) Vor jeder Dateneingabe wird eine Anfrage des Rechners ausgegeben. Programmausgaben erfolgen<br />

in sinnvoller Art <strong>und</strong> Weise <strong>und</strong> nicht in Form von U = 1,3421645E-02, ohne Einheiten <strong>und</strong><br />

ohne elektro-technische Notation, sondern in Form von : Uaus = 13,4 mV<br />

10) Programme erhalten einen eindeutigen Namen, natürlich nach den Regeln von MS-DOS.<br />

Nur wenn Sie sich an alle diese Regeln halten, nehmen Dozenten oder Zeitschriften Ihre Programme an. Sie<br />

ersparen sich auch viel Ärger in Datennetzen <strong>und</strong> bei Kommilitonen während des Studiums. Nach einiger Zeit<br />

des Eingewöhnens werden Sie sehen, dass dies ganz normal ist <strong>und</strong> auch einen Sinn hat.<br />

11.07.02<br />

10-dokumentation


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Übungsaufgaben für lineare Programme<br />

Programmiertechnik Klasse :<br />

Informations- <strong>und</strong> Arbeitsblatt Name :<br />

ÜBUNGSAUFGABEN ZUM LINEAREN PROGRAMMABLAUF<br />

11/25 Datum :<br />

Bevor Sie beginnen, Ihre <strong>erste</strong>n Programme in <strong>Turbo</strong>-<strong>Pascal</strong> zu programmieren erinnern Sie sich<br />

bitte daran, dass ein strukturiertes Vorgehen das Wichtigste überhaupt ist. Programmierknechte, die<br />

später Ihre gedankliche Arbeit in einen Quelltext umsetzen gibt es auf dem Arbeitsmarkt genug.<br />

Wenn überhaupt, dann entwickeln Sie als Ingenieur später nur das Konzept <strong>und</strong> die Dokumentation.<br />

Beachten Sie also die Hinweise <strong>zur</strong> Programmentwicklung auf dem Blatt 4/25 !<br />

Aufgabe 1:<br />

Ein Messwerk mit einem Innenwiderstand von 1500Ω hat einen Endausschlag von 1,5 V. Schreiben<br />

Sie ein Programm, das nach der Eingabe eines gewünschten Messbereichs den benötigten Vorwiderstand<br />

in kΩ ausgibt. Folgende Bildschirmdarstellung sei fürs <strong>erste</strong> vorgeschlagen :<br />

Meßbereichserweiterung<br />

===================<br />

Geben Sie bitte den gewünschten Messbereich in Volt ein ? xxx<br />

Der erforderliche Vorwiderstand für das Instrument beträgt : yyyy.yy kΩ<br />

Aufgabe 2:<br />

Schreiben Sie zwei Programme, die Vektoren - z.B. aus der Elektrotechnik - umrechnen.<br />

a) Von der Polarform in die Rechteckform P ==> R<br />

b) von der Rechteckform in die Polarform R ==> P<br />

In der Elektrotechnik ist dies ein gr<strong>und</strong>legendes Rechenverfahren beim Umgang mit komplexen Zahlen<br />

in der Wechselstromtechnik. z.B. für die Impedanz Z = 100 Ω + j 230 Ω oder Z = |Z| + e jϕ<br />

Die Ausgaben sollten in folgender Form auf dem Bildschirm dargestellt werden :<br />

Vektor = ⏐xx.xx [ Einheit ]⏐ • e^ j yy.yy ° bzw. Vektor = xxx.xxx [ Einheit ] + j yyy.yyy [ Einheit ]<br />

Aufgabe 3:<br />

Das Volumen eines Gases ( 3000 cm 3 = 3 l ) bei 20 °C <strong>und</strong> einem Druck von 998 hPa soll für die<br />

Normalbedingung ( 1013 hPa <strong>und</strong> 0 °C ) umgerechnet werden. Die Umrechnung kann mit der allgemeinen<br />

Gasformel, die den Zusammenhang zwischen Gasvolumen, Druck <strong>und</strong> Temperatur beschreibt,<br />

berechnet werden.<br />

Aufgabe 4:<br />

Ein Programm soll Sie nach Vornamen, Namen, PLZ, Ort, Straße <strong>und</strong> Hausnummer fragen. Nach der<br />

hoffentlich geglückten Eingabe der 6 Daten, soll das Programm auf Anfrage [ j(a) oder y(es) ] Ihre<br />

Daten mitten auf dem Bildschirm in Form einer Visitenkarte geordnet wieder ausgeben.<br />

Aufgabe 5:<br />

Zerlegen Sie die Aufgaben 1 bis 3 in Prozeduren ( siehe dazu Blatt 12/25 ) .<br />

Aufgabe 6:<br />

Laden Sie ein Register mit der Binärzahl: 0101 0101(2) <strong>und</strong> schieben Sie alle Bits im Register um zwei<br />

Stellen nach links. Verknüpfen Sie das Ergebnis logisch UND mit der Maske 1100 000(2) <strong>und</strong> geben<br />

Sie an, welches Bit im Register zum Schluss noch gesetzt ist.<br />

Und denken Sie daran :<br />

Program testing can be used to show the presence of bugs, but never to show their absence !<br />

Zitat nach E.W.DIJKSTRA<br />

11.07.02<br />

11-übung-eva


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Prozeduren<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

PROZEDUREN ALS UNTERPROGRAMME<br />

12/25 Datum :<br />

Ein langes Programm kann sehr schnell unübersichtlich werden. Man fasst deshalb Teilprobleme zu Unterprogrammen<br />

zusammen. Aus dem Hauptprogramm werden diese Unterprogramme dann entsprechend aufgerufen.<br />

Das bringt vor allem dann Vorteile, wenn ein Unterprogramm mehrfach genutzt werden kann. In <strong>Turbo</strong>-<strong>Pascal</strong><br />

unterscheidet man zwei Arten von Unterprogrammen ( subroutines ).<br />

a) die Prozeduren ( PROCEDURE ) - sie bewirken etwas nur dadurch, dass sie aufgerufen werden<br />

Beispiel : ClrScr; GotoXY(x,y); Randomize; Delay(x) usw.<br />

b) die Funktionen ( FUNCTION ) - sie liefern bei ihrem Aufruf stets nur einen Wert an eine Variable<br />

Beispiel : y:= sin(x); y:= sqrt(x); y:= ro<strong>und</strong>(x); y:=int(x); usw.<br />

Subroutinen sind aber in <strong>Turbo</strong>-<strong>Pascal</strong> nicht nur fest vorgegeben, wie die obigen Beispiele, sondern sie können<br />

von uns auch selbst <strong>erste</strong>llt werden. Das ist z.B. unbedingt notwendig, wenn man ständig im Hauptprogramm<br />

die gleiche Berechnung durchzuführen hat oder mathematische Funktionen wie z.B.: y:= n! (Fakultät); y:= arcsin(x);<br />

y:= a b oder auch y:= log(x) benötigt, die in <strong>Turbo</strong>-<strong>Pascal</strong> nicht <strong>zur</strong> Verfügung stehen. Wenn man dann<br />

eine größere Anzahl von Prozeduren <strong>und</strong> Funktionen <strong>erste</strong>llt <strong>und</strong> gesammelt hat, kann man in einem späteren<br />

Arbeitsschritt diese Subroutinensammlung in einer eigenen UNIT zusammenfassen <strong>und</strong> im Deklarationsteil mit<br />

USES ; aufrufen ( s.S.13/20 ). Alle Subroutinen sind dann stets verfügbar.<br />

a) einfache parameterlose Prozeduren<br />

Unterprogramme müssen im Hauptprogramm zunächst deklariert werden. Das geschieht mit dem Schlüsselwort<br />

PROCEDURE gefolgt vom selbst gewählten Namen des Unterprogramms <strong>und</strong> dem Semikolon. Der Anweisungsteil<br />

der Prozedur steht genau wie beim Hauptprogramm zwischen BEGIN <strong>und</strong> END; hier allerdings<br />

gefolgt von einem Semikolon !<br />

PROCEDURE Eingabe;<br />

VAR ....<br />

BEGIN<br />

Anweisung 1;<br />

Anweisung ..;<br />

END;<br />

Im Hauptprogramm wird das Unterprogramm nur mit seinem Prozedur-Namen – <strong>und</strong> evtl. mit Parameterangaben<br />

- aufgerufen ( hier: Eingabe; ). Das Schlüsselwort Procedure entfällt beim Aufruf der Subroutine.<br />

b) Lokale <strong>und</strong> globale Variable in Prozeduren<br />

Prozeduren sind fast genau so aufgebaut wie Programme selbst. Sie können deshalb auch einen eigenen Deklarationsteil<br />

enthalten. Variable, die innerhalb der Prozedur deklariert worden sind, gelten nur innerhalb dieser<br />

Prozedur. Im übergeordneten Hauptprogramm sind sie unbekannt. Man nennt sie lokale Variable. Im Hauptprogramm<br />

deklarierte Variable sind im ganzen Programm, also auch in den Unterprogrammen gültig. Werden<br />

sie im Unterprogramm verändert, so haben sie auch im Hauptprogramm geänderte Werte. Es können also unerwünschte<br />

„Seiteneffekte“ entstehen. Man nennt solche Variablen globale Variable. Innerhalb einer Prozedur<br />

können im Vereinbarungsteil weitere ( Unter- ) Prozeduren definiert werden, die aber nur aus diesem Unterprogramm<br />

heraus aufgerufen werden können.<br />

c) Prozeduren mit Wert-Parameterübergabe ( call by value )<br />

Einer Prozedur können Werte übergeben werden. Dazu wird der Prozedurkopf um Namen <strong>und</strong> Datentypenbezeichnung<br />

der empfangenen Variablen ergänzt. Also beispielsweise: PROCEDURE Addiere ( x, y : Byte );<br />

Beim Aufruf der Prozedur im Hauptprogramm müssen natürlich die Parameter mit übergeben werden, wobei<br />

darauf zu achten ist, dass die Datentypen der einzelnen Parameter auch übereinstimmen. z.B.: Addiere ( 2,4 );<br />

Da Wert-Parameter nicht verändert werden können ( es gibt ja keinen Speicherplatz, der für sie reserviert ist ),<br />

ist eine Rückgabe des veränderten Wertes an das Hauptprogramm nicht möglich.<br />

d) Prozeduren mit Variablen-Parameterübergabe ( call by reference )<br />

Benötigt man veränderte Wert-Parameter später noch im Hauptprogramm, so muss man Variablen-Parameter<br />

im Prozedurkopf vereinbaren. Sie werden durch ein vorangestelltes VAR im Prozedurkopf gekennzeichnet.<br />

Beispiel : PROCEDURE Addiere ( VAR X, Y : Integer); Beim Aufruf im Hauptprogramm dürfen hinter dem<br />

Prozedurnamen aber nur Variable - <strong>und</strong> keine Konstanten oder arithmetischen Ausdrücke - angegeben werden,<br />

da diese ja an die geänderten Parameter <strong>zur</strong>ückgegeben werden. Beispiel : Addiere ( a,b );<br />

11.07.02<br />

12-prozeduren


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Funktionen<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

FUNKTIONEN ALS UNTERPROGRAMME<br />

13/25 Datum :<br />

Funktionen sind spezielle Prozeduren, die als Ergebnis genau einen einzigen Wert, den Funktionswert,<br />

an das aufrufende Programm <strong>zur</strong>ückliefern. Auch sie müssen im Deklarationsteil des Hauptprogramms<br />

vereinbart werden. Das Schlüsselwort lautet FUNCTION gefolgt von dem Namen <strong>und</strong> der<br />

formalen Parameterliste. Zusätzlich wird hinter einem Doppelpunkt immer ein Datentyp als Ergebnistyp<br />

erwartet. Eine Funktion gehorcht daher folgender Syntax :<br />

FUNCTION < Name > (< Parameterliste> : < Datentyp > ) : < Ergebnistyp >;<br />

VAR ...;<br />

BEGIN<br />

....<br />

< Anweisungen >;<br />

< Name > := < Berechnung der Funktion >;<br />

....<br />

END;<br />

Auch bei Funktionen können Wert-Parameter <strong>und</strong> Variablen-Parameter übergeben werden. Allerdings<br />

ist die Verwendung von Variablen-Parametern in Funktionen wenig sinnvoll, da nun zusätzlich zum<br />

einzelnen Funktionswert noch weitere Variablen übergeben werden können, was dem eigentlichen<br />

Sinn der Funktion entgegensteht. Nutzen Sie in einem solchen Falle Prozeduren.<br />

Beispiel:<br />

Es soll eine Funktion mit dem Namen „Sinus“ geschrieben werden, die die Eingabe des Winkels im<br />

üblichen Gradmaß erlaubt <strong>und</strong> den berechneten Wert an die Variable y übergibt.<br />

PROGRAM Test_einer_Funktion; Programmkopf<br />

USES CRT;<br />

VAR X,Y : REAL; Deklarationsteil<br />

FUNCTION Sinus( Winkel : REAL ): REAL;<br />

BEGIN<br />

Sinus := Sin( Winkel * Pi / 180 );<br />

END;<br />

BEGIN (* Hauptprogramm *) Anweisungsteil<br />

ClrScr;<br />

Write (´Bitte Winkel eingeben : ´); ReadLn(X); E ingabe<br />

Y := Sinus (X); V erarbeitung<br />

Write (´Der Sinus des Winkels ´, X:7:2,´ beträgt : ´, Y :7:5 ); A usgabe<br />

END.<br />

Der Vorteil von Funktionen gegenüber Prozeduren besteht darin, dass sie im Hauptprogramm wie<br />

eine Variable behandelt werden <strong>und</strong> nicht wie eine Prozedur als Anweisung. Deshalb können nur<br />

Funktionen direkt in allen Ausdrücken z.B. Ausgabeanweisungen aufgerufen werden, ohne den Ausgabewert<br />

zuvor einer Variablen zuweisen zu müssen. Für das obige Beispiel wäre also auch folgende<br />

Ausgabeanweisung erlaubt :<br />

WriteLn(´Der Sinus des Winkels ´,X:7:2,´ beträgt : ´, Sinus(X):7:5 );<br />

Ruft man Prozeduren oder Funktionen in ihrem eigenen Anweisungsteil selbst immer wieder auf, so<br />

nennt man eine solche Subroutine rekursiv. Aber Vorsicht, der Heap-Speicher kann überlaufen.<br />

11.07.02<br />

13-funktionen


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

UNITS<br />

14/25 Datum :<br />

Hat man viele zusammengehörige Prozeduren <strong>und</strong> Funktionen gesammelt, die zum Beispiel die<br />

Maus unter <strong>Turbo</strong>-<strong>Pascal</strong> steuern, den Datenaustausch über die serielle Schnittstelle regeln oder<br />

auch selbstgebastelte, erweiterte mathematische Funktionen, so kann man diese Programmteile in<br />

UNITS zusammenfassen. Die Vorteile liegen auf der Hand :<br />

- Prozeduren / Funktionen müssen nur einmal geschrieben werden<br />

- Programme werden kürzer <strong>und</strong> übersichtlicher<br />

- zu einem Thema gehörende Subroutinen werden geordnet zusammengefasst<br />

Eine Unit besteht aus drei Teilen : 1) dem Interface ( der Schnittstelle ); 2) der Implementation<br />

( d.h. dem tatsächlichen Programmkode ) <strong>und</strong> 3) der Initialisierung ( einer Art Hauptprogramm ). Die<br />

gr<strong>und</strong>sätzliche Struktur der Unit ist weitgehend mit der eines Programms vergleichbar. Ihr Aufbau ist<br />

anschließend aufgeführt :<br />

UNIT < name >; { Das Schlüsselwort UNIT ersetzt hier den Begriff PROGRAM }<br />

INTERFACE<br />

{ der Interface-Teil wird als „öffentlicher“ Teil bezeichnet. Er enthält alle Namen der Konstanten,<br />

Standard-Units, Variablen, Funktionen <strong>und</strong> Prozeduren, die dem Hauptprogramm zu<br />

gänglich sein sollen. Damit sind diese Elemente global vereinbart. Funktionen <strong>und</strong> Prozeduren<br />

werden allerdings nur mit ihren vollständigen Kopfteilen aufgeführt. }<br />

IMPLEMENTATION<br />

{ Der eigentliche Quellkode der bereits im Interface-Teil genannten Funktionen oder Prozeduren<br />

erfolgt erst hier. Hier werden auch die lokalen Konstanten, Datentypen <strong>und</strong> Variablen<br />

vereinbart, die nur innerhalb der Unit gelten.<br />

BEGIN (* INITIALISIERUNG *)<br />

{ bleibt meist leer, nur wenn beim Start des Programms bestimmte Einstellungen für diese<br />

Unit erforderlich sind, kann hier ein Anweisungsteil stehen; z.B. ein Reset. }<br />

END.<br />

Wird ein solches Unit-Programm mit dem <strong>Pascal</strong> Compiler übersetzt, so entsteht im gesetzten Pfad (<br />

Menue OPTIONS; Schalter DIRECTORIES; EXE & TPU directory ) eine Objektkode - Datei mit der<br />

Extension: < Unitname > •TPU ( <strong>Turbo</strong> <strong>Pascal</strong> Unit ). Anschließend können Sie die Unit in Ihrem Programm<br />

mit der USES - Anweisung jederzeit aufnehmen. Aber das kennen Sie ja bereits von der Verwendung<br />

der Standard-Units her, die mit <strong>Turbo</strong>-<strong>Pascal</strong> bereits geliefert wurden; z.B.: USES CRT. Die<br />

anderen Standard Units heißen: SYSTEM, DOS, PRINTER, GRAPH, OVERLAY, TURBO3 <strong>und</strong><br />

GRAPH3. Sie sind in der Datei <strong>Turbo</strong>.TPL ( <strong>Turbo</strong> <strong>Pascal</strong> Library ) zusammengefasst.<br />

Beispiel für eine Cursor-Unit ( mit Verwendung des Video-Interrupts 10hex )<br />

UNIT Cursor; BEGIN<br />

regs.ax:=$0100;regs.cx:=$2607;intr($10,regs);<br />

INTERFACE END;<br />

USES DOS; PROCEDURE Cursor_an;<br />

VAR regs : REGISTERS; BEGIN<br />

PROCEDURE Cursor_weg; regs.ax:=$0100; regs.cx:= $0C0D;intr($10,regs);<br />

PROCEDURE Cursor_an; END;<br />

BEGIN<br />

IMPLEMENTATION { Anweisungen entfallen }<br />

PROCEDURE Cursor_weg; END.<br />

Mit dem Programm TPUMOVER.EXE ( im <strong>Pascal</strong>-Paket enthalten ) kann man seine eigenen Units in<br />

die Standard-<strong>Pascal</strong>-Library für Units ( TURBO.TPL ) fest mit aufnehmen bzw. wieder entfernen. Das<br />

heißt, man muss nicht mehr darauf achten, ob die eigene Unit im richtigen Pfad <strong>zur</strong> Verfügung steht.<br />

11.07.02<br />

14-units


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

WIEDERHOLUNGSSTRUKTUREN<br />

15/25 Datum :<br />

Schleifen; ( engl. loops )<br />

In allen Programmen vorher befassten wir uns mit linearen Algorithmen; das waren Anweisungen, die<br />

eine nach der anderen schrittweise ausgeführt wurden. Nun kommt es aber häufiger vor, dass eine<br />

oder mehrere Anweisungen wiederholt durchlaufen werden müssen, weil Sie z.B. eine Eingabe falsch<br />

ausgeführt haben <strong>und</strong> nun noch einmal einlesen müssen. Oder Sie wollen die gleiche Rechnung<br />

noch einmal ausführen; allerdings mit geänderten Zahlenwerten.<br />

Wie auch immer, Sie müssen im Programm <strong>zur</strong>ückspringen an die Stelle im Programm, die erneut<br />

durchlaufen werden soll. Allerdings nur so lange, bis eine Anweisung die Wiederholung verbietet. In<br />

<strong>Pascal</strong> stehen Ihnen dazu drei Möglichkeiten der Schleifenprogrammierung <strong>zur</strong> Verfügung :<br />

ja<br />

Wiederholungsanweisungen<br />

Anzahl der W iederholungen<br />

bekannt ?<br />

Ist die Anzahl der Schleifendurchläufe<br />

bekannt, so nutzt man die<br />

zählergesteuerte Schleife. Dazu<br />

gehört, dass man zunächst eine<br />

Zählervariable oder auch Laufvariable<br />

deklariert die mitzählt, wie oft<br />

die Schleife schon durchlaufen wurde.<br />

Es v<strong>erste</strong>ht sich von selbst,<br />

dass der Datentyp dieser Variablen<br />

eine Integerzahl bzw. eine ordinale<br />

Größe sein muss. Ist der Endstand<br />

erreicht, bricht die Schleife ab.<br />

Syntax der Anweisung : FOR := (DOWN)TO DO<br />

BEGIN<br />

< Anweisungen > ;<br />

END;<br />

Im Gegensatz zu anderen <strong>Programmiersprache</strong>n ist es bei dieser Anweisung nicht möglich, die<br />

Schrittweite anzugeben. Man weicht dann auf die beiden anderen Schleifenanweisungen aus.<br />

Schleife mit Endebedingung Schleife mit Anfangsbedingung<br />

nein<br />

zählergesteuerte Schleife bedingungsgesteuerte Schleife<br />

Abbruchbedingung<br />

am Anfang der Schleife<br />

kopfgesteuerte Schleife<br />

( pre check loop )<br />

Abbruchbedingung<br />

am Ende der Schleife<br />

fußgesteuerte Schleife<br />

( post check loop )<br />

REPEAT WHILE < Bedingung erfüllt > DO<br />

< Anweisungen > ; BEGIN<br />

UNTIL < Bedingung erfüllt > ; < Anweisungen > ;<br />

END;<br />

Solange in beiden bedingungsgesteuerten Wiederholungen die Bedingung erfüllt, also wahr ist, werden<br />

die eingeklammerten Anweisungen wiederholt. Wird die Bedingung falsch, geht das Programm<br />

zum nächsten, der Schleife folgenden, Befehl über. Die eingeklammerten Anweisungen bezeichnet<br />

man auch als Schleifenkörper. Die graphische Darstellung der drei Schleifenkonstruktionen für das<br />

Struktogramm oder den PAP entnehmen Sie bitte dem Blatt 5/25. Im PAP müssen die bedingungsgesteuerten<br />

Schleifen durch Verzweigungen dargestellt werden.<br />

Zum Schluss noch eine Auswahl an Vergleichsoperatoren für die Bedingungsprüfung :<br />

= gleich < > ungleich > größer Keypressed<br />

< kleiner >= größer gleich


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informations- <strong>und</strong> Arbeitsblatt Name :<br />

ÜBUNGEN ZU WIEDERHOLUNGSSTRUKTUREN<br />

Übungsaufgaben für Wiederholungsstrukturen<br />

16/25 Datum :<br />

Bevor Sie die einzelnen Aufgaben konkret angehen, denken Sie bitte daran, dass die strukturierte<br />

Vorgehensweise ( Seite 4/25 ) das vorrangige Lernziel darstellt. Gerade hier sind die Programmablaufpläne<br />

oder Struktogramme unbedingt erforderlich. Werden die Abbruchbedingungen vorher<br />

nicht genau geprüft, bleibt das Programm in der Wiederholungsschleife „hängen“ <strong>und</strong> kann nur mit<br />

Gewalt abgebrochen werden. Der Quelltext geht damit unweigerlich verloren.<br />

Aufgabe 1:<br />

a) Ein konstanter Widerstand von R = 330 Ω mit einer maximalen Leistung von P = 0,5 W wird an<br />

unterschiedlichen Spannungen U = 1 V bis 29 V in Schritten a´ 4 V betrieben. Ermitteln Sie für<br />

jeden Spannungswert den dazugehörigen Strom, <strong>und</strong> geben Sie die Werte tabellarisch geordnet<br />

auf dem Bildschirm aus.<br />

b) Ermitteln Sie zusätzlich jeweils auch den maximal zulässigen Strom durch den Widerstand.<br />

Geben Sie auch diese Werte mit Einheiten in der Tabelle mit aus.<br />

c) Zeichen Sie die Graphen sauber in ein beschriftetes Diagramm, <strong>und</strong> lesen Sie ab, welche Spannung<br />

Umax noch möglich ist, ohne den Widerstand zu zerstören. Welcher Strom IR fließt?<br />

Aufgabe 2:<br />

An eine Ersatzspannungsquelle Uo = 12 V mit konstantem Innenwiderstand Ri = 10 Ω wird ein passiver<br />

Zweipol angeschlossen. Leider ist der Widerstand des „Verbrauchers“ nicht konstant, sondern<br />

schwankt von 1 Ω bis 101 Ω ( wir beginnen erst bei 1 Ω, um im Programm die Division durch Null zu<br />

vermeiden ). Berechnen Sie den Strom I, die Klemmenspannung Uk <strong>und</strong> die am „Verbraucher“ abgegriffene<br />

Leistung Pab für die unterschiedlichen Belastungsfälle. Geben Sie die Werte I = f(RL), Uk =<br />

f(RL) <strong>und</strong> Pab = f(RL) tabellarisch am Bildschirm aus. Zeichen Sie in einem Diagramm sauber die<br />

Graphen, deren Werte Sie mit Ihrem Programm ermittelt haben. Was können Sie für Schlüsse ziehen,<br />

wenn es um die Leistungsaufnahme eines „Verbrauchers“ geht ? Welche Forderung stellen Sie an<br />

ein Netzteil, ein Ladegerät oder an eine Satellitenantenne ?<br />

Aufgabe 3:<br />

Innerhalb eines Programms soll eine Zahl eingelesen werden, die nicht kleiner als 20 aber auch nicht<br />

größer als 100 sein darf. Bei Falscheingaben muss der Wert neu eingelesen werden; <strong>und</strong> zwar solange,<br />

bis der Wert im Gültigkeitsbereich liegt. Programmieren Sie ein Unterprogramm, das diese<br />

Anforderung an die Eingabe übernimmt. Entwickeln Sie selbst ein Hauptprogramm, um die Subroutine<br />

zu kontrollieren.<br />

Aufgabe 4:<br />

Über die parallele Schnittstelle des Rechners, soll eine Platine mit 8 LEDs ( light emitting diode ) angesteuert<br />

werden. Die Leuchtdioden sollen dabei wie ein Lauflicht aufleuchten. Zur Programmierung<br />

über die parallele Schnittstelle siehe Blatt 17/25). Wie werden die LEDs angeschlossen ?<br />

Aufgabe 5:<br />

Ein Programm soll mitten auf dem Bildschirm in 10 Reihen <strong>und</strong> 10 Spalten das „Kleine Einmal-Eins“<br />

in Form einer Tabelle ausgeben; so dass man sofort z.B. das Produkt von 7 * 6 ablesen kann.<br />

Aufgabe 6:<br />

Ein Potentiometer von 100 Ω wird als Spannungsteiler eingesetzt. An seinen Schleifer werden nacheinander<br />

die Lastwiderstände 5 Ω, 45 Ω, 85 Ω <strong>und</strong> 125 Ω angeschlossen. Berechnen Sie für jeden<br />

Lastwiderstand die Ausgangsspannung Uaus, wenn der Schleifer in 10 Ω – Schritten verändert wird.<br />

11.07.02<br />

16-übungen-loops


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

DIE PARALLELE SCHNITTSTELLE LPT<br />

17/25 Datum :<br />

Will man mit dem Computer reale Prozesse steuern oder überwachen, so erfordert dies zunächst<br />

einmal eine geeignete Verbindung <strong>zur</strong> Außenwelt. Ein Programm soll ja in der Lage sein, Informationen<br />

von außen zu erfassen <strong>und</strong> Steuersignale an äußere Geräte weiterzugeben. Das erforderliche<br />

Tor <strong>zur</strong> Außenwelt wird durch Interfaces geöffnet. Für PCs nach dem Industriestandard lassen sich,<br />

über die ohnehin vorhandenen Schnittstellen, die serielle Schnittstelle ( RS232 ), die Druckerschnittstelle<br />

( Centronics ) <strong>und</strong> der Joystick-Anschluss direkt als Interface nutzen. Damit erübrigt sich jede<br />

weitere Hardware.<br />

Die parallele Schnittstelle ( LPT1 oder LPT2 ) des PCs stellt insgesamt 17 digitale Leitungen <strong>zur</strong> Verfügung,<br />

die sich für den schnellen Datenaustausch mit Interface-Schaltungen nutzen lassen. Die Ein-<br />

<strong>und</strong> Ausgänge sind TTL-kompatible Leitungen <strong>und</strong> nicht vor Überlastung geschützt !<br />

Regeln :<br />

1) Interfaceschaltungen nur bei ausgeschaltetem PC anschließen !<br />

2) An die Eingänge dürfen nur Gleichspannungen zwischen 0 V <strong>und</strong> 5 V gelegt werden !<br />

3) Ausgänge des Ports niemals kurzschließen oder mit anderen Ausgängen verbinden !<br />

4) An die Kontakte der 25-poligen Sub-D-Stecker keine Fremdspannungen anlegen !<br />

5) Alle Ausgänge dürfen nur mit maximal 10 mA „belastet“ werden !<br />

6) Induktive Lasten ( Relais, Motor ... ) gr<strong>und</strong>sätzlich nur mit Freilaufdiode schalten !<br />

Der Datenaustausch über den parallelen Port erfolgt über drei 8-Bit-Register, die jeweils unter einer<br />

Basisadresse ( BA ) <strong>und</strong> den beiden folgenden Adressen zu erreichen sind. Für die einzelnen<br />

Schnittstellen gelten folgende Basisadressen :<br />

Schnittstelle 1: LPT1 ⇒ $378 oder 888 Schnittstelle 2: LPT2 ⇒ $278 oder 632<br />

Das <strong>erste</strong> Register heißt Datenregister <strong>und</strong> ist unter der Basisadresse zu erreichen. Es stellt ( in der<br />

Regel ) einen zusammenhängenden 8-Bit Ausgabeport <strong>zur</strong> Verfügung, dessen positive Spannungspegel<br />

sich im Bereich von 3,5 V bis 5 V bewegen (TTL-Pegel). Der <strong>Pascal</strong>-Befehl für die Ausgabe<br />

eines Bytes n über das Datenregister lautet :<br />

Datenausgabe Port [ BA ] := n ;<br />

Unter der Portadresse BA + 1 kann man das Byte des Statusregisters in eine Variable einlesen <strong>und</strong><br />

auswerten. Diese Hilfsleitungen für den Drucker sind meist TTL-kompatibel, d.h. offene Eingänge<br />

erscheinen als High-Pegel. Das Lesen der Daten über das Statusregister mit gleichzeitiger Korrektur<br />

des invertierten Eingangs „ busy “<strong>und</strong> Ausblendung der unbenutzten Eingänge 2 0 bis 2 2 lautet :<br />

Datenregister Adresse : BA<br />

Variable := (Port [ BA+1 ] XOR 128) AND 248;<br />

7 6 5 4 3 2 1 0<br />

Statusregister Adresse: BA + 1<br />

7 6 5 4 3 2 1 0<br />

Steuerregister Adresse: BA + 2<br />

error<br />

select<br />

paper empty<br />

acknowledge<br />

busy (invertiert)<br />

7 6 5 4 3 2 1 0<br />

select-in (invertiert)<br />

init / reset<br />

autofeed (invertiert)<br />

strobe (invertiert)<br />

D0 .. D7 ausgeben<br />

nur lesen<br />

ausgeben<br />

( evtl. lesen )<br />

Die Portadresse BA + 2 erlaubt den Zugriff auf<br />

das Steuer- oder Controlregister. Über die vier<br />

Steuerleitungen können Informationen ausgegeben<br />

werden. Da es sich aber um Open-Kollektor<br />

Ausgänge handelt, können sie auch gelesen werden,<br />

wenn man die Anschlüsse über 3,3 kΩ Widerstände<br />

gegen +5 V legt. Beachten Sie bitte,<br />

dass drei der vier Leitungen invertiert verwendet<br />

werden. Diese Invertierung kann aber bereits bei<br />

der Ein- oder Ausgabe über BA+2 wie folgt korrigiert<br />

werden :<br />

Ausgabe: Port [Ba+2] := n XOR 11;<br />

Eingabe: Variable:=(Port[Ba+2]XOR 11)AND 15;<br />

Das Bit 2 5 des Steuerregisters schaltet die Richtung des Datenflusses im Datenregister um,<br />

wenn die Schnittstelle bidirektional ist oder im ECP- oder EPP-Modus arbeitet (BIOS).<br />

11.07.02<br />

17-LPT


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

ENTSCHEIDUNGS- BZW. VERZWEIGUNGSSTRUKTUREN<br />

18/25 Datum :<br />

Im täglichen Leben müssen wir ständig Entscheidungen treffen. Meist sind es WENN .. DANN Entscheidungen,<br />

die oft erhebliche Auswirkungen haben. Auch in Programmen können wir solche Entscheidungen<br />

treffen. Solche Programme enthalten dann mindestens eine Bedingung, die darüber<br />

entscheidet, in welcher Reihenfolge die Anweisungen abgearbeitet werden. In <strong>Turbo</strong>-<strong>Pascal</strong> werden<br />

dabei folgende Auswahlstrukturen unterschieden :<br />

• Einfache Auswahl<br />

- einseitige Auswahl IF .. THEN ..<br />

Sie ist ein Sonderfall der zweiseitigen Auswahl, der sogenannten Alternative.<br />

- zweiseitige Auswahl ( Alternative ) IF .. THEN .. ELSE ..<br />

Die abgefragte Variable kann zwei Fälle abdecken.<br />

• Mehrfache Auswahl ( Fallstruktur ) CASE .. OF .. END;<br />

Die in der Bedingung abgefragte Variable kann beliebig viele Fälle annehmen.<br />

Bedingung<br />

erfüllt<br />

nein<br />

ja<br />

Anweisung 1<br />

Anweisung 2<br />

IF < Bedingung=true > THEN<br />

BEGIN<br />

< Anweisungen ><br />

END ;<br />

Bedingung<br />

erfüllt<br />

nein<br />

Anweisung a<br />

Anweisung b<br />

ja<br />

Anweisung 1<br />

Anweisung 2<br />

IF < Bedingung=true > THEN<br />

BEGIN<br />

< Anweisungen 1,2 ><br />

END<br />

ELSE<br />

BEGIN<br />

< Anweisungen a,b><br />

END ;<br />

Ausdruck<br />

Fall1<br />

Fall2<br />

Fall3<br />

Anweisung 1<br />

Anweisung 2<br />

Anweisung 3<br />

CASE < Variable > OF<br />

< Wert1 > : BEGIN<br />

<br />

END;<br />

< Wert2 > : BEGIN<br />

< Wert3 > : BEGIN<br />

<br />

END;<br />

<br />

END;<br />

Die Verwendung der einzelnen Verzweigungsstrukturen können Sie den Ausschnitten der Programmablaufpläne<br />

entnehmen. Ihre zeichnerische Darstellung für die Struktogramme finden Sie auf<br />

der Seite 5/25. Es gibt eigentlich nur wenige Punkte bei der Programmierung zu beachten :<br />

• Wenn nach einer Auswahl nur eine Anweisung alleine ausgeführt werden soll, kann man die Einklammerung<br />

der Anweisung mit BEGIN <strong>und</strong> END entfallen lassen; man rückt sie dann etwas ein.<br />

• Vor ELSE darf bei der zweiseitigen Auswahl kein Semikolon stehen ( trotz END ), da der gesamte<br />

Befehl an dieser Stelle noch nicht beendet ist.<br />

• Bei der Mehrfachauswahl kann die Variable nur ordinale ( abzählbare ) Datentypen aufnehmen,<br />

d.h. der logische Vorgänger PRED( n ) oder Nachfolger SUCC( n ) muss bekannt sein.<br />

• Bei der Mehrfachauswahl kann deshalb die Variable auch aus „Characters“ bestehen. Sie<br />

steht/stehen dann in Hochkommata. Beispiel : CASE Variable OF ´A , a´ : BEGIN ...<br />

• Innerhalb eines Verzweigungsteils sind weitere Verzweigungen möglich; führen aber zu<br />

unübersichtlichen Programmen. Besser ist hier die Mehrfachauswahl geeignet.<br />

END;<br />

13.07.02<br />

18-verzweigungen


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informations- <strong>und</strong> Arbeitsblatt Name :<br />

ÜBUNGEN ZU VERZWEIGUNGSSTRUKTUREN<br />

Übungsaufgaben Verzweigungsstrukturen :<br />

19/25 Datum :<br />

- Formulieren Sie das Problem in einem ganzen Satz.<br />

- Deklarieren Sie die notwendigen Konstanten, Variablen <strong>und</strong> deren Datentypen.<br />

- Skizzieren Sie den PAP <strong>und</strong>/oder das zugehörige Struktogramm.<br />

- Erstellen Sie den Quelltext <strong>und</strong> entfernen Sie alle Syntaxfehler.<br />

- Prüfen Sie Ihr Programm auf logische Fehler ( Testläufe ).<br />

- Dokumentieren Sie Ihr Programm.<br />

- Entfernen Sie Rechtschreibfehler aus Bildschirmmeldungen, <strong>und</strong> sorgen Sie für eine übersicht-<br />

liche <strong>und</strong> sinnvolle Bildschirmdarstellung.<br />

Aufgabe 1:<br />

Prüfen Sie eine einzugebende Zahl auf ihr Vorzeichen; lassen Sie einen entsprechenden Kommentar<br />

ausgeben. Bedenken Sie auch die Grenzfälle des Zahlenbereichs !<br />

Aufgabe 2:<br />

Lesen Sie das Statusbyte der parallelen Schnittstelle LPT2 ein, <strong>und</strong> lassen Sie ein Programm melden,<br />

ob die Leitung Acknowledge „high“ oder „low“ -Pegel hatte ( siehe Blatt 16/20 ).<br />

Aufgabe 3:<br />

Erweitern Sie Ihre linearen Programme, welche Vektoren umrechnen. Wahlweise von der Polarform<br />

in die Rechteckform ; oder von der Rechteckform in die Polarform. Die Wahl wird über ein Menue mit<br />

< P > <strong>und</strong> < R > gesteuert. Fehleingaben sollen <strong>zur</strong> Fehlermeldung führen; die Eingabe erfolgt dann<br />

erneut. Ihr Programm wird übersichtlicher, wenn Sie Ihre linearen Umrechnungsprogramme zunächst<br />

in Prozeduren verwandeln, die Sie im Hauptprogramm nur aufrufen müssen.<br />

Aufgabe 4:<br />

Der Laststrom <strong>und</strong> die Ausgangsspannung eines linearen Spannungsteilers soll berechnet werden.<br />

Dabei sollen Sie über ein Menue zwischen den drei Fällen : a) Kurzschluss; b) Leerlauf <strong>und</strong> c) Belastung<br />

wählen können. Als Referenzspannung sei hier 50 V vorgegeben. Wählen Sie mit , <br />

oder . R1 = 220 Ω; R2 = 330 Ω; RL = 180 Ω . Schreiben Sie das Programm einmal mit IF .. THEN<br />

.. ELSE <strong>und</strong> einmal mit CASE .. OF .. END.<br />

Aufgabe 5:<br />

Ein Programm soll quadratische Gleichungen in der Form : ax 2 + bx + c = 0 lösen können. Beachten<br />

Sie die Fälle, in denen die Diskriminante negativ oder gleich „Null“ wird !<br />

Aufgabe 6:<br />

In den pascalinischen Sümpfen leben die vier Stämme der Asis, Belas, Cedis <strong>und</strong> Drudis. Forschungen<br />

haben ergeben, dass es vier Eigenschaften gibt, die eine Unterscheidung der Stämme erlauben :<br />

ein Bewohner der Sümpfe kann ( muss aber nicht ) manuseln, einen Knelt haben, löpsen <strong>und</strong> nopeln.<br />

Man weiß, dass nur die Asis einen Knelt haben <strong>und</strong> manuseln. Hat jemand keinen Knelt <strong>und</strong> nopelt,<br />

dann ist er gewiss ein Bela. Ein Bewohner mit Knelt, der nicht manuselt, ist ein Cedi, wenn er immer<br />

nopelt. Wer keinen Knelt hat <strong>und</strong> löpst, nie nopelt <strong>und</strong> stets manuselt, ist mit Bestimmtheit ein Cedi;<br />

würde er nicht manuseln, wäre er ein Drudi. Es ist geradezu typisch für Drudis, dass sie weder manuseln<br />

noch nopeln, aber einen ordentlichen Knelt haben. Ganz enthaltsame Bewohner, die keinen<br />

Knelt haben, nicht löpsen <strong>und</strong> nicht nopeln, sind Drudis, wenn sie manuseln, <strong>und</strong> Cedis, wenn sie<br />

nicht manuseln.<br />

Ein Programm soll nun die vier Eigenschaften eines Sumpfbewohners erfragen ( Antwort J/N ) <strong>und</strong><br />

eine Diagnose liefern, zu welchem Stamm dieser gehört. Eine geschachtelte bedingte Anweisung, die<br />

genau der vorgegebenen Beschreibung folgt, löst das Problem.<br />

11.07.02<br />

19-übungen-verzw


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informations- <strong>und</strong> Arbeitsblatt Name :<br />

BEISPIEL KOMBINIERTE KONTROLLSTRUKTUREN TEIL 1<br />

20/25 Datum :<br />

Beispielaufgabe mit kombinierten Kontrollstrukturen:<br />

Zur Steuerung von Gleichstrom-Motoren sind Brückenschaltungen hervorragend geeignet. Man setzt die<br />

Gleichstrommotoren in deren Mitte <strong>und</strong> kann ohne großen Aufwand die Drehrichtungen ändern. Eine solche<br />

Schaltung, die zusätzlich vor späteren Softwarefehlern schützt, finden Sie in nachfolgender Skizze.<br />

D1..D4 = 1N4001<br />

D5, D6 = 1N4148<br />

T1 , T3 = BD242<br />

T2 , T4 = BD241<br />

T5 , T6 = BD140<br />

Ue1<br />

D5<br />

Die Transistoren T1, T3 ( PNP ) <strong>und</strong> T2, T4 ( NPN )<br />

bilden die Brückenschaltung, in deren Mitte der Motor<br />

sitzt. Die Dioden D1 bis D4 sind die Freilaufdioden<br />

für die Motorspule. D5 <strong>und</strong> D6 verhindern, dass<br />

bei falscher Ansteuerung nicht die beiden Komplemetär-Transistoren<br />

der Brücke durchsteuern; so wird<br />

ein Kurzschluss zwischen Gro<strong>und</strong> <strong>und</strong> Betriebsspannung<br />

vermieden. Die beiden Eingangstransistoren<br />

T5 <strong>und</strong> T6 sind PNP - Transistoren <strong>und</strong> interpretieren<br />

offene Eingänge als logisch High. Angesteuert<br />

werden sie über die Eingänge Ue1 <strong>und</strong> Ue2 mit logisch<br />

Low. Ue1 <strong>und</strong> Ue2 liegen am Datenregister der<br />

parallelen Schnittstelle auf den beiden niederwertigsten<br />

Bits ( Adressen : s.S. 17/25 ) .<br />

Aufgabe :<br />

Schreiben Sie ein <strong>Pascal</strong>-Programm, das die Drehrichtung des Gleichstrommotors mit den Tasten < R > für<br />

Rechtslauf, < L > für Linkslauf <strong>und</strong> < S > für Stopp steuern kann. Der Motor soll im Programm mehrfach umgeschaltet<br />

werden können. Der Abbruch des Programms soll über die ESCAPE - Taste erfolgen.<br />

Problemanalyse :<br />

Der Motor lauft im Rechtslauf, wenn Ue1 = high <strong>und</strong> Ue2 = low Pegel erhält. Steuerbyte : 0000 0001 = 1 dez.<br />

Der Motor lauft im Linkslauf, wenn Ue1 = low <strong>und</strong> Ue2 = high Pegel erhält. Steuerbyte : 0000 0010 = 2 dez.<br />

Der Motor steht, wenn Ue1 = high <strong>und</strong> Ue2 = high Pegel erhält. Steuerbyte : 0000 0011 = 3 dez.<br />

Die Escape-Taste ist im ASCII-Kode durch „ #27 “ definiert <strong>und</strong> kann über eine Variable eingelesen werden.<br />

Programmentwurf :<br />

Programm Drehrichtungssteuerung<br />

Deklaration<br />

Beginn<br />

Bildschirm löschen<br />

Ende<br />

T1 T3<br />

120<br />

Steuerleitungen für den Motor auf Stillstand setzen<br />

Überschrift ausgeben<br />

D1 D3<br />

Menue <strong>zur</strong> Steuerung ausgeben<br />

Auswahl einlesen<br />

wiederhole bis die Escape Taste betätigt wurde<br />

Schnittstellen Reset ( Motor Stillstand )<br />

M<br />

+5V .. +12 V<br />

2k7 2k7<br />

T2 D2 D4 T4<br />

2k7 2k7<br />

120 120<br />

Gro<strong>und</strong><br />

120<br />

Ist die Auswahl =<br />

R L<br />

S<br />

Steuerbyte "2" Steuerbyte "1" Steuerbyte "3"<br />

Rechtslauf Linkslauf Stopp<br />

D6<br />

Ue2<br />

Start<br />

Deklaration<br />

Bild schirm<br />

löschen<br />

Steuerleitu n g e n<br />

auf Reset<br />

Überschrift <strong>und</strong><br />

M enue ausgeben<br />

Auswahl<br />

einlesen<br />

W ahl ?<br />

R<br />

L<br />

S<br />

Steuerbyte R echtslauf<br />

ausgeben<br />

Steuerbyte Linkslauf<br />

ausgeben<br />

Steuerbyte S topp<br />

ausgeben<br />

nein<br />

Escape<br />

?<br />

Steuerleitu n g e n<br />

auf R eset<br />

Ende<br />

13.07.02<br />

20-beispiel-1


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informations- <strong>und</strong> Arbeitsblatt Name :<br />

BEISPIEL KOMBINIERTE KONTROLLSTRUKTUREN TEIL II<br />

21/25 Datum :<br />

Quelltext<br />

(**********************************************************************)<br />

(* Programm : Drehrichtungs-Steuerung *)<br />

(* Software : COMPILER <strong>Turbo</strong> <strong>Pascal</strong> 7.0 unter MS-DOS 6.22 *)<br />

(* Hardware : Pentium 133 MHz, VGA-Karte *)<br />

(* Ort/Datum : Hans-Böckler-Schule, 48155 Münster 11.07.02 *)<br />

(**********************************************************************)<br />

{ Dieses Programm steuert die Drehrichtung eines Motors über die }<br />

{ Leitungen Bit1 <strong>und</strong> Bit2 des Datenregisters der parallelen Schnitt- }<br />

{ stelle LPT2. }<br />

{ Der externe Motor sitzt in einer Brückenschaltung mit Transistoren }<br />

PROGRAM Drehrichtungs_Steuerung;<br />

USES CRT;<br />

CONST LPT = 632; (* Adresse LPT2 *)<br />

Zeitkonst = 3000; (* 3000 ms = 3 s *)<br />

VAR Eingabe : Char;<br />

BEGIN (* Hauptprogramm *)<br />

ClrScr;<br />

Port[LPT]:= 3; (* Bit1= 1 ; Bit2= 1 *)<br />

GotoXY(1,3); TextColor(6);<br />

WriteLn ('Drehrichtungssteuerung eines Motors');<br />

TextColor(7); WriteLn;<br />

WriteLn('Geben Sie bitte die gewünschte Steuerung an :');<br />

WriteLn;<br />

WriteLn('Rechtslauf < R >');<br />

WriteLn('Linkslauf < L >');<br />

WriteLn('Stopp < S >');<br />

Write ('Abbruch mit < ESC > ==> ');<br />

REPEAT<br />

Eingabe := ReadKey;<br />

CASE Eingabe OF<br />

'R','r' : BEGIN<br />

Port[LPT] := 1; (* Bit1= 1 ; Bit2= 0 *)<br />

GotoXY(1,13); ClrEol;<br />

WriteLn('Der Motor läuft nun im Rechtslauf.');<br />

GotoXY(33,11);<br />

END;<br />

'L','l' : BEGIN<br />

Port[LPT] := 2; (* Bit1= 0 ; Bit2= 1 *)<br />

GotoXY(1,13); ClrEol;<br />

WriteLn('Der Motor läuft nun im Linkslauf.');<br />

GotoXY(33,11);<br />

END;<br />

'S','s' : BEGIN<br />

Port[LPT] := 3; (* Bit1= 1 ; Bit2= 1 *)<br />

GotoXY(1,13); ClrEol;<br />

WriteLn('Der Motor steht nun.'); GotoXY(33,11);<br />

END;<br />

END;<br />

UNTIL Eingabe = #27; (* ASCII Nr.27≡Escape*)<br />

ClrScr; GotoXY(20,10); Textcolor(18);<br />

Write('That`s all folks ....');<br />

Port[LPT]:=3; (* Bit1= 1 ; Bit2= 1 *)<br />

END.<br />

11.07.02<br />

21-beispiel-2


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

ARRAYS / FELDER<br />

22/25 Datum :<br />

Information :<br />

Bei vielen Problemstellungen wäre eine Lösung nur sehr schwer <strong>und</strong> umständlich zu programmieren,<br />

wenn nur die einfachen Datentypen CHAR, REAL, INTEGER usw. <strong>zur</strong> Verfügung stünden. Deshalb<br />

bieten viele <strong>Programmiersprache</strong>n die Möglichkeit, aus den einfachen Datentypen weitere Datentypen<br />

zusammenzusetzen. Man nennt solche Datentypen strukturierte Datentypen. Je nachdem wie<br />

die neuen Datenstrukturen gebildet werden, unterscheidet man in <strong>Pascal</strong> zwischen<br />

• Feld : ARRAY ( Zusammenfassung mehrerer Elemente gleichen Datentyps )<br />

• Menge : SET ( bestimmte Anzahl von Elementen eines ordinalen Datentyps )<br />

• Satz : RECORD ( Zusammenfassung von Daten unterschiedlichen Datentyps )<br />

• Datei : FILE ( Folge von Sätzen, die meist die Struktur eines Records haben )<br />

Ziel : Hier soll zunächst nur der zusammengesetzte Datentyp ARRAY besprochen werden.<br />

Ein ARRAY – oft auch Feldvariable genannt – können Sie sich wie ein Regal mit vielen Fächern vorstellen.<br />

In jedem der Fächer kann ein Gegenstand gleichen Typs aufbewahrt werden. Dabei kann es<br />

vorkommen, dass die Fächer nicht nur nebeneinander, sondern in mehreren Reihen übereinander<br />

oder sogar zusätzlich noch hintereinander liegen. Wollen Sie nun jemanden beauftragen , einen Gegenstand<br />

zu holen, so bitten Sie ihn beispielsweise, den Gegenstand aus dem linken Fach in der<br />

zweiten Reihe von oben zu entnehmen.<br />

Um also auf eine Variable in einem Feld zuzugreifen, nennen Sie lediglich die Lage ( den Index ) im<br />

Feld. Dieser Index muss deshalb als Variable vorab deklariert werden. Natürlich muss das Feld selbst<br />

auch im Deklarationsteil vereinbart werden. Allgemein gilt für die Felddeklaration folgende Syntax :<br />

VAR < FeldBezeichner > : ARRAY [ < IndexAnfang > .. < IndexEnde > ] OF < Datentyp > ;<br />

Da wir hier nur einen einzigen Index verwenden, spricht man von einem eindimensionalen Feld -<br />

ähnlich einer einzigen Reihe von nebeneinander gelegenen Schubladen im Regal. Nur .., die Schubladen<br />

sind im Moment noch leer, denn die Felder wurden noch nicht gefüllt. Auf sie kann, durch einen<br />

in eckigen Klammern angegebenen Index, während der Laufzeit des Programms lesend oder schreibend<br />

zugegriffen werden.<br />

Daten aus der Tabelle lesen Daten in die Tabelle schreiben<br />

Wert := FeldBezeichner [ Index ] ; FeldBezeichner [ Index ] := Wert ;<br />

Sie können aber nicht nur ein dynamisches Array <strong>zur</strong> Laufzeit erzeugen, sondern bereits <strong>zur</strong> Entwurfszeit<br />

können die Einträge in eine Feldvariable erfolgen. Dazu muss das Array lediglich als typisierte<br />

Konstante deklariert werden, dem die Einträge (Items) sofort zugewiesen werden. Beispiel :<br />

CONST Woche : ARRAY [ 1.. 7 ] OF STRING = (’Montag’, ’Dienstag’, ’Mittwoch’ , ... , ’Sonntag’);<br />

Soll die Feldvariable außer Zeilen auch noch Spalten enthalten so spricht man von einem zweidimensionalen<br />

Feld, oft auch als Matrix oder Tabelle bezeichnet. Auch hier müssen die Elemente vom gleichen<br />

Datentyp sein; lediglich ein zweiter Index muss vereinbart werden, um sowohl die Zeile als auch<br />

die Spalte richtig adressieren zu können. Auch dreidimensionale <strong>und</strong> noch höherdimensionale Felder<br />

sind möglich, sprengen jedoch schnell die Speichergrenzen <strong>und</strong> können jenseits der drei Dimensionen<br />

nur noch sehr schwer verstanden werden. Mit dem Compilerbefehl { $R+ } können sie eine Bereichsüberprüfung<br />

einschalten, um zu verhindern, dass ein Zugriff über die Grenzen eines Feldes<br />

hinaus erfolgt. Die Deklaration <strong>und</strong> der Zugriff auf ein zweidimensionales Feld erfolgt wie im Beispiel:<br />

Deklaration Zugriff<br />

VAR Bezeichner : ARRAY [n..m, x.. y] OF WORD; Wert : = Bezeichner [ Index1, Index2 ];<br />

Ein mehrdimensionales Array kann auch anders deklariert werden; für welche Art Sie sich entscheiden<br />

bleibt Ihnen überlassen : VAR MyArray : ARRAY [ n..m ] OF ARRAY [ x..y ] OF DatenTyp;<br />

11.07.02<br />

22-arrays


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informations- <strong>und</strong> Arbeitsblatt Name :<br />

RECORDS BZW. VERBUND<br />

23/25 Datum :<br />

Eine Vereinigung von Daten unterschiedlichen Typs wird als Datensatz bezeichnet. <strong>Pascal</strong> kennt <strong>zur</strong><br />

Darstellung eines solchen Datensatzes den Datentyp Record - auch als Verb<strong>und</strong> bekannt, in dem<br />

sich viele unterschiedliche Datenfelder vereinen lassen. Im Gegensatz zum Array ( Feld ) können hier<br />

unterschiedliche Datentypen zu einer Einheit zusammengefasst werden. Die entstehenden Variablen<br />

nennt man deshalb Verb<strong>und</strong>- bzw. Recordvariable.<br />

Beispiel :<br />

Bei der Auswertung von Lottozahlen, die in einer Tippgemeinschaft spielen, muss sichergestellt sein,<br />

dass die einzelnen Tippreihen, die aus 6 Zahlen zwischen 1 <strong>und</strong> 49 bestehen, dem einzelnen Spieler<br />

zugeordnet werden können.<br />

Zunächst initiiert man daher eine Variable Spieler <strong>und</strong> deklariert sie als Record :<br />

VAR Spieler : Record<br />

Name : String[20];<br />

Tippreihe : Array[1..6] OF Byte;<br />

End;<br />

Der Zugriff auf die Einzeldaten im Record erfolgt über den<br />

Variablennamen <strong>und</strong> den Feldnamen, die durch einen<br />

Punkt, den sogenannten Qualifizierer, getrennt sind.<br />

Hier z. B.: WriteLn ( Spieler.Name );<br />

Es muss also ständig der Verb<strong>und</strong>variablen_Name <strong>und</strong> der Feld_Name angegeben werden, was mit<br />

viel Schreibarbeit verb<strong>und</strong>en ist. Deshalb gibt es in <strong>Pascal</strong> die Möglichkeit, die Schreibweise mittels<br />

der WITH-Anweisung abzukürzen <strong>und</strong> auf den Verb<strong>und</strong>variablen_Namen zu verzichten.<br />

In allgemeiner Form lautet die Anweisung :<br />

WITH Verb<strong>und</strong>variable DO<br />

Begin<br />

Anweisung_1;<br />

Anweisung_2;<br />

…;<br />

end;<br />

Für unseren Fall gilt:<br />

WITH Spieler DO<br />

Begin<br />

WriteLn ( Name );<br />

FOR n := 1 TO 6 DO<br />

Write ( Tippreihe [n] :6 );<br />

end;<br />

Da die Datensätze für alle Spieler der Tippgemeinschaft gleich sind, liegt es nahe, dass man die Spieler<br />

in einem eindimensionalen Feld ( Array ) zusammenfasst. Man bildet dafür eine zusammengesetzte<br />

Datenstruktur das :<br />

Array Spielergemeinschaft mit 1.. n Records<br />

Spieler 1<br />

Name<br />

Tippreihe<br />

Spieler 2<br />

Name<br />

Tippreihe<br />

Spieler 3<br />

Name<br />

Tippreihe<br />

Spieler n<br />

VAR Spielgemeinschaft : ARRAY [ 1 .. n ] OF Record<br />

Name : String[20];<br />

Tippreihe : Array [ 1.. 6 ] OF Byte;<br />

End;<br />

Name<br />

Tippreihe<br />

Der allgemeine Zugriff auf diese Datenstruktur erfolgt über Feldvariablen_Name[Index].Feld_Name<br />

Aufgabe : Entwickeln Sie eine Musteranwendung für eine Tippgemeinschaft mit 5 Spielern.<br />

Per Zufallsgenerator sollen für alle 5 Spieler die Tippreihen gezogen werden.<br />

Über ein Menue kann auf die Daten der Spieler zugegriffen werden.<br />

11.07.02<br />

23-records


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informations- <strong>und</strong> Arbeitsblatt Name :<br />

MENGEN ( SETS )<br />

24/25 Datum :<br />

Information:<br />

Interessanterweise gehören Mengen zu den <strong>Pascal</strong>-Strukturen, die am wenigsten eingesetzt werden.<br />

Das mag daran liegen, dass die Unterstützung von Mengen nur in <strong>Pascal</strong> unterstützt wird <strong>und</strong> in den<br />

meisten <strong>Programmiersprache</strong>n nicht. Der Begriff Menge oder Set stammt aus der Mengenlehre <strong>und</strong><br />

beschreibt eine Ansammlung von Daten des gleichen Typs, die als eine Einheit ( Teilmenge ) gesehen<br />

werden. Der Basisdatentyp aus dem die (Teil-)Menge gebildet wird muss ordinal sein, d.h., sie<br />

müssen abzählbar sein.<br />

So sind z.B. alle Großbuchstaben eine Menge der ASCII-Zeichen oder alle Ziffern zwischen 1 <strong>und</strong> 9<br />

eine Menge der Ganzzahlen bzw. wiederum eine Teilmenge der ASCII-Zeichen.<br />

Mengenwerte können nicht über die Tastatur eingegeben werden, sondern sie müssen per Anweisung<br />

gebildet werden. Die <strong>erste</strong> Möglichkeit besteht darin, die Elemente der Mengen zwischen eckigen<br />

Klammern anzugeben. Bei zusammenhängenden Bereichen genügt es das <strong>erste</strong> <strong>und</strong> letzte Element<br />

getrennt durch zwei Punkte anzugeben. Andere werden durch Kommata getrennt.<br />

Beispiele : [ ‘a‘ .. ‘z‘ ] oder [ ‘A‘, ‘E‘, ‘I‘, ‘O‘, ‘U‘ ] bzw. gemischt [ 0..9, 15,33,77 ] oder Leermenge [ ]<br />

Die zweite Möglichkeit ist die implizite Mengenverwendung. Als Beispiel möge die Benutzeroberfläche<br />

eines Programms in Form eines Menüs dienen. Die einzelnen Funktionen des Menüs können durch<br />

Tippen des Anfangsbuchstabens ausgelöst werden. Dabei dürfen natürlich nur ganz bestimmte<br />

Buchstaben eingegeben werden, anderenfalls soll die Eingabe wiederholt werden. Als zugelassene<br />

Buchstaben legen wir ( L)inks, (R)echts <strong>und</strong> (S)top sowie deren Kleinbuchstaben fest.<br />

VAR m:CHAR;<br />

....<br />

Repeat<br />

m:= ReadKey;<br />

until m IN [ ‘L‘, ‘R‘, ‘S‘, ‘l‘, ‘r‘, ‘s‘ ];<br />

...<br />

Mit <strong>Hilfe</strong> des logischen Operators „IN“ wird festgestellt, ob<br />

der Wert der Variablen m in der Menge enthalten ist. Das<br />

Ergebnis dieser Prüfung ist stets vom Typ Boolean, alsowahr<br />

(true) oder falsch (false). Alternative : ..NOT m IN ..<br />

Mengen können natürlich auch explizit deklariert werden. Dazu dient die folgende Anweisung :<br />

VAR : SET OF ;<br />

Dabei kann der Mengendatentyp ein einfacher<br />

Standarddatentyp, ein Teilbereichtstyp oder ein<br />

selbstdefinierter Typ sein.<br />

Beispiel :<br />

VAR Buchstabe : SET OF CHAR;<br />

....<br />

Buchstabe := [ ‘A‘ .. ‘Z‘ ];<br />

Beachten Sie bitte, dass die Variablen vom Typ Menge nicht ein Datum aus der Menge besitzen,<br />

sondern immer die gesamte Menge. Deswegen können Variablen vom Typ SET OF auch nicht direkt<br />

auf dem Bildschirm mit Write bzw. WriteLn ausgegeben werden. Die Kardinalität (Anzahl der Elemente)<br />

in einer Menge kann unter Extended <strong>Pascal</strong> mit anzahl:= card ( menge); ermittelt werden.<br />

Die Anzahl der zugeordneten Elemente im SET darf 256 nicht überschreiten !<br />

Auf Mengendatentypen können logische Operatoren angewendet werden, deren Operatoren, Operanten<br />

<strong>und</strong> Resultate wiederum Mengen sind. Z.B.: Durchschnitt / Schnittmenge (M1 * M2 → ODER);<br />

Vereinigungsmenge ( M1 + M2 → UND ); Teilmenge ( M1


Hans-<br />

Böckler-<br />

Schule<br />

Münster<br />

Programmiertechnik Klasse :<br />

Informationsblatt Name :<br />

EIGENE DATENTYPEN<br />

25/25 Datum :<br />

Information:<br />

Die wichtigsten Standard-Datentypen von <strong>Turbo</strong>-<strong>Pascal</strong> wurden bereits behandelt. Natürlich gibt es<br />

noch mehr ( Pointer, Object, Text, File usw. ) aber hier soll nur vorgestellt werden, wie man mit <strong>Hilfe</strong><br />

der TYPE-Vereinbarung im Deklarationsteil des Programms eigene Datentypen vereinbart <strong>und</strong> wozu<br />

das gut sein kann.<br />

Einschränkend muss natürlich darauf hingewiesen werden, dass neue Datentypen nur aus den von<br />

<strong>Pascal</strong> vordefinierten Datentypen, den daraus gebildeten Unterbereichen oder aus zusammengesetzten<br />

<strong>Pascal</strong>-Datentypen bestehen dürfen.<br />

allgemeine Deklaration : TYPE TypName : Definition; Beispiel : TYPE TJahr : 1990..2060; 1)<br />

1]<br />

Eine Variable vom Typ TJahr könnte demzufolge nur einen Wert zwischen 1990 <strong>und</strong> 2060 annehmen<br />

Um eine Verwechslung von neuen Datentypnamen mit Variablebezeichnern zu vermeiden, schlage<br />

ich vor, den neuen Datentypnamen ein „ T “ – für Typ – voranzustellen; also z.B. TJahr oder TFarbe;<br />

Hat man es mit Mengen zu tun ( 24/25 ), so machen selbstdefinierte Datentypen schnell Sinn, wenn<br />

man die Übersichtlichkeit des Quelltextes steigern möchte. Als Beispiel soll hier die Liste aller Tage<br />

einer Woche dienen :<br />

Datentypvereinbarung : TYPE TMyWeekDays = ( ’ Montag ’,’ Dienstag ’, .. ‚’ Sonntag ’ );<br />

Variablendeklaration : VAR Today, Birthday : TMyWeekDays;<br />

Zuweisung im Hauptprogramm : Birthday := ’Mittwoch’;<br />

Richtig wichtig werden eigene Datentypen aber immer dann, wenn man z.B. Records ( 23/25 ) als<br />

Parameter an Subroutinen übergeben muss. Innerhalb der Parameterliste erwarten die Unterprogramme<br />

ja nicht nur den Namen des formalen Parameters, sondern auch den dazugehörigen Datentyp;<br />

<strong>und</strong> im Prozedur- bzw. Funktionskopf können Sie hier keinen neuen Record mehr definieren.<br />

Problem :<br />

Angenommen, Sie haben aus einer Zahlenreihe alle Primzahlen isoliert <strong>und</strong> in eine vorab deklarierte<br />

Mengenvariable mit dem Namen PrimZahl übernommen. Diese Menge wollen Sie nun ausdrucken.<br />

Da wir aber nicht nur ein Datum in der Menge besitzen, sondern die gesamte Menge, können wir die<br />

Variable PrimZahl nicht direkt auf dem Bildschirm z.B. mit WriteLn(); ausgegeben. Was also tun ?<br />

Wir definieren zunächst ein Unterprogramm,<br />

das uns den Inhalt der als<br />

Parameter übergebenen Menge bis zu<br />

einer festen Obergrenze ausgibt.<br />

Wie man sieht, ist für den formalen Parameter<br />

der Menge im Prozedurkopf bereits<br />

ein neuer Datentyp definiert worden.<br />

Im Deklarationsteil des Hauptprogramms<br />

muss vorab der neue Datentyp <strong>und</strong> die<br />

dazugehörige Variable deklariert werden.<br />

Aufruf der Prozedur im Hauptprogramm Ausgabe ( PrimZahl );<br />

PROCEDURE Ausgabe ( Menge : TZahlen );<br />

VAR Z : Word;<br />

BEGIN<br />

FOR Z := 1 TO ObereGrenze DO<br />

IF Z IN Menge THEN<br />

Write(Z:3);<br />

END;<br />

CONST ObereGrenze = 200;<br />

TYPE TZahlen = SET OF 0 .. ObereGrenze;<br />

VAR PrimZahl : TZahlen;<br />

In <strong>Pascal</strong> besteht auch die Möglichkeit, Prozeduren <strong>und</strong> Funktionen als Typen zu deklarieren. Nach<br />

der Vereinbarung z.B. eines solchen Prozedurtyps können dann zugehörige Prozedurvariablen vereinbart<br />

werden. Einziges Problem : die Routinen, die solchen Prozedurvariablen zugewiesen werden,<br />

müssen vorab als FAR vereinbart werden. Das geschieht mit der Compilerdirektive { $F+ }.<br />

Beachten Sie, dass nur globale Routinen an die Prozedurvariablen übergeben werden können.<br />

Beispiel : TYPE TProzedurName = Procedure ( Parameter );<br />

11.07.02<br />

25-type

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!