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
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