Einführung in PL/1 für Wirtschaftswissenschaftler [3., neubearbeitete Auflage. Reprint 2018] 9783486782707, 9783486212143


193 47 12MB

German Pages 208 Year 1988

Report DMCA / Copyright

DOWNLOAD PDF FILE

Table of contents :
Inhaltsverzeichnis
1. Einführung
2. Berechnung und Ausgabe von arithmetischen Ausdrücken
3. Variablen und Wertzuweisung
4. Arithmetische Standardfunktionen
5. Steuerung des Programmablaufs
6. Zeichenketten
7. Steuerung der Ein-/Ausgabe
8. Gruppierungen von Datenelementen
9. Blöcke
10. Kapitel: Prozeduren
11. Programmunterbrechungen
Anhänge
Register
Recommend Papers

Einführung in PL/1 für Wirtschaftswissenschaftler [3., neubearbeitete Auflage. Reprint 2018]
 9783486782707, 9783486212143

  • 0 0 0
  • Like this paper and download? You can publish your own PDF file online for free in a few minutes! Sign Up
File loading please wait...
Citation preview

Einführung in

PL/1

für Wirtschaftswissenschaftler

Von

Dr. Klaus Werner Wirtz

Professor für Betriebswirtschaftslehre insbesondere Datenverarbeitung 3., neubearbeitete Auflage

R. Oldenbourg Verlag München Wien

CIP-Titelaufnahme der Deutschen Bibliothek Wirtz, Klaus Werner: Einführung in PL 1 für Wirtschaftswissenschaftler / von Klaus Werner Wirtz. - 3., neubearb. Aufl. - München ; Wien : Oldenbourg, 1989 ISBN 3 - 4 8 6 - 2 1 2 1 4 - 1

© 1989 R. Oldenbourg Verlag GmbH, München Das Werk außerhalb lässig und filmungen

einschließlich aller Abbildungen ist urheberrechtlich geschützt. Jede Verwertung der Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung des Verlages unzustrafbar. Das gilt insbesondere für Vervielfältigungen, Übersetzungen, Mikroverund die Einspeicherung und Bearbeitung in elektronischen Systemen.

Gesamtherstellung: Rieder, Schrobenhausen

ISBN 3-486-21214-1

Inhaltsverzeichnis

1. Kapitel: 1.1. 1.2.

D e r Prozeß der E n t w i c k l u n g eines Programms Darstellung von Algorithmen d u r c h S t r u k t o g r a m m e

2. Kapitel:

2.1. 2.2. 2.2.1. 2.2.2. 2.2.3. 2.3. 2.4. 2.5.

3.5.

Berechnung und Ausgabe von arithmetischen Ausdrücken

Der f o r m a l e A u f b a u eines P L / 1 - P r o g r a m m s Arithmetische A u s d r ü c k e Arithmetische K o n s t a n t e n Arithmetische O p e r a t o r e n A u s w e r t u n g von arithmetischen A u s d r ü c k e n Ausgabe von Ergebnissen mit d e m PUT L I S T - B e f e h l . . . . Zeichenketten-Konstanten Übungen

3. Kapitel: 3.1. 3.2. 3.3. 3.4.

Einführung

Variablen und Wertzuweisung

Der Begriff der Variablen N a m e n , T y p e n und Wertebereiche von Variablen Wertzuweisung Einlesen von Werten in Variable mit dem GET L I S T Befehl Übungen

11 11 17

24 24 25 26 27 28 29 32 33

34 34 35 39 42 45

4. Kapitel:

Arithmetische Standardfunktionen

47

5. Kapitel:

Steuerung des Programmablaufs

50

5.1. 5.2. 5.2.1. 5.2.2.

Sequenz von A n w e i s u n g e n Die DO-Anweisung zur Iteration Die DO-Anweisung als L a u f a n w e i s u n g Die DO-Anweisung mit Bedingung

50 50 53 58

6

Inhaltsverzeichnis

5.2.2.1. 5.2.3. 5.3. 5.3.1. 5.3.2. 5.4.

F o r m u l i e r u n g von B e d i n g u n g e n : V e r g l e i c h s o p e r a t o r e n u n d logische V e r k n ü p f u n g s o p e r a t o r e n S c h a c h t e l u n g von D O - A n w e i s u n g e n Die I F - A n w e i s u n g zur E n t s c h e i d u n g S c h a c h t e l u n g von I F - A n w e i s u n g e n Anweisungsgruppen Übungen

6. Kapitel: 6.1. 6.2. 6.2.1. 6.2.2. 6.3.

Zeichenketten-Variablen V e r a r b e i t u n g von Z e i c h e n k e t t e n Verkettung Standardfunktionen f ü r Zeichenketten Übungen

7. Kapitel: 7.1. 7.2. 7.3.

Steuerung der E i n - / A u s g a b e

DATA-gesteuerte Ausgabe EDIT-gesteuerte Ein-/Ausgabe Übungen

8. Kapitel: 8.1. 8.1.1. 8.1.2. 8.1.3. 8.1.4. 8.1.5. 8.2. 8.2.1. 8.2.2. 8.2.3. 8.2.4. 8.3. 8.4.

Zeichenketten

Gruppierungen von Datenelementen

Bereiche V e r e i n b a r u n g von Bereichen O p e r a t i o n e n mit Bereichen Unterbereiche E i n - / A u s g a b e von Bereichen S t a n d a r d f u n k t i o n e n f ü r Bereiche Strukturen V e r e i n b a r u n g von S t r u k t u r e n Z u g r i f f auf S t r u k t u r e l e m e n t e O p e r a t i o n e n mit S t r u k t u r e n E i n - / A u s g a b e von S t r u k t u r e n Bereiche von S t r u k t u r e n Übungen

60 63 66 69 70 71

74 74 75 78 81 87

90 90 92 101

102 102 103 105 108 109 110 116 118 119 121 122 126 126

Inhaltsverzeichnis

9. Kapitel:

9.1. 9.2. 9.3.

BEGIN-Blöcke Das Block-Konzept Übungen

10. Kapitel:

10.1. 10.2. 10.2.1. 10.2.2. 10.2.3. 10.2.4. 10.2.5. 10.3. 10.4. 10.5.

Prozeduren

Unterprogramme und Funktionen Interne Unterprogramme Vereinbarung von internen Unterprogrammen A u f r u f von internen Unterprogrammen Argumente und Parameter Bereiche und Strukturen als Argumente Die RETURN-Anweisung Externe Unterprogramme Funktionen Übungen

11. Kapitel:

11.1. 11.2. 11.2.1. 11.2.2. 11.2.3. 11.2.4. 11.3.

Blöcke

Programmunterbrechungen

Gründe f ü r Programmunterbrechungen ON-Einheiten Dateiende (ENDFILE) Division durch Null ( Z E R O D I V I D E ) Datenumwandlungsfehler (CONVERSION) Sonstige Unterbrechungen Übungen

Anhänge

AI. A2. A2.1. A2.2. A2.2.1. A2.2.2. A2.3.

7

131

132 135 137

141

141 142 143 144 146 152 154 156 157 160

162

162 163 164 167 168 169 170

171

Der PL/1 -Zeichensatz Typ und Genauigkeit von Ergebnissen arithmetischer Ausdrücke Festlegung des Typs von Ergebnissen Festlegung der Genauigkeit von Ergebnissen Festpunktoperanden Gleitpunktoperanden Beispiele

171 173 174 174 174 176 176

8

Inhaltsverzeichnis

A3. A3.1. A3.2. A3.3. A3.4. A3.5. A4. A5.

Größere Übungsaufgaben Produktionsplanung Versicherungsagentur Textformatierung Benzinverbrauch Vertreterumsätze Lösungshinweise und Lösungen zu ausgewählten Übungen Literaturverzeichnis

Sachregister

179 179 181 183 187 188 190 205 206

Vorwort (zur ersten bis dritten Auflage) Das vorliegende Buch ist aus Lehrveranstaltungen e n t s t a n d e n , die der A u t o r von 1977 bis 1986 an der Universität Essen - G e s a m t hochschule d u r c h g e f ü h r t hat. Es setzt keine P r o g r a m m i e r k e n n t n i s s e beim Leser voraus; nützlich sind j e d o c h G r u n d k e n n t n i s s e über a u tomatisierte D a t e n v e r a r b e i t u n g , wie sie etwa in Veranstaltungen zur E i n f ü h r u n g in die D a t e n v e r a r b e i t u n g oder aus e n t s p r e c h e n d e n L e h r b ü c h e r n (einige sind im Literaturverzeichnis g e n a n n t ) e r w o r b e n werden können. Die Programmiersprache P L / 1 existiert seit 1965. Sie w u r d e mit dem Ziel konzipiert, f ü r möglichst viele A u f g a b e n s t e l l u n g e n e i n setzbar zu sein; daher weist sie einen sehr großen S p r a c h u m f a n g a u f , der im R a h m e n eines E i n f ü h r u n g s t e x t s nicht k o m p l e t t b e h a n delt werden kann. In diesem Buch wird eine auf kommerzielle P r o bleme zugeschnittene U n t e r m e n g e der Sprache vermittelt. Der A u f b a u des Buchs ist so angelegt, d a ß es z u m Selbststudium geeignet ist. Die einzelnen Kapitel beginnen d u r c h w e g mit einer F o r m u l i e r u n g des Lernziels; auf den darstellenden Teil folgen Ü b u n g s a u f g a b e n , in d e n e n die behandelten Sprachelemente durch A n w e n d u n g v e r t i e f t w e r d e n . Zahlreiche Programmbeispiele im Text erleichtern das Verständnis des Inhalts. P r o g r a m m i e r e n , gleich in welcher Programmiersprache, ist im w e sentlichen eine praktische Tätigkeit und kann nicht d u r c h L i t e r a turstudium allein erlernt werden. Die Bearbeitung von Ü b u n g s a u f gaben ist daher sehr wichtig f ü r den L e r n e r f o l g . Ein in P L / 1 c o dierter Algorithmus k a n n in diesem Z u s a m m e n h a n g noch nicht als Lösung gelten; erst d e r Ablauf eines Programms auf einer D a t e n verarbeitungsanlage zeigt, ob das Programm das t u t , was von ihm erwartet wird. Bei diesem "Testen" von P r o g r a m m e n wird von Fall zu Fall neben diesem Buch das P L / 1 - H a n d b u c h des Ü b e r s e t z e r h e r stellers heranzuziehen sein, um Detailfragen zu klären. Vor allem ist im Text gelegentlich von "implementierungsabhängigen" E i g e n s c h a f ten der Sprache P L / 1 die Rede; das sind Dinge, die j e d e r Hersteller selbst festlegen kann. Die in diesem Buch a b g e d r u c k t e n Programme w u r d e n f ü r die erste A u f l a g e auf den Datenverarbeitungsanlagen P R I M E 4 0 0 / 7 5 0 des H o c h s c h u l r e c h e n z e n t r u m s Essen und T R 4 4 5 des H o c h s c h u l r e c h e n zentrums Düsseldorf gerechnet. Für die dritte A u f l a g e w u r d e n eini-

10

Vorwort

ge P r o g r a m m e auf d e n S i e m e n s - G r o ß r e c h n e r des H o c h s c h u l r e c h e n zentrums Düsseldorf übertragen. Ein a n d e r e r Teil d e r Programme w u r d e a u ß e r d e m mit d e m Digital Research P L / 1 - Ü b e r s e t z e r auf einem Personal C o m p u t e r implementiert. Dieser P L / 1 - Ü b e r s e t z e r macht eine U n t e r m e n g e der P L / 1 - S p r a c h e auch f ü r P C - B e n u t z e r v e r f ü g b a r ; er enthält allerdings nicht alle Sprachelemente, die in diesem Buch b e h a n d e l t werden. Während in der zweiten Auflage des Buchs verschiedene E r r a t a der ersten A u f l a g e v e r m e r k t w u r d e n , w u r d e f ü r die dritte A u f l a g e der gesamte Text inhaltlich überarbeitet und in eine lesefreundlichere F o r m gebracht. Abschließend d a n k e ich den Personen, ohne d e r e n Hilfe und U n t e r stützung dieses Buch nicht oder nicht in dieser Form entstanden wäre: Herrn Prof. Dr. D. Seibt, in dessen Fachgebiet B e t r i e b s i n f o r m a t i k / O p e r a t i o n s Research im Fachbereich Wirtschaftswissenschaften der Universität Essen - Gesamthochschule ich von 1977 bis 1980 als Wissenschaftlicher Mitarbeiter b e s c h ä f t i g t war; Herrn Prof. D i p l . - I n f . R. Senger (Fachhochschule K a r l s r u h e ) , der während seiner Tätigkeit als L e h r b e a u f t r a g t e r in Essen d e n A u f b a u der diesem Buch zugrundeliegenden Lehrveranstaltungen mitgeprägt hat; Herrn D i p l . - K f m . T. Bauer (Universität H o h e n h e i m ) , dem ich zahlreiche A n r e g u n g e n verdanke; Frau K. Eggert, Frau B. E m m e r i c h , Frau I. Siebert und Frau E. Vorholt, die verschiedene E n t w i c k l u n g s s t u f e n des Manuskripts d e r ersten Auflage geschrieben haben; und nicht zuletzt Herrn D i p l . - V o l k s w . M. Weigert vom Oldenbourg Verlag, der die E n t w i c k l u n g u n d Herstellung des Buchs unterstützt hat.

Klaus Werner Wirtz

1. Einführung Lernziel: Ziel dieses e i n f ü h r e n d e n Kapitels ist, den Prozeß der E n t w i c k l u n g von Programmen kurz darzustellen. Es zeigt sich, d a ß d e r Teil d i e ses Prozesses, in d e m die Programmiersprache P L / 1 (oder eine a n dere Sprache) zur A n w e n d u n g gelangt, nur einer von m e h r e r e n a b grenzbaren Arbeitsvorgängen ist, die teils nacheinander, teils p a r a l lel ablaufen. Deshalb wird diesen anderen Entwicklungsphasen, die in den folgenden Kapiteln nicht mehr behandelt w e r d e n , hier b e sondere A u f m e r k s a m k e i t gewidmet.

1.1. Der Prozeß der Entwicklung eines Programms U n t e r einem Programm f ü r eine Datenverarbeitungsanlage versteht man eine A r b e i t s v o r s c h r i f t , mit der ein Problem oder eine Klasse von irgendwie ähnlichen Problemen gelöst wird. Der Prozeß der Programmentwicklung beginnt also mit einer P r o blemerkennung. Ein Problem kann z.B. sein, die Lösungen der q u a dratischen G l e i c h u n g 4x2 + 8x + 3 = 0 zu f i n d e n ; eine Klasse von ähnlichen Problemen stellt die M e n g e der quadratischen Gleichungen ax2 + bx + c = 0 dar, die alle nach einem einheitlichen Schema gelöst werden k ö n n e n . Ein anderes Problem ist, aus f r ü h e r e n Umsatzwerten eines Betriebs z u k ü n f t i g erwartete Umsatzwerte zu prognostizieren. Dieses Problem ist o f f e n b a r wesentlich ungenauer f o r m u l i e r t als das erste. U n k l a r ist vor allem, - welcher Art die vorliegenden Vergangenheitswerte sind (z.B. M o n a t s - , Jahreswerte), - wieviele Werte vorliegen, - wieviele Werte vorausgesagt werden sollen, und - welches statistische V e r f a h r e n anzuwenden ist. Solange diese Fragen nicht beantwortet sind, ist an eine Bearbeitung des Problems - ob manuell oder mit H i l f e einer D a t e n v e r a r b e i t u n g s anlage - nicht zu denken. An die P r o b l e m e r k e n n u n g schließt sich also eine Problemanalvse an, die zum Ziel hat, möglichst alle zur

12

1. K a p i t e l : E i n f ü h r u n g

Bearbeitung des Problems erforderlichen Informationen zusammenzustellen und zu entscheiden, ob das Problem grundsätzlich lösbar ist. Auf die Problemanalyse folgt - manchmal ohne erkennbaren Ü b e r gang - die Suche nach einem Lösungsweg. Ein solches Verfahren zur Lösung kann sehr einfach zu finden sein; f ü r das Problem der quadratischen Gleichungen z.B. entdeckt man in einer Formelsammlung folgendes Verfahren: 1) a muß ungleich Null sein (sonst liegt keine quadratische Gleichung vor). o 2) b - 4 a c muß größer oder gleich Null sein (sonst gibt es komplexe Lösungen, die hier nicht interessieren). 3) Liegen diese Voraussetzungen vor, dann ergeben sich die Lösungen x-^ und X2 nach der Formel b 1 x-jy2 = ~ 2a ± 2a * W u r z e l a u s ( b 2 - 4 a c ) Damit ist der Lösungsweg bereits beschrieben. Ein solches V e r f a h ren bezeichnet man als Algorithmus. An einen Algorithmus werden folgende Anforderungen gestellt: - Er muß einen Anfang und mindestens ein Ende haben. Unser Algorithmus hat drei mögliche Enden: nach Schritt 1 und 2 im Fehlerfall, nach Schritt 3 im "Normalfall". - Er muß nach einer endlichen Zahl von Schritten zu einem Ende kommen. Oben sind es entweder ein, zwei oder drei Schritte. - Er muß ein oder mehrere Ergebnisse haben. Ergebnisse des obigen Algorithmus sind: "Es liegt keine quadratische Gleichung vor" oder "Die Lösungen sind komplex" oder "Die Lösungen sind reell und betragen x-^ und X2". -

Er muß - wenn nötig - Eingabewerte zulassen. Unser Algorithmus braucht im konkreten Fall Zahlenwerte f ü r a , b und c . Er muß eindeutig sein, d.h. mehrmaliges Ausführen des Algorithmus mit den gleichen Eingabewerten muß stets gleiche E r gebnisse liefern. Dies ist bei dem obigen Algorithmus gewährleistet.

Nicht immer kann der komplette Lösungsweg aus einer Formelsammlung einfach abgeschrieben werden. Sehr oft stellt das Finden eines geeigneten Algorithmus einige Anforderungen an den Einfallsreichtum und die Kreativität des Bearbeiters. Große und komplizierte Algorithmen werden der Übersichtlichkeit wegen oft in

1. Kapitel: G i n f ü h r u n g

13

F o r m von grafischen Darstellungen anschaulich gemacht. In diesem Buch werden dazu die sogenannten Struktogramme v e r w e n d e t , d e ren A u f b a u und G e b r a u c h im nächsten Abschnitt beschrieben wird. Soll ein Algorithmus automatisch in einer Datenverarbeitungsanlage a b l a u f e n , m u ß er in einer dieser Anlage verständlichen Sprache f o r muliert w e r d e n . Den Vorgang der Umsetzung eines n o r m a l s p r a c h lich oder in einer G r a f i k f o r m u l i e r t e n Algorithmus nennt m a n C o dierung; eine f ü r Datenverarbeitungsanlagen geeignete Sprache heißt Programmiersprache. Es gibt zahlreiche Programmiersprachen; eine davon ist die Sprache P L / 1 , die Gegenstand dieses Buches ist. Der Vorgang der Codierung ist - im Gegensatz zu dem eher kreativen Prozeß der L ö s u n g s f i n d u n g - ein m e h r formaler Prozeß, da s c h w e r p u n k t m ä ß i g auf die Regeln der Programmiersprache zu achten ist. Nach Beendigung der Codierung liegt ein Programm vor. Der P r o zeß der Programmentwicklung ist damit jedoch noch nicht a b g e schlossen, da sich an verschiedenen Stellen Fehler eingeschlichen haben können: - Im Programm können Verstöße gegen die Syntax der P r o g r a m miersprache enthalten sein. - Im Verlauf der Problemanalyse, der Lösungsfindung oder d e r Codierung können Irrtümer a u f g e t r e t e n sein, die zur Folge h a ben, d a ß das Programm nicht die nach der Problemstellung zu e r w a r t e n d e n Ergebnisse liefert. Ein Programm, das u.a. eine M e h r w e r t s t e u e r von 14 % e r r e c h n e n soll und zu einem Betrag von 100 als Mehrwertsteuer den Wert 1,40 ausgibt, mag s y n t a k tisch richtig sein, inhaltlich ist es jedoch falsch. Solche Fehler müssen g e f u n d e n und behoben werden, bevor ein Programm als fertig gelten kann. Verstöße gegen die Syntax d e r Programmiersprache werden automatisch vom Übersetzer e r k a n n t . Der Übersetzer ist ein - üblicherweise vom Hersteller der D a t e n v e r arbeitungsanlage zur V e r f ü g u n g gestelltes - Programm, das die A n weisungen des Programms auf syntaktische Richtigkeit p r ü f t und in Befehle der Maschinensprache überträgt. Inhaltliche Fehler k ö n n e n nicht automatisch e r k a n n t w e r d e n , da der Übersetzer keine K e n n t nis von d e m zu lösenden Problem hat; er kann nur f o r m a l e P r ü f u n gen v o r n e h m e n . Nach inhaltlichen Fehlern sucht man, i n d e m man das P r o g r a m m mit Eingabewerten a b l a u f e n läßt, f ü r die die E r g e b nisse bekannt sind. A b w e i c h u n g e n zwischen diesen Ergebnissen u n d den Ausgabewerten des Programms deuten auf inhaltliche Fehler hin.

14

1. Kapitel: Einführung

Den Vorgang der Fehlersuche und -behebung nennt man Test: die Daten, die zum Ausprobieren eines Programms benutzt werden, heißen Testdaten. Testen ist ein Prozeß, der üblicherweise mehrmals durchlaufen wird: Findet man einen Fehler, sucht man seine U r sache und behebt sie; danach wird das Programm erneut ausprobiert. Zeigt sich wieder ein Fehler, wird dessen Ursache gesucht und behoben; ein neuer Testlauf schließt sich an, usw. Die Problematik des Programmtestens besteht darin, daß man stets nur eine kleine Menge der insgesamt möglichen Eingabedaten im Test ausprobieren kann; die Richtigkeit eines Programms kann also nicht endgültig bewiesen werden. In der Praxis kommt es denn auch häufig vor, daß nach Jahren der Benutzung eines Programms immer noch Fehler gefunden werden, die durch vorher nie aufgetretene, aber zulässige Konstellationen von Eingabedaten ans Tageslicht kommen. Zwei Empfehlungen f ü r die Suche nach inhaltlichen Fehlern lauten: 1) Möglichst viele verschiedene Kombinationen von Eingabedaten, die auch Sonderfälle und Grenzwerte des Algorithmus a b decken, ausprobieren. Für den Algorithmus zur Lösung der quadratischen Gleichung bedeutet das, auch Eingabedaten, die keine quadratische Gleichung beschreiben, und solche, die zu komplexen Lösungen führen, vorzusehen. 2) Mit der inneren Einstellung, Fehler finden zu wollen, an den Test herangehen. Dies klingt trivial; hat man ein Programm selbst entwickelt, ist man jedoch oft von seiner Richtigkeit völlig überzeugt und hat deshalb Schwierigkeiten, Fehler als Fehler zu erkennen. (Aus diesem Grund überträgt man in der Praxis häufig das Testen eines Programms nicht dem Ersteller, sondern einer anderen Person, da das Aufdecken von Fehlern, die ein anderer begangen hat, leichter fällt!) Nach Abschluß der Testphase ist das Programm fertig. Eine sehr wichtige Aktivität wurde jedoch bisher noch nicht erwähnt, da sie parallel zu allen anderen Tätigkeiten ausgeführt wird: die Dokumentation. Ziel der Dokumentation ist, alle Unterlagen bereitzustellen, die zur Nutzung des Programms, zum Verständnis der Programmergebnisse und f ü r spätere Programmänderungen notwendig sind. Dazu reicht der Text des Programms oft nicht aus. Bestandteile einer Dokumentation können sein: - Die Formulierung des Problems, das das Programm löst, - Die Darstellung des Lösungswegs, - Der kommentierte Programmtext,

1. Kapitel: Einführung

15

- Testdaten und Ergebnisse von Programmläufen. Die ersten beiden und der letzte Punkt sind wohl einsichtig; wie ein Programmtext verständlich aufgebaut und kommentiert wird, wird in den folgenden Kapiteln anhand von Beispielen erläutert. Die E r fahrung zeigt, daß sogar der Autor eines Programms Schwierigkeiten hat, sich nach einiger Zeit zu erinnern, was das Programm tut und wie es das tut, wenn ihm nur der nackte Programmtext vorliegt.

Abb. 1.1. Der Prozeß der Programmentwicklung Die Phasen - Problemerkennung,

16

1. K a p i t e l : E i n f ü h r u n g

- Problemanalyse, - E n t w i c k l u n g eines Algorithmus, - Codierung, und - Test l a u f e n also n a c h e i n a n d e r ab. Alle Phasen tragen etwas zur D o k u mentation bei. Fehler, die im Test a u f t r e t e n , werden auf ihren U r sprung hin untersucht: falsches Problemverständnis, Irrtümer bei d e r E n t w i c k l u n g des Algorithmus, Ungenauigkeiten bei der Codierung können Fehlerursachen sein. In Abhängigkeit von der Phase, in der der Fehler w u r z e l t , müssen eventuell mehrere Arbeitsvorgänge w i e derholt w e r d e n . Dieser A b l a u f ist zugeschnitten auf die Zwecke des vorliegenden Buchs: Ein einzelner Leser soll lernen, relativ kleine, überschaubare P r o g r a m m i e r p r o b l e m e zu bearbeiten. Die daraus entstehenden P r o g r a m m e w e r d e n im allgemeinen nicht unmittelbar praktisch einsetzbar sein; sie haben bloßen Ü b u n g s c h a r a k t e r . In der betrieblichen Praxis l a u f e n g r o ß e P r o g r a m m e n t w i c k l u n g s p r o j e k t e in vieler H i n sicht anders ab; Unterschiede ergeben sich vor allem aus: - Der T r e n n u n g zwischen Entwicklern und A n w e n d e r n eines P r o gramms. P r o g r a m m e werden meist in der D a t e n v e r a r b e i t u n g s a b teilung entwickelt; angeregt und angewendet werden sie meist von einer Fachabteilung. Die Phasen der P r o b l e m e r k e n n u n g und der Problemanalyse werden daher o f t von Fachspezialisten aus der Fachabteilung und von Datenverarbeitungsspezialisten g e meinsam d u r c h g e f ü h r t . Damit die Fachabteilung das entwickelte P r o g r a m m selbständig nutzen kann, sind auch an die D o k u m e n tation besondere A n f o r d e r u n g e n zu stellen. - Der G r ö ß e eines betrieblichen Projekts. Reale P r o j e k t e sind o f t so u m f a n g r e i c h , d a ß ein Einzelner mit ihrer Bearbeitung ü b e r f o r d e r t wäre. Folglich werden solche Projekte von A r b e i t s g r u p pen abgewickelt, wobei sich Probleme der Arbeitsteilung und der Projektorganisation und -lenkung ergeben. - Der N o t w e n d i g k e i t , parallel zur E n t w i c k l u n g der Programme o r ganisatorische Konsequenzen der E i n f ü h r u n g der Programme zu e r k e n n e n u n d diese Umstellungen vorzubereiten. Hier sind F r a gen d e r Ä n d e r u n g von Arbeitsabläufen, der Neufestlegung von Arbeitsinhalten und der Schulung von späteren Benutzern der P r o g r a m m e angesprochen. - Der "Lebensdauer" von Programmen. Einmal entwickelte P r o g r a m m e haben eine durchschnittliche Einsatzdauer von sieben bis zehn J a h r e n . In diesem Zeitraum ä n d e r n sich h ä u f i g die A n f o r d e r u n g e n an die Programme, so d a ß die Ä n d e r u n g und Weiter-

1. Kapitel: Einführung

17

entwicklung bestehender Programme zu einem wesentlichen A u f wandsfaktor werden. Abschließend sei noch einmal betont, daß der Schwerpunkt des v o r liegenden Buchs eindeutig in der Codierphase liegt. Fragen der P r o blemanalyse und des Testens von Programmen werden mehr am R a n d e im R a h m e n der vorgestellten Programmbeispiele behandelt; eine gewisse Fertigkeit in diesen Arbeiten erlangt der Leser, wenn er möglichst viele der j e d e m Kapitel angefügten Ü b u n g s a u f g a b e n programmiert und auf einer Datenverarbeitungsanlage testet.

1.2. Darstellung von Algorithmen durch Struktogramme Ein Algorithmus, wie der im vorigen Abschnitt zur Lösung von quadratischen Gleichungen a n g e f ü h r t e , besteht aus einzelnen Schritten, die in einer bestimmten Reihenfolge hintereinander a u s g e f ü h r t werden. U m diese Reihenfolge deutlich zu machen, wird dieser Beispielalgorithmus noch einmal in leicht veränderter Form dargestellt: 1) 2)

Nimm Werte f ü r a , b und c . Wenn a ungleich Null ist, fahre bei 3) fort; sonst beende das V e r f a h r e n , weil keine quadratische Gleichung vorliegt.

3) 4)

Berechne b 2 - 4 a c . 2 Wenn b - 4 a c größer oder gleich Null ist, f a h r e bei 5) fort; sonst beende das Verfahren, weil komplexe Lösungen a u f t r e t e n . Berechne b 1 x 1 = - 2a + 2a * Wurzel aus (b2 - 4ac)

5)

6)

Berechne x2

7)

= -

b 2a



-

1 2a



* Wurzel

aus

(b

?

-

4ac)

G i b x-^ und x 2 aus.

Durch diesen Algorithmus werden drei verschiedene Reihenfolgen (Wege) beschrieben, von denen im konkreten Fall jeweils nur eine zur A u s f ü h r u n g kommt: - Ist a gleich Null, werden die Schritte 1 und 2 ausgeführt. o - Ist a ungleich Null und b - 4 a c kleiner Null, werden die Schritte 1 bis 4 ausgeführt. - Ist a ungleich Null und b - 4 a c größer oder gleich Null, werden die Schritte 1 bis 6 ausgeführt.

18

1. Kapitel: Einführung

Die Schritte 2 und 4 enthalten sogenannte Entscheidungen, die die weitere Reihenfolge steuern. Die anderen Schritte laufen ohne weiteres hintereinander ab, genauer: - Auf Schritt 1 folgt auf jeden Fall Schritt 2. - Auf Schritt 3 folgt auf jeden Fall Schritt 4. - Auf Schritt 5 folgt unbedingt Schritt 6. Solche Teile eines Algorithmus, die linear hintereinander ausgeführt werden, nennt man Sequenzen. Ein einzelner Arbeitsschritt, der keine Entscheidung enthält, wird grafisch in einem Rechteck abgebildet:

Berechne

x

b = - — + 1 2a

1 / — \/b v 2a

2

-

4ac

Abb. 1.2. Anweisungssymbol Eine Seouenz von Schritten wird durch mehrere untereinander stehende Rechtecke gleicher Breite dargestellt: Berechne

x

Berechne

x

1

2

= -b + ± 2a 2a =

_ b 2a

1

2a

\

A2_

4ac

A2_

4ac

V

\

V

Abb. 1.3. Sequenz Ein Arbeitsschritt, der eine Entscheidung enthält, wird in folgendem Symbol abgebildet:

Abb. 1.4. Entscheidungssymbol

1. Kapitel: Einführung

19

Das auf der Spitze stehende Dreieck enthält die Frage, die den weiteren Ablauf steuert. Diese Frage lautet bei Schritt 2: "Ist a ungleich Null?". Bei Schritt 4 heißt sie: "Ist b 2 - 4 a c größer oder gleich

^ Ja

k>2 -- 4 a c g r ö ß e r o d e r ^ ^ ^ ^ ^ gleich 0 ? ^ ^ ^ ^ Nein

Abb. 1.5. Beispiele zum Entscheidungssymbol In die unterhalb der Worte "Ja" und "Nein" stehenden Rechtecke werden dann die Schritte eingetragen, die ausgeführt werden, wenn die Frage bejaht bzw. verneint wird. Innerhalb eines solchen J a oder Nein-Zweigs kann also eine Sequenz von Schritten, aber auch eine weitere Entscheidung stehen. Mehrere Symbole können zu größeren Einheiten zusammengesetzt werden. Alle sechs Schritte des obigen Algorithmus sind in Abbildung 1.6. zu einer Gesamtdarstellung, einem sogenannten Struktogramm. zusammengefaßt. Die drei alternativen Wege, die in dem Algorithmus stecken, werden in der Abbildung gut sichtbar durch die drei Ausgänge, die das Struktogramm nach unten hat. Festzuhalten ist: - Weder die absolute Größe der einzelnen Symbole, noch das Verhältnis der Seitenlängen zueinander liegen fest. - Die Symbole können ineinander verschachtelt werden.

20

1. K a p i t e l : E i n f ü h r u n g

Nimm Werte für a, b und c Ja Berechne

~

— —

a ungleich

OJP^^^fj^

b2-4ac

Gib größer o d e r ^ ^ 'Keine ^ ^ ^ ^ ^ gleich 0? ^ ^ . quadratische Ja ^ ^ Nein Gleichung' aus Berechne x = Gib -b/2a + 'Komplexe (l/2a) \J b2-4ac Lösungen' aus Berechne x 2 = -b/2a (l/2a) \J b2-4ac Gib x , x^ aus 1' 2 Abb. 1.6. S t r u k t o g r a m m "Lösung einer quadratischen Gleichung" Ein drittes Konstruktionselement f ü r Struktogramme wird benötigt, wenn d e r A l g o r i t h m u s f ü r quadratische Gleichungen so erweitert wird, d a ß er f ü r beliebig viele Wertetripel ( a , b , c ) die Lösungen der zugehörigen quadratischen Gleichungen berechnet. Dies g e schieht, indem d e r oben formulierte Algorithmus um einen A n fangsschritt 0 ergänzt wird, der lautet: 0)

Wiederhole die Schritte 1 bis 7, solange Werte f ü r a , b und vorliegen.

c

Das dritte Konstruktionselement bezeichnet also Wiederholungen. Die Anzahl der Wiederholungen wird d a d u r c h begrenzt, d a ß j e d e Wiederholung d e r Schritte 1 bis 7 zur Bedingung hat, d a ß noch Werte f ü r a , b und c vorliegen. Sobald das E n d e der Eingabewerte erreicht ist, b r i c h t die Wiederholung ab.

1. Kapitel: E i n f ü h r u n g

21

Das Symbol f ü r eine Wiederholung hat folgendes Aussehen:

Wiederhole, solange Bedingung gilt zu wiederholende

Schritte

Abb. 1.7. Wiederholungssymbol Der wiederholt ablaufende Algorithmus für quadratische Gleichungen stellt sich also so dar:

Wiederhole, solange Werte vorhanden Nimm Werte für a, b und c Ja

aungleichO^?__—üein

Berechne b 2 -4ac Gib 'Keine größer oder gleich 0? ^ ^ . quadratische Ja ^ ^ Nein Gleichung' aus Gib Berechne x = -b/2a + 'Komplexe (l/2a) \ J b2-4ac Lösungen' aus Berechne = -b/2a (l/2a) \J b 2 -4ac Gib x , x 2

aus

Abb. 1.8. Struktogramm "Lösung von quadratischen Gleichungen" Über diese drei grafischen Konstrukte hinaus werden keine weiteren Darstellungselemente benötigt. Diese Darstellungsform wurde 1973 von I. Nassi und B. Shneiderman vorgestellt (Nassi/Shneiderman (1973)); Struktogramme werden daher auch als Nassi-Shneiderman-Diagramme bezeichnet.

22

1. Kapitel: E i n f ü h r u n g

Eine natürliche Grenze des U m f a n g s von Struktogrammen ist d u r c h die G r ö ß e einer DIN A4-Seite gegeben. Sind Algorithmen größeren U m f a n g s darzustellen, wird e m p f o h l e n , zunächst einen U m r i ß des A l g o r i t h m u s a u f z u z e i c h n e n , in d e m f ü r z u s a m m e n g e h ö r e n d e V e r a r beitungsschritte lediglich eine Bezeichnung f ü r diese Schritte e i n g e tragen wird. Diese Bezeichnungen verweisen auf weitere S t r u k t o g r a m m e , in d e n e n die zugehörigen Verarbeitungsschritte detailliert w e r d e n . Je nach U m f a n g des Algorithmus k a n n diese V e r f e i n e r u n g m e h r m a l s wiederholt w e r d e n . F ü r unseren Algorithmus könnte man beispielsweise wie in A b b i l d u n g 1.9. vorgehen.

Zusammenfassung: Z u r grafischen Darstellung von Algorithmen werden drei Symbole eingeführt: - Das Anweisungssymbol. - Das Entscheidungssvmbol. - Das Wiederholungssvmbol. Der Eingang in ein Symbol ist die O b e r k a n t e , der Ausgang die U n t e r k a n t e des Symbols. Die Symbole werden nach folgenden Regeln zu S t r u k t o g r a m m e n zusammengefügt: - Sequenzen von Anweisungen werden d u r c h U n t e r e i n a n d e r z e i c h nen von Anweisungssymbolen dargestellt, wobei die U n t e r k a n t e des oberen Symbols mit der Oberkante des unteren Symbols z u sammenfällt. - Im J a - und N e i n - Z w e i g eines Entscheidungssymbols k ö n n e n j e weils ein Symbol oder K o m b i n a t i o n e n von Symbolen a u f t r e t e n . - Im Innern eines Wiederholungssymbols können ein Symbol oder K o m b i n a t i o n e n von Symbolen a u f t r e t e n . Daraus folgt, d a ß auch das ganze Struktogramm bei seiner O b e r k a n te beginnt und bei seiner U n t e r k a n t e endet. Die absolute G r ö ß e der Symbole und das Verhältnis ihrer Seitenlängen zueinander sind v a riabel. S t r u k t o g r a m m e sollten nicht größer als eine DIN A4-Seite sein. Sind Algorithmen größeren U m f a n g s darzustellen, wird eine A u f t e i l u n g auf mehrere S t r u k t o g r a m m e v o r g e n o m m e n . Dabei stellt das erste Struktogramm den ganzen Algorithmus im Ü b e r b l i c k dar; weitere S t r u k t o g r a m m e detaillieren einzelne Teile v o r h e r g e h e n d e r S t r u k t o g r a m m e , so d a ß die Gesamtdarstellung einen hierarchischen A u f b a u erhält.

1. Kapitel: Einführung

Quadratische

Gleichungen

Wiederhole, solange Werte vorhanden Lösung einer Gleichung Lösung einer Gleichung Nimm Werte für a, b und c Ja

— - —

_^^a L jungleich 0



Berechne b 2 -4ac Gib größer o d e r / ^ 'Keine gleich 0? ^ ^ quadratische Ja ^ ^ Nein Gleichung' aus Gib Berechnung der reellen Lösungen 'Komplexe Lösungen' Gib x , x^ aus aus 1 2 Berechnung der reellen Lösungen b = - — 2a + 2a N 1 b Berechne x = 2a~ 2a 2

Berechne x

yb2 2-

>

4ac 4ac

Abb. 1.9. Schrittweise Verfeinerung eines Struktogramms

23

2. Berechnung und Ausgabe von arithmetischen Ausdrücken Lernziel: Sie sollen lernen, ablauffähige P L / 1 - P r o g r a m m e f ü r einfache Berechnungen zu erstellen.

2.1. Der formale Aufbau eines PL/1-Programms Ein P L / 1 - P r o g r a m m hat folgenden formalen A u f b a u :

p r o g r a m m n a m e : PROCEDURE O P T I O N S (MAIN) ; anweisungl; anweisung2;

END

programmname;

Die groß geschriebenen Wörter PROCEDURE, O P T I O N S , MAIN und END sind sogenannte Schlüsselwörter, die in der P L / 1 - S p r a c h e eine feste Bedeutung haben. Für p r o g r a m m n a m e kann ein (ziemlich) frei gewählter Name eingesetzt werden. Seine Zusammensetzung unterliegt folgenden Beschränkungen: - Das erste Zeichen m u ß ein Buchstabe sein. - Die restlichen Zeichen können Buchstaben, Z i f f e r n oder U n t e r streichungszeichen ( _ ) sein. In P L / 1 zählen auch die Zeichen $, # und @ zu den Buchstaben. - Die maximale Länge des Namens ist implementierungsabhängig. Jede P L / 1 - A n w e i s u n g endet mit einem Semikolon. Die Anweisung PROGRAMM_l: PROCEDURE O P T I O N S ( M A I N ) ; bedeutet, daß mit ihr ein Programm namens PROGRAMM_l beginnt; die Anweisung END PROGRAMM 1 ;

2. Kapitel: Arithmetische Ausdrücke

25

bedeutet, daß mit ihr das Programm PROGRAMM_l endet. Zwischen diesen beiden formalen Anfangs- und Endeanweisungen stehen die eigentlichen funktionstragenden Anweisungen. Zur Erläuterung eines Programms innerhalb des Programmtexts dienen die Kommentare, die mit / * beginnen und mit * / enden; z.B. /* Dies ist ein Kommentar

*/

In einem Kommentar darf jede Zeichenfolge, ausgenommen * / vorkommen. Kommentare dürfen überall da in ein Programm eingefügt werden, wo ein Leerzeichen stehen darf. Kommentare sind keine Anweisungen und werden deshalb auch nicht mit einem Semikolon abgeschlossen. Sie beeinflussen den Ablauf des Programms nicht. Bei der zeilenweisen Niederschrift eines Programms hat man viele Freiheiten; PL/1 ist nämlich eine "formatfreie" Sprache, d.h. man ist beim Hinschreiben der Anweisungen nicht an eine starre Zeileneinteilung gebunden, mit einer Ausnahme: es dürfen nur die Schreibstellen 2 bis 72 jeder Zeile benutzt werden. Innerhalb dieses Bereichs können die Anweisungen nach Belieben angeordnet werden. Diese Freiheit sollte dazu gebraucht werden, den Programmtext möglichst übersichtlich zu gestalten; Empfehlungen hierzu sind: - Nicht mehr als eine Anweisung in eine Zeile schreiben; - Leerzeilen und Einrückungen zur optischen Gliederung des Textes einfügen.

2 . 2 . A r i t h m e t i s c h e Ausdrücke

Arithmetische Ausdrücke sind aus der Mathematik bekannt; Beispiele sind 7+3x5

18+9.5 ; 4

; 25+16x4

.

Mit diesen Ausdrücken sind gewisse Bedeutungen verbunden. Bekannt sind vor allem - die Zahlen, - die Zeichen f ü r arithmetische Operationen,

26

-

2. Kapitel: A r i t h m e t i s c h e Ausdrücke

die Reihenfolge, in der ein arithmetischer Ausdruck ausgerechnet wird.

Der Formalismus der Sprache PL/1 verlangt etwas abweichende Darstellungsarten. Im folgenden wird also zu sprechen sein über die PL/1-Realisierung von - Zahlen (arithmetischen Konstanten), - Arithmetischen Operationen, und über die - PL/1-spezifische Auswertung von arithmetischen Ausdrücken. 2.2.1. Arithmetische Konstanten Die Z i f f e r n 0 bis 9 werden in PL/1 wie üblich geschrieben. Zur Abtrennung des gebrochenen Teils einer Zahl von ihrem ganzen Teil verwendet man den Dezimalpunkt. Weiterhin gibt es in PL/1 die bekannten Vorzeichen + und - . Größere Unterschiede gibt es bei der sogenannten Potenzschreibweise. bei der eine Zahl als Produkt eines Dezimalbruchs und einer Potenz zur Basis 10 dargestellt wird, z.B. 406721 = 4,06721 X 105 0,00023 = 2,3 X 10"4 Hierbei gibt der Exponent von 10 an, um wieviele Stellen das K o m ma des Dezimalbruchs (der Mantisse) nach rechts (positiver Exponent) oder links (negativer Exponent) verschoben wird. Diese Potenzschreibweise ist auch in PL/1 möglich. Die Zeichenfolge x 1 0 wird jedoch durch den Buchstaben E (für "Exponent") ersetzt und der Exponent wird nicht hochgestellt. Die PL/1-Darstellungen der obigen Zahlen sehen also so aus (man beachte den Dezimalpunkt!) 4.06721E5 2.3E-4 Leerzeichen innerhalb von Zahlen sind nicht erlaubt. Die Gemeinsamkeiten und Unterschiede zwischen der bekannten und der PL/1-Zahlendarstellung sind in Tabelle 2.1. zusammengefaßt.

2. Kapitel: Arithmetische Ausdrücke

Bekannte Darstellung

PL/1-Darstellung

Ziffern 0 , . . . , 9 Dezimalkomma 9 , 5 Vorzeichen + 2 - 4 Potenzschreibweise 2,3 ' 10~4

Ziffern 0 , . . . , 9 DezimalDunkt 9 . 5 Vorzeichen + 2 - 4 mit E 2.3E-4

27

T a b . 2.1. Darstellung von arithmetischen Konstanten

2.2.2. Arithmetische Operatoren G e l ä u f i g sind die Operatoren + (Addition), - (Subtraktion), ' oder x (Multiplikation) und : , / oder Bruchstrich (Division). Die P o t e n zierung wird üblicherweise d u r c h Hochstellung des Exponenten a u s gedrückt. In P L / 1 gibt es die Operatoren + f ü r die Addition, - f ü r die S u b traktion, * f ü r die Multiplikation, / f ü r die Division und * * f ü r die Potenzierung. Wie in der M a t h e m a t i k haben die Zeichen + und - also eine D o p p e l b e d e u t u n g als Vorzeichen und als Operator. Die G e m e i n s a m k e i t e n und Unterschiede sind in Tabelle 2.2. dargestellt. Z u beachten ist noch zweierlei: - Alle Operatoren müssen hingeschrieben werden; das Weglassen von Multiplikationszeichen ist nicht möglich. - Das Divisionsbeispiel mit d e m Bruchstrich zeigt, d a ß der B r u c h strich auch etwas über die R e i h e n f o l g e d e r Berechnung aussagt; in P L / 1 sind h i e r f ü r zusätzliche K l a m m e r n notwendig. D a r ü b e r wird im nächsten Abschnitt m e h r gesagt.

28

2. Kapitel: Arithmetische Ausdrucke

Bekannte Darstellung

Bedeutung

P L / 1 -Darstellung

+

Addition Subtraktion Multiplikation

+

Division

/

-

oder X oder

/ I

oder oder

Exponent

7 + 11 7 - 5 3 ' 4 7 X 11 pq - ab 3 + 4 7 - 2 8 / 0,5 12 : 4 2 (85)2

Potenzierung

-

*

* *

7 + 11 7 - 5 3 * 4 7 * 11 P*Q - A*B (3+4)/(7-2) 8 / 0.5 1 2 / 4 2 ** 4 (8**5)**2

Tab. 2.2. Arithmetische Operatoren

2.2.3. Auswertung von arithmetischen Ausdrücken Wenn in einem arithmetischen A u s d r u c k mehrere O p e r a t o r e n v o r k o m m e n , m u ß festgelegt sein, in welcher R e i h e n f o l g e die R e c h e n operationen a u s g e f ü h r t werden. In A n l e h n u n g an die b e k a n n t e R e gel "Punktrechnung vor Strichrechnung" gilt, d a ß Multiplikationen und Divisionen vor Additionen und Subtraktionen a u s g e f ü h r t w e r den. Noch höher rangieren der Potenzoperator und die Vorzeichen. Es besteht also die in Tabelle 2.3. dargestellte R a n g o r d n u n g . Treten m e h r e r e Operatoren der gleichen Stufe a u f , wird bei O p e r a t o r e n der Stufe 1 von rechts nach links ausgewertet, bei Operatoren d e r a n d e ren Stufen jedoch von links nach rechts.

Rang 1

+, - (Vorzeichen) und * * (Potenzierung)

2

* (Multiplikation) und /

3

+ (Addition) u n d - (Subtraktion)

(Division)

Tab. 2.3. R a n g o r d n u n g d e r arithmetischen Operatoren

2. Kapitel: Arithmetische Ausdrücke

29

Beispiele: - 2 * 5 * * 3 ergibt - 2 5 0 (zuerst wird 5 * * 3 berechnet, dann mit - 2 multipliziert) 18

+

4

*

(erst 4 * 7 , -2

**

7 /

2 ergibt 3 2

dann 2 8

/

2 , dann 1 8

+

14)

4 ergibt - 1 6 (!)

3 + 4 / 7 - 2 ergibt 1 . 5 7 (erst 4 / 7 , dann Addition und Subtraktion) Das letzte Beispiel ist das Divisionsbeispiel mit dem Bruchstrich aus Tabelle 2.2. Offensichtlich führt die schematische Übertragung des Bruchs in den P L / 1 -Formalismus zu einem Fehler, da der Bruchstrich auch aussagt, daß zuerst der Zähler, dann der Nenner, und zuletzt erst die Division auszurechnen ist. Eine Beeinflussung der Reihenfolge von Berechnungen ist in PL/1 durch Klammern möglich. Es gilt die Regel, daß Klammern zuerst, und zwar von innen nach außen, aufgelöst werden. Beliebig viele, auch überflüssige, Klammern können verwendet werden. Der Ü b e r sichtlichkeit halber sollte man von dieser Möglichkeit reichlich G e brauch machen! Unser Bruchstrich-Beispiel lautet also richtig (3 + 4) / (7 - 2)

2.3. Ausgabe von Ergebnissen mit dem P U T L I S T - B e f e h l Es können jetzt beliebig komplizierte arithmetische Ausdrücke in PL/1 formuliert werden. Nun wird eine P L / 1 - A n w e i s u n g vorgestellt, mit der die Ergebnisse solcher Berechnungen ausgegeben werden. Die einfachste Ausgabeanweisung lautet:

PUT LIST(arithmetischer_ausdruck); PUT und L I S T sind PL/1 -Schlüsselwörter; die Klammern umgeben den arithmetischen Ausdruck; am Ende steht ein Semikolon.

30

2. Kapitel: Arithmetische Ausdrücke

Beispiel: Wenn in einem PL/1-Programm die Anweisung PUT L I S T ( 1 7 + 4 ) ; vorkommt, dann geschieht bei der Ausführung des Programms an dieser Stelle zweierlei: - Das Ergebnis der Addition wird berechnet; - Dieses Ergebnis wird ausgegeben. Sie erhalten also die Zahl 2 1 am Bildschirm angezeigt oder ausgedruckt. Ein weiteres Beispiel: Nach der Formel Warenwert x (1 - R a b a t t ) + F r a c h t soll der Rechnungsbetrag für folgende Werte errechnet und ausgegeben werden: - Warenwert = DM 127,00, - Rabatt = 0,03 (also 3 %), - Fracht = DM 2,50. Einsetzen der Werte in die Formel, Beachtung des PL/1 -Formalismus und Hinzunahme der Ausgabeanweisung liefert PUT L I S T ( 1 2 7 . 0 0 * ( 1 - 0 . 0 3 ) + 2 . 5 0 ) ; Diese Anweisung, eingebettet in den oben erläuterten formalen Rahmen eines PL/1-Programms, ergibt unmittelbar ein vollständiges Programm: RECHNUNG: PROCEDURE OPTIONS ( M A I N ) ; / * Programm z u r E r m i t t l u n g d e s R e c h n u n g s b e t r a g s aus Warenwert, R a b a t t s a t z und Frachtkosten */ PUT L I S T ( 1 2 7 . 0 0

* (1 -

0.03)

+

2.50);

END RECHNUNG; Läßt man dieses Programm auf einer DV-Anlage ablaufen, erhält man angezeigt oder ausgedruckt: 125.6900 Zwei Erweiterungen sollen das Arbeiten mit der PUT L I S T - A n weisung einfacher und effizienter gestalten: - Zwischen den Klammern können beliebig viele arithmetische Ausdrücke stehen, die berechnet und ausgegeben werden sollen. Dabei werden zwei Ausdrücke durch ein Komma voneinander

2. Kapitel: Arithmetische Ausdrucke

-

31

getrennt. Die Ergebnisse werden automatisch in bestimmte Schreibstellen der Ausgabezeile, ähnlich den Tabulatorpositionen einer Schreibmaschine, geschrieben; dabei ist sichergestellt, daß zwischen zwei Ergebnissen stets ein Zwischenraum gelassen wird und daß am Ende einer Zeile eine neue Zeile begonnen wird. Beispiel: PUT L I S T ( 1 7 + 4 , 127.00*(l-0.03)+2.50); Ergebnis: 2 1 125.6900 Daneben gibt es die Möglichkeit, die von verschiedenen PUT L I S T - A n w e i s u n g e n erzeugten Ergebnisse optisch voneinander zu trennen. Hierzu dienen die Positionierungs-Schlüsselwörter, die in der PUT L I S T - A n w e i s u n g zwischen den Wörtern PUT und L I S T angegeben werden. Die Positionierungs-Schlüsselwörter und ihre Bedeutungen sind:

PAGE SKIP(n)

LINE(m)

Es wird eine neue Seite begonnen. Es werden n - 1 Leerzeilen freigelassen. ( S K I P ( l ) , für das man auch einfach S K I P schreiben kann, bedeutet, daß eine neue Zeile begonnen wird.) Die Ausgabe beginnt in Zeile m. Man hat sich die Zeilen einer Druckseite von 1 bis etwa 60 (implementierungsabhängig) durchnumeriert vorzustellen.

PAGE und S K I P ( n ) sowie PAGE und L I N E (m) können auch zusammen auftreten und haben dann die Wirkung, daß vor A u s f ü h rung von S K I P ( n ) bzw. L I N E ( m ) eine neue Seite begonnen wird. Ist bei Angabe von L I N E (m) die Nummer der aktuellen Zeile bereits größer als m, dann wird die m-te Zeile der nächsten Seite aufgesucht. Die Positionierungsangaben werden immer vor dem Drucken der Ergebnisse ausgeführt. Beispiel: PUT PAGE L I S T ( 1 7 + 4 ) ; PUT S K I P ( 3 ) LIST(127.00*(1-0.03)+2.50); Ergebnis: 21 (1. Zeile einer neuen Seite) (Leerzeile) (Leerzeile) 125.6900

32

2. Kapitel: Arithmetische Ausdrücke

Berücksichtigt man, daß mit einer PUT L I S T - A n w e i s u n g auch andere als arithmetische Ausdrücke ausgegeben werden können (darüber mehr im nächsten Abschnitt), dann sieht der Formalismus der PUT L I S T - A n w e i s u n g jetzt so aus:

PUT p o s

LIST(ausdruckl,ausdruck2,...);

p o s steht hier für eins (oder eine erlaubte Kombination) der oben aufgeführten Positionierungs-Schlüsselwörter, p o s kann auch ganz entfallen. Soll nur eine Ansteuerung einer Seite oder Zeile erfolgen, kann man auch nur PUT p o s ; schreiben. Die Angabe PUT PAGE; z.B. resultiert nur in einem Seitenvorschub; gedruckt wird nichts.

2.4. Zeichenketten-Konstanten Werden von einem PL/1-Programm viele verschiedene Ergebnisse berechnet und ausgegeben, dann wird eine Kennzeichnung der Ergebnisse im Ausdruck wichtig, um die Übersicht über die Bedeutung der Zahlen zu behalten. Statt 1 2 5 . 6 9 0 0 sollte z.B. besser ausgegeben werden Rechnungsbetrag = 125.6900. Solche erläuternden Texte werden in der PL/1-Sprache Zeichenketten-Konstanten genannt. Formal werden sie in Apostrophe (Hochkommata) eingeschlossen:

•text'

Der Text kann aus einer beliebigen Zeichenfolge bestehen. Soll ein Apostroph im Text selbst vorkommen, muß es doppelt geschrieben werden, um es von den äußeren, nicht zum Text gehörenden A p o strophen zu unterscheiden.

2. Kapitel: Arithmetische Ausdrücke

33

Beispiele:

•Rechnungsbetrag = ' •17 und 4 i s t 1 1 Crime d o e s n ' ' t p a y ' Zeichenketten-Konstanten können von PUT LIST-Anweisungen genauso ausgegeben werden wie die Ergebnisse arithmetischer Ausdrücke; jedoch wird aus ihnen nichts "berechnet"; sie werden so ausgegeben, wie sie hingeschrieben werden. Sie sind auch Ausdrücke, müssen also auch durch Kommata von anderen Ausdrücken abgetrennt werden. Beispiele:

a)

b)

PUT L I S T ( ' R e c h n u n g s b e t r a g = ' , 127.00*(l-0.03)+2.50, »17 u n d 4 i s t ' , 1 7 + 4 ) ; Ergebnis: Rechnungsbetrag = 125.6900 17 u n d 4 i s t 2 1 PUT L I S T ( ' E n d e d e s 2 . K a p i t e l s ' ) ; Ergebnis: Ende d e s 2 . K a p i t e l s

2.5. Übungen

1.

Ändern Sie das Programm RECHNUNG aus Abschnitt 2.3. so ab, daß es den Rechnungsbetrag für folgende Werte ausrechnet: - Warenwert = DM 864,98, - Rabatt = 8 %, -Fracht = DM 21,50.

2.

Erweitern Sie das Programm aus Übung 1: In Zeile 2 einer neuen Druckseite soll zunächst das Wort Rechnung gedruckt werden, danach mit 2 Zeilen Abstand das Ergebnis in der Form Rechnungsbetrag = xxx.xx.

3.

Rechnen Sie 20 Grad Celsius in Grad Fahrenheit nach der Formel F = 1 , 8 C + 32 um. Geben Sie das Ergebnis s o a u s : 2 0 Grad C e l s i u s e n t s p r e c h e n x x x Grad Fahrenheit.

3. Variablen und Wertzuweisung Mit d e m Wissen aus Kapitel 2 können Sie (fast) beliebig k o m p l i zierte arithmetische Ausdrücke P L / l - g e r e c h t formulieren und m i t tels P U T L I S T berechnen und ausgeben lassen. Trotzdem sind die so erzeugbaren Programme aus verschiedenen Gründen auf die D a u er unbefriedigend: - Da alle Werte, mit denen gerechnet wird, im Programm direkt (als Konstanten) angegeben werden, wird bei mehrfachen A b l ä u f e n des gleichen Programms immer das gleiche Ergebnis berechnet und ausgegeben. Es ist also nicht sehr sinnvoll, ein Programm mehr als einmal ablaufen zu lassen. Soll das Programm mit anderen Werten arbeiten, muß die PUT L I S T - A n w e i s u n g neu g e schrieben und das ganze Programm neu übersetzt und gestartet werden. Dies ist sehr mühsam. - Viel brauchbarer wären Programme, die nicht ein konkretes Problem lösen, sondern die gleich eine ganze Klasse von Problemen bearbeiten. Bezogen auf das Beispielprogramm RECHNUNG aus dem vorigen Kapitel bedeutet das, dieses Programm so zu verallgemeinern, daß es f ü r beliebige Warenwerte, Rabattsätze und Frachtkosten die Rechnungsbeträge nach der allgemeinen Formel Rechnungsbetrag=Warenwert*(1-Rabatt)+Fracht errechnet und ausgibt. - Diese Verallgemeinerung setzt voraus, daß es eine Möglichkeit geben muß, konkrete Werte für den Warenwert, den Rabattsatz und die Frachtkosten beim Ablauf des Programms in das Programm so einzugeben, daß mit diesen Werten dann gerechnet wird.

Lernziel: In diesem Kapitel wird der Begriff der Variablen eingeführt, mit deren Hilfe die Erstellung von Programmen möglich wird, die allgemeine, nicht auf konkrete Einzelwerte bezogene Arbeitsvorschriften enthalten.

3 . 1 . Der Begriff der Variablen Eine Variable hat zwei Bestandteile: - Einen Wert (der in einem Speicherplatz abgelegt ist); - Einen Namen (der auf diesen Wert verweist).

S. Kapitel: Variablen u n d Wertzuweisung

35

Der im Speicherplatz enthaltene Wert der Variablen kann sich beliebig o f t ändern, während der Name der Variablen immer gleich bleibt. In einem P L / 1 - P r o g r a m m m u ß man den Namen einer Variablen und einige Eigenschaften der Werte, die die Variable annehmen können soll, in einer sogenannten Vereinbarung festlegen. Der Speicherplatz wird dann vom Übersetzer automatisch reserviert.

Variable Name

/ _

Wert Speicherplatz Abb. 3.1. Der Begriff der Variablen

3.2. Namen, Typen und Wertebereiche von Variablen Namen von Variablen sind, ähnlich den in Abschnitt 2.1. eingef ü h r t e n Namen von Programmen, ziemlich f r e i wählbar. Es gelten die dort genannten Einschränkungen, die kurz wiederholt werden: - Ein Name besteht aus Buchstaben, Z i f f e r n und Unterstrichen; - Das erste Zeichen m u ß ein Buchstabe sein; - Die maximale Länge eines Namens ist implementierungsabhängig. Beispiele f ü r gültige Namen sind: PERSONALNUMMER RECHNUNGS BETRAG PI_QUADRAT A1305_BXZ Während man mit den ersten drei Namen unmittelbar eine Bedeutung verbindet, ist der letzte Name aussagelos (obwohl er formal korrekt ist). U m zu übersichtlichen und gut lesbaren Programmen zu gelangen, sollte man f ü r Variablen stets sprechende Namen w ä h -

36

3. Kapitel: Variablen und Wertzuweisung

len, d.h. Namen, die auf die Bedeutung der mit ihnen verbundenen Werte hinweisen. Innerhalb eines Programms müssen Variablennamen eindeutig sein, d.h. zwei verschiedene Variablen dürfen nicht den gleichen Namen tragen. Es werden zunächst zwei Typen von Variablen eingeführt (ein weiterer Typ wird in Kapitel 6 vorgestellt). In Abschnitt 2.2.1. wurden zwei Arten von arithmetischen Konstanten behandelt: - Die sogenannten Festpunktzahlen, die aus einem ganzzahligen und einem gebrochenen Teil, getrennt durch einen Dezimalpunkt, bestehen. - Die sogenannten Gleitpunktzahlen, die aus einer Mantisse und einem Exponenten bestehen. Innerhalb der Mantisse kann der Punkt beliebig verschoben werden, wenn man den Exponenten entsprechend anpasst; daher der Name. Entsprechend gibt es zwei Typen von Variablen: Variablen, deren Werte Festpunktzahlen sind, und Variablen, deren Werte Gleitpunktzahlen sind. Die Festlegung des Wertebereichs von Variablen ist f ü r Fest- und Gleitpunktzahlen unterschiedlich: - Bei Festpunktzahlen wird angegeben, wieviele Ziffernstellen die Werte maximal haben können (der Dezimalpunkt zählt hierbei nicht mit) und wieviele Stellen davon hinter dem Dezimalpunkt stehen. - Bei Gleitpunktzahlen wird nur die Zahl der Ziffernstellen der Mantisse angegeben; der Exponent hat eine festen - implementierungsabhängigen - Wertebereich. Diese Festlegungen von Namen, Typ und Wertebereich von Variablen werden in einem PL/1-Programm in der DECLARE-Anweisung niedergelegt, die manchmal auch Vereinbarung genannt wird. Ihre allgemeine Form ist: DECLARE n a m e

attribute;

DECLARE ist ein neues Schlüsselwort, das eine Vereinbarung einleitet. Für n a m e ist der selbstgewählte Name der Variablen einzusetzen; a t t r i b u t ist ein Oberbegriff f ü r alle sonstigen notwendigen Angaben.

3. Kapitel: Variablen und Wertzuweisung

37

Für dezimale Festpunktzahlen heißen die Attribute DECIMAL F I X E D

(p,q)

wobei f ü r p die Gesamtzahl der Ziffernstellen, f ü r q die Zahl der Stellen nach dem Dezimalpunkt einzusetzen ist. Ist q = 0, handelt es sich um eine ganze Zahl; dann können die Angabe von q und das vorausgehende Komma entfallen: DECIMAL F I X E D

(p)

Der größtmögliche Wert f ü r p ist wieder implementierungsabhängig. Dezimalpunkt und Vorzeichen zählen bei der Angabe von p und q nicht mit. Dezimale Gleitpunktzahlen werden mit den Attributen DECIMAL FLOAT

(p)

versehen, wobei f ü r p die Zahl der Mantissenziffern eingesetzt wird. Beispiel: Variablen, die die in dem Programm RECHNUNG verwendeten Werte f ü r die Größen Warenwert (127.00), Rabatt (0.03) und Frachtkosten (2.50) annehmen können, werden wie folgt vereinbart: DECLARE WARENWERT DECIMAL F I X E D ( 5 , 2 ) ; DECLARE RABATT DECIMAL F I X E D ( 3 , 2 ) ; DECLARE FRACHT DECIMAL F I X E D ( 3 , 2 ) ; Zwei Vereinfachungen der DECLARE-Anweisung erleichtern die Schreibarbeit, wenn viele Variablen zu vereinbaren sind: - Mehrere Variablen können mit einem DECLARE vereinbart werden, indem das Wort DECLARE nur einmal am Anfang genannt und jede Einzelvereinbarung außer der letzten mit einem K o m ma statt mit einem Semikolon abgeschlossen wird; allgemein:

38

3. Kapitel: Variablen und Wertzuweisung

DECLARE namel attributel, name 2 attribute2, . •

-

. . , • •



t

Beispiel: DECLARE WARENWERT DECIMAL F I X E D (5,2), RABATT DECIMAL F I X E D (3,2), FRACHT DECIMAL F I X E D (3,2); Werden m e h r e r e Variablen mit identischen Attributen vereinbart, können die gemeinsamen A t t r i b u t e "ausgeklammert" werden; allgemein:

DECLARE (namel, name2, ...) attribute; Beispiel: DECLARE

(RABATT,

FRACHT) DECIMAL F I X E D

Z u s a m m e n f a s s e n d e s Beispiel: DECLARE WARENWERT DECIMAL F I X E D ( R A B A T T , FRACHT) DECIMAL F I X E D

(3,2);

(5,2), (3,2);

Die hier deklarierte Variable RABATT kann offensichtlich Werte zwischen -9.99 und +9.99 annehmen; diese sind die kleinsten und größten Zahlen mit drei Stellen, von denen zwei Nachkommastellen sind. Von B e d e u t u n g ist darüberhinaus noch, d a ß die kleinstmögliche Ä n d e r u n g des Werts von RABATT 0.01 beträgt; kleinere Werte kann RABATT nicht a u f n e h m e n , da nur zwei Stellen nach dem D e zimalpunkt v e r e i n b a r t sind.

Zusammenf assung: Es können jetzt dezimale Fest- und Gleitpunktvariablen vereinbart werden. Benötigt werden nun Anweisungen, mit denen man V a r i ablen Werte gibt. Dies ist Gegenstand der folgenden beiden A b schnitte.

3. Kapitel: Variablen und WertEuweisung

39

3.3. Wertzuweisung Die allgemeine Form der Wertzuweisung lautet: variable = ausdruck; Der rechts vom Gleichheitszeichen stehende Ausdruck wird ausgerechnet und das Ergebnis wird der links stehenden Variablen als Wert zugewiesen. Beispiel: Eine Variable VAR sei vereinbart mit DECLARE VAR DECIMAL FIXED ( 2 , 0 ) ; Dann bewirkt die Wertzuweisung VAR = 4 * 17 - 5 ; daß der Wert des Ausdrucks 4 * 17 - 5 ausgerechnet und VAR zugewiesen wird. Nach Ausführung der Zuweisung hat VAR also den Wert 63. Die Tatsache, daß der Wert von VAR im Verlauf eines Programms geändert werden kann, wird von dem folgenden Beispielprogramm illustriert, zu dessen Verständnis noch eine Vorbemerkung erforderlich ist: Soll der Wert einer Variablen ausgegeben werden, gibt man den Namen der Variablen in einer PUT LIST-Anweisung an. Bei der Ausführung des PUT L I S T im Programmablauf wird dann der aktuelle mit dem Variablennamen verbundene Wert ausgegeben. VARIABLENWERTE: PROCEDURE O P T I O N S ( M A I N ) ; / * B e i s p i e l e zur Ä n d e r b a r k e i t von Werten Variablen */ DECLARE VAR DECIMAL

in

FIXED(2,0);

VAR = 1 0 ; / * 1. Wertzuweisung */ PUT S K I P L I S T ( ' W e r t v o n VAR i s t VAR); VAR = 9 9 ; / * 2. Wertzuweisung */ PUT S K I P L I S T ( ' W e r t v o n VAR i s t ' , VAR); PUT S K I P L I S T ( ' W e r t END VARIABLENWERTE;

v o n VAR i s t

',

VAR);

40

3. Kapitel: Variablen und Wertzuweisung

Die Ergebnisse dieses Programms sind: Wert Wert Wert

von von von

VAR i s t VAR i s t VAR i s t

10 99 99

Erläuterung: Mit der ersten Wertzuweisung wird der Wert 1 0 in VAR gespeichert. Deshalb wird mit dem ersten PUT L I S T auch der Wert 1 0 ausgegeben. Durch die zweite Wertzuweisung wird der neue Wert 9 9 in VAR abgelegt; der alte Wert 1 0 wird überschrieben. Mit dem zweiten PUT L I S T wird also der neue Wert 9 9 angezeigt. Vor dem dritten PUT L I S T erfolgt keine neue Wertzuweisung; folglich wird der Wert 9 9 noch einmal ausgegeben. Mit dem dritten PUT L I S T wird vor allem demonstriert, daß durch das Ausgeben eines Variablenwerts dieser Wert nicht aus der Variablen "verschwindet"; vielmehr bleibt er auch nach der Ausgabe noch in der Variablen erhalten. Diesen Tatbestand nennt man "zerstörungsfreie Datenabgabe". Das in der Wertzuweisung auftretende Gleichheitszeichen bezeichnet offenbar keine statische Gleichheit im mathematischen Sinn, sondern einen dynamischen Prozeß, in dessen Ablauf zuerst die rechte Seite ausgerechnet und danach das Ergebnis der links stehenden Variablen zugewiesen wird. Durch diese Abfolge wird es möglich, daß auf der rechten und der linken Seite einer Zuweisung der gleiche Variablenname auftreten kann. Die Zuweisung VAR = VAR + 1 ; bewirkt z.B., daß der alte Wert von VAR um eins erhöht und das Ergebnis als neuer Wert von VAR gespeichert wird. Zwei Eigenschaften der Wertzuweisung werden im folgenden besprochen: 1) Die automatische T y p - und Genauigkeitsanpassung: 2) Die Möglichkeiten, Fehler bei der Wertzuweisung zu begehen. Zu 1): Die Variable WARENWERT war vereinbart worden mit DECLARE WARENWERT DECIMAL F I X E D ( 5 , 2 ) ; und kann damit Werte bis 999.99 aufnehmen. Eine Wertzuweisung an WARENWERT sieht so aus: WARENWERT = 1 3 4 . 7 8 ;

3. Kapitel: Variablen und Wertzuweisung

41

Ist d e r Wert zufällig ein ganzer D M - B e t r a g , etwa 127, d a n n kann m a n schreiben WARENWERT = 1 2 7 . 0 0 ; Man k a n n aber auch e i n f a c h WARENWERT = 1 2 7 ; schreiben. Die automatische Genauigkeitsanpassung von P L / 1 sorgt d a f ü r , d a ß die dreistellige ganze Zahl 1 2 7 vor der Z u w e i s u n g an WARENWERT in die f ü n f s t e l l i g e Zahl mit zwei Dezimalstellen 1 2 7 . 0 0 umgewandelt wird. Ein ähnlicher Mechanismus namens automatische T y p a n p a s s u n g wird wirksam, wenn sich rechte und linke Seite einer Zuweisung hinsichtlich des Typs ( F e s t p u n k t / G l e i t p u n k t ) unterscheiden. Bei der Zuweisung WARENWERT = 1 . 2 7 E 2 ; wird die Gleitpunktzahl 1 . 2 7 E 2 erst in die entsprechende Festp u n k t z a h l 1 2 7 u m g e w a n d e l t (Typanpassung). Dann e r f o l g t die oben beschriebene Genauigkeitsanpassung in 1 2 7 . 0 0 ; dieser Wert schließlich wird WARENWERT zugewiesen. Zu 2): Fehler bei der Wertzuweisung an Festpunktvariable treten vor allem dann a u f , wenn der A u s d r u c k auf der rechten Seite mehr b e d e u t same Z i f f e r n hat, als die Variable auf der linken Seite a u f n e h m e n kann. Zwei Fälle sind zu unterscheiden: - Der A u s d r u c k hat m e h r Dezimalstellen. In diesem Fall werden die überschüssigen Z i f f e r n ohne Warnung bei der Zuweisung a b geschnitten. Beispiel: DECLARE WARENWERT DECIMAL F I X E D (5,2); WARENWERT = 1 3 4 . 7 8 4 3 ; In WARENWERT wird 1 3 4 . 7 8 gespeichert. - Der A u s d r u c k hat mehr Z i f f e r n vor dem Dezimalpunkt. Das A b schneiden überschüssiger Z i f f e r n wie im ersten Fall würde zu unsinnigen Ergebnissen f ü h r e n , z.B. würde bei WARENWERT = 1 0 0 0 . 0 0 ; d e r Wert 0 zugewiesen! Tatsächlich wird der Programmablauf beim A u f t r e t e n dieses Fehlers abgebrochen, und eine Fehlermeld u n g wird ausgegeben. In P L / 1 haben die meisten möglichen P r o g r a m m u n t e r b r e c h u n g e n Namen (wozu das gut ist, wird in Kapitel 11 erläutert); diese hier heißt S I Z E ( G r ö ß e ) , weil die G r ö ß e der Variablen nicht ausreicht, um alle Z i f f e r n a u f z u n e h men.

42

3. Kapitel: Variablen und Wertiuweisung

3.4. Einlesen von Werten in Variable mit dem GET LIST-Befehl Innerhalb eines Programms können die Werte von Variablen mit Zuweisungen beliebig verändert werden. U m Werte von außen e i n zulesen, z.B. Bedienereingaben von einer Tastatur oder Daten, die auf einem externen Datenträger abgespeichert sind, muß die GET L I S T - A n w e i s u n g benutzt werden, die folgende allgemeine Form hat:

GET L I S T ( v a r i a b l e l ,

variable2,

...)',

Für v a r i a b l e l , ... werden die Namen der Variablen eingesetzt, in die Werte eingelesen werden sollen. Die externe Darstellung einzulesender Werte ist identisch mit der Form, in der Konstanten innerhalb von P L / 1 - P r o g r a m m e n geschrieben werden. Zwei Werte werden voneinander getrennt durch - ein K o m m a oder - beliebig viele Leerzeichen oder - ein K o m m a und beliebig viele Leerzeichen vor u n d / o d e r hinter dem K o m m a . Es gibt keine Bindung einzelner Werte an bestimmte Schreibstellen. Auch das Ende einer Schreibzeile oder beispielsweise einer L o c h karte als externem Datenträger stellt keine Grenze dar; ein Wert, der in den letzten Schreibstellen einer Zeile/Lochkarte beginnt, kann in den ersten Schreibstellen der nächsten Zeile/Lochkarte fortgesetzt werden; dies wird man der Übersichtlichkeit wegen jedoch möglichst vermeiden! Allgemein hat man sich die Menge der Eingabedaten als einen Strom von Werten vorzustellen, bei dem die physikalischen Grenzen der verwendeten Eingabemedien keine Rolle spielen; die Eingabe mit GET L I S T heißt deshalb auch stromorientierte Eingabe. Ein Beispiel verdeutlicht die Arbeitsweise der GET sung:

LIST-Anwei-

3. Kapitel: Variablen und Wertiu Weisung

E I N L E S E N : PROCEDURE / * B e i s p i e l z u r GET DECLARE V A R 1 VAR2

OPTIONS(MAIN); LIST-Anweisung

DECIMAL DECIMAL

43

*/

FIXED(3,2), FIXED(5);

GET L I S T ( V A R 1 , V A R 2 ) ; PUT S K I P L I S T ( V A R 1 , VAR2);

/ *

1.

Lesen

*/

GET L I S T ( V A R 1 , V A R 2 ) ; PUT S K I P L I S T ( V A R 1 , VAR2);

/ * 2.

Lesen

*/

GET L I S T ( V A R 1 , V A R 2 ) ; PUT S K I P L I S T ( V A R 1 , VAR2);

/ *

3.

Lesen

*/

END

EINLESEN;

Die Eingabedaten werden in folgender Form eingegeben: 1 . 9 4 , 17 , 9.01,10025 0.1 317 Mit dem ersten G E T L I S T werden die ersten zwei Eingabewerte eingelesen; der erste Wert 1 . 9 4 wird der erstgenannten Variablen V A R 1 zugewiesen; der zweite Wert 1 7 der zweiten Variablen V A R 2 . Die zweite Leseanweisung liest das nächste Wertepaar und weist 9 . 0 1 an V A R 1 , 1 0 0 2 5 an VAR2 zu. Das dritte G E T L I S T schließlich liest den fünften und sechsten Wert und speichert 0 . 1 bzw. 3 1 7 in V A R 1 bzw. V A R 2 ab. Die PUT L I S T - A n w e i s u n g e n liefern also 1.94 17 9.01 10025 0.10 317 Der letzte Wert für V A R 1 wurde als 0 . 1 eingegeben, wird aber als 0 . 1 0 ausgegeben, weil die Vereinbarung von V A R 1 zwei Dezimalstellen vorsieht. Allgemein werden durch die G E T L I S T - A n w e i sung, wenn nötig, die gleichen Genauigkeits- und Typanpassungen vorgenommen, wie sie bei der Wertzuweisung in Abschnitt 3.3. b e sprochen wurden. Zwei der Möglichkeiten, Fehler beim Einlesen hervorzurufen, und ihre Folgen sind ebenfalls schon von der Zuweisung bekannt:

44

3. Kapitel: Variablen und WerUuweisung

-

Zuviele Dezimalstellen werden ohne Warnung abgeschnitten. Zuviele Stellen vor dem Dezimalpunkt führen zu einem Programmabbruch mit der SIZE-Fehlermeldung. Ein weiterer Fehler tritt auf, wenn weniger Eingabewerte vorhanden sind als alle GET LIST-Anweisungen eines Programms zusammen verlangen. In diesem Fall läuft das Programm korrekt ab bis zu der ersten GET LIST-Anweisung, der Eingabewerte fehlen. An dieser Stelle bricht das Programm mit einer Fehlermeldung namens "Dateiende" (ENDFILE) ab. Zum Abschluß dieses Kapitels wird das Programm RECHNUNG, das in Abschnitt 2.3. f ü r feste Werte formuliert worden war, allgemeiner gefaßt. Es enthält jetzt die Formel RECHNUNGSBETRAG = WARENWERT* (1-RABATT) + FRACHT, in die zu Beginn des Programms die konkreten Werte für WARENWERT, RABATT und FRACHT eingelesen werden. RECHNUNG_2: PROCEDURE O P T I O N S ( M A I N ) ; / * V e r a l l g e m e i n e r u n g d e s P r o g r a m m s RECHNUNG*/ DECLARE WARENWERT DECIMAL (RABATT, FRACHT) DECIMAL RECHNUNGSBETRAG DECIMAL

FIXED(5,2), FIXED(3,2), FIXED(6,2);

/*

E i n l e s e n d e r W e r t e f ü r WARENWERT, RABATT u n d FRACHT * / GET LIST(WARENWERT, RABATT, FRACHT);

/ * B e r e c h n e n d e s RECHNUNGSBETRAGS * / RECHNUNGSBETRAG = WARENWERT * ( 1 - RABATT) + FRACHT; / * Ausgeben des Rechnungsbetrags PUT L I S T ( ' R e c h n u n g s b e t r a g = RECHNUNGSBETRAG); END RECHNUNG_2; Ablauf dieses Programms mit den Eingabewerten 127 , 0 . 0 3 , 2 . 5 ergibt Rechnungsbetrag = 125.69

*/

3. Kapitel: Variablen und Wertcuweisung

45

Nochmaliger Testlauf mit den neuen Werten 505.34 , 0.07 , 9.8 ergibt Rechnungsbetrag = 479.76 Im Hinblick auf die Allgemeingültigkeit dieses Programms ist anzumerken, daß eine wesentliche Einschränkung der Verwendbarkeit in den vereinbarten Genauigkeiten der Variablen liegt. Die größtmöglichen Werte der einzelnen Variablen sind: - WARENWERT = 999.99, - RABATT = 9.99, - FRACHT = 9.99, - RECHNUNGSBETRAG = 9 9 9 9 . 9 9 . Das Programm versagt also, wenn z.B. ein Warenwert von DM 1500.00 verarbeitet werden soll. Abhilfe können Sie in der nachfolgenden Übung schaffen!

3.5. Übungen 1.

Ändern Sie das oben vorgestellte Programm RECHNUNG_2 so ab, daß Warenwerte bis unter DM 100000.00 und Frachtkosten bis unter DM 1000.00 eingegeben und verarbeitet werden können. Überlegen Sie dabei auch, wie groß der Rechnungsbetrag höchstens werden kann.

2.

Erstellen Sie ein Programm, das die Wochenlohnberechnung f ü r einen Arbeitnehmer durchführt. Drei Werte werden eingelesen: Personalnummer (sechsstellige ganze Zahl), Geleistete Wochenstunden (zweistellige ganze Zahl), Stundenlohn in DM (zwei Stellen vor, zwei Stellen hinter dem Dezimalpunkt). Der Bruttolohn ist das Produkt von Stunden und Stundenlohn. Vom Bruttolohn werden 15 % Lohnsteuer und 11 % Sozialversicherung abgezogen, um den Nettolohn zu erhalten. Ausgegeben werden die eingelesenen Werte, der Bruttolohn, der Lohnsteuerbetrag, der Sozialversicherungsbeitrag und der Nettolohn. Alle Werte sollen mit erläuternden Texten versehen werden.

46

3.

3. Kapitel: Variablen und Wertiuweisung

Eine einfache Provisionsabrechnung für einen Vertreter ist zu programmieren. Der Vertreter verkauft zwei Artikel A und B. Vom Verkaufserlös für A erhält er 12,5 % Provision, vom Erlös für B 10 %. Eingelesen werden Werte f ü r Verkaufte Menge und Einzelpreis von A, Verkaufte Menge und Einzelpreis von B. Unter der Überschrift Vertreterabrechnung werden ausgedruckt: Die eingelesenen Werte, Die Verkaufserlöse für A und B, Die Provisionen für A und B, Die Provisionssumme.

4.

Arithmetische Standardfunktionen

Neben den bisher eingeführten arithmetischen Grundoperationen gibt es eine Reihe weiterer aus der Mathematik bekannter Operationen mit arithmetischen Größen, z.B. Wurzelziehen oder den Absolutbetrag berechnen, sowie eine Anzahl bekannter Funktionen, z.B. Logarithmus, Exponentialfunktion oder Sinusfunktion. Wenn diese Operationen und Funktionen in PL/1 nicht vorhanden wären, müßte man f ü r jede dieser Berechnungen selbst ein Programm schreiben. Abgesehen davon, daß man bei vielen Funktionen gar nicht weiß, wie man sie berechnet (weil man gewünschte Werte in mathematischen Tafeln nachschlägt - oder weil man einen Taschenrechner mit den entsprechenden Funktionstasten hat!), wäre ein solches Vorgehen sehr mühsam. Glücklicherweise ist in der PL/1-Sprache bereits eine große Anzahl von mathematischen (und anderen) Funktionen vorprogrammiert, die nur aufgerufen zu werden brauchen. Diese Funktionen nennt man Standardfunktionen oder eingebaute Funktionen (Built-In Functions). Sie werden durch ihre Namen, gefolgt von dem Wert oder den Werten, f ü r die die Funktion berechnet werden soll, a u f gerufen. Diese Werte werden in Klammern eingeschlossen und durch Kommata voneinander getrennt. Einige gängige arithmetische Funktionen folgen. Andere Standardfunktionen werden z.B. in K a pitel 6 (Zeichenketten) und 8 (Bereiche und Strukturen) behandelt.

SQRT(X) ABS(X) LOGIO(X) EXP(X) SIN(X) MAX(XI, X2, MIN(XI, X2,

• . ) . . )

-

Wurzel von X Absolutbetrag von X Logarithmus zur Basis 10 von X Exponentialfunktion von X Sinus von X Maximum von X I , X2, ... Minimum von X I , X2, ...

Vereinbart wird die Benutzung einer Standardfunktion durch eine DECLARE-Anweisung mit dem (einzigen) Attribut B U I L T I N : DECLARE funktionsname BUILTIN;

48

4. Kapitel: Arithmetische Standardfunktionen

Verwendet werden können Standardfunktionen z.B. in arithmetischen Ausdrücken, etwa bei Wertzuweisungen oder in PUT LIST-Anweisungen: A = SQRT(16) + 8 6 ; PUT LIST(SIN(A) ) ; In A wird 90 (4 + 86) gespeichert; ausgegeben wird 1 (Sinus von 90). Ein Beispiel zeigt die Verwendung der Standardfunktion SQRT bei der Lösung der quadratischen Gleichung a x 2 + bx + c = 0 . Unter den Voraussetzungen, daß a ungleich Null und b - 4ac größer oder gleich Null sind, ergeben sich zwei reelle Lösungen x-^ und "X-2 nach der Formel b 1 X-1/2 = ~ 2 a - 2 a * W u r z e l a u s ( b 2 ~ 4 a c ) Das folgende Programm liest Werte für a, b und c ein und berechnet daraus x-^ und X2> QUAD_GLEICHUNG: PROCEDURE OPTIONS(MAIN) ; / * B e r e c h n u n g d e r r e e l l e n L ö s u n g e n XI u n d X2 der quadratischen Gleichung A*X**2 + B*X + C = 0 u n t e r d e n V o r a u s s e t z u n g e n : A u n g l e i c h 0 und B**2 - 4*A*C g r ö ß e r o d e r g l e i c h 0 * / DECLARE ( A , B , C , X I , X 2 ) DECIMAL F I X E D ( 1 0 , 4 ) ; DECLARE SQRT BUILTIN; / * E i n l e s e n A, B, C * / GET L I S T ( A , B, C ) ; / * E r r e c h n e n X I , X2 * / XI = - B / ( 2 * A ) + SQRT(B**2 X2 = - B / ( 2 * A ) - SQRT(B**2 -

4*A*C)/(2*A); 4*A*C)/(2*A);

/ * A u s g e b e n d e r E i n g a b e w e r t e und d e r Ergebnisse */ PUT SKIP L I S T ( 1 A = ' , A , 1 B =',B,1 C =•,C); PUT SKIP L I S T ( ' X I = ' , X 1 , » X2 = ' , X 2 ) ; END QUAD GLEICHUNG;

4. Kapitel: Arithmetische Standardfunktionen

Für die Eingabedaten 4 , 8 und 3 gibt das Programm aus: A = 4.0000 B = 8.0000 C = XI = -0.5000 X2 = -1.5000

49

3.0000

5. Steuerung des Programmablaufs Lernziel: Im ersten Kapitel wurde erläutert, daß sich alle Programme aus den drei Steuerungselementen Sequenz, Iteration und Entscheidung konstruieren lassen. Dieses Kapitel stellt die PL/1-Realisierungen dieser Elemente vor, so daß Sie am Ende dieses Kapitels Programme mit Entscheidungen und mit bedingten Wiederholungen von Anweisungsfolgen schreiben können.

5 . 1 . S e q u e n z von Anweisungen

Unter einer Anweisungssequenz war die lineare Abfolge von untereinanderstehenden Anweisungen in einem Struktogramm verstanden worden; vgl. Abbildung 5.1. Lies Warenwert,

Rabatt, Fracht

Rechnungsbetrag

=

Warenwert Gib Rechnungsbetrag

*

(1 - R a b a t t ) +

Fracht

aus

Abb. 5.1. Sequenz In PL/1 wird eine Sequenz durch einfaches Hintereinanderschreiben von Anweisungen realisiert, z.B. GET LIST(WARENWERT, RABATT, FRACHT); RECHNUNGSBETRAG = W A R E N W E R T * (1 - R A B A T T ) + FRACHT? PUT LIST(RECHNUNGSBETRAG); Alle mit dem bisherigen Wissen entwickelbaren Programme sind also rein sequentielle Programme.

5 . 2 . Die D O - A n w e i s u n g zur Iteration

Wozu braucht man Wiederholungen von Anweisungsfolgen? Angenommen, in einem Betrieb fielen täglich 100 Berechnungen der Art an, wie sie von dem am Ende des dritten Kapitels vorgestellten Pro-

6. Kapitel: Steuerung des Programmablaufs

51

gramm RECHNUNG_2 ausgeführt werden. Bei Verwendung dieses Programms müßte es hundertmal mit je einem Satz von Eingabewerten gestartet werden. Viel einfacher wäre es, wenn in einem neuen Programm die Anweisungen von RECHNUNG_2, vom Einlesen der Werte bis zur Ausgabe des Rechnungsbetrags, hundertmal wiederholt würden. Das Struktogramm zu dieser Lösung, das in A b bildung 5.2. gezeigt wird, bereitet keine Schwierigkeiten.

Wiederhole hundertmal Lies Warenwert, Rabatt, Fracht Rechnungsbetrag = Warenwert * (1 - Rabatt) + Fracht Gib Rechnungsbetrag

aus

Abb. 5.2. Beispiel f ü r eine feste Zahl von Wiederholungen In PL/1 gibt es f ü r diesen ersten Fall der Wiederholung von A n weisungen, der dadurch charakterisiert ist, daß die Zahl der Wiederholungen von vornherein feststeht, die sogenannte Laufanweisung. Sie wird im folgenden Abschnitt behandelt. Angenommen, die Zahl der Rechnungsbeträge, die täglich zu ermitteln ist, schwankt von Tag zu Tag. In diesem Fall muß das Programm also f ü r eine variable, von der Anzahl der Eingabedaten abhängige Zahl von Wiederholungen konstruiert werden. Um hier bei der Verarbeitung dem Programm mitzuteilen, daß das Ende der Eingabedaten erreicht ist, greift man zu einem Trick: Nach allen Datentripeln wird ein Wert f ü r WARENWERT eingegeben, der normalerweise nicht vorkommt, etwa - 1 . An diesem Ausnahmewert erkennt das Programm, daß die Wiederholungen zu beenden sind. Das Struktogramm f ü r diese Lösung in Abbildung 5.3. trägt diesem Trick Rechnung: Der Warenwert wird getrennt von den Werten f ü r Rabatt und Fracht eingelesen, um den besonderen Wert - 1 sofort zu erkennen und die Wiederholungen zu beenden.

52

5. Kapitel: Steuerung des Programmablaufs

Lies Warenwert Wiederhole solange Warenwert ungleich -1 Lies Rabatt,

Fracht

Rechnungsbetrag = Warenwert * (1 - Rabatt) + Fracht Gib Rechnungsbetrag

aus

Lies Warenwert Abb. 5.3. Beispiel f ü r eine variable Zahl von Wiederholungen Beachtenswert an diesem Struktogramm ist, daß es zwei Lesebefehle f ü r WARENWERT enthält: der erste wird nur einmal am Anfang ausgeführt, so daß schon beim ersten Eintritt in die Wiederholungsschleife geprüft wird, ob bereits das Ende der Verarbeitung erreicht ist. Das Struktogramm behandelt also auch den Fall korrekt, daß gar keine Rechnungsbeträge zu ermitteln sind. Der zweite Lesebefehl liest am Ende der Verarbeitung eines Satzes von Eingabewerten den nächsten Warenwert "im voraus" ein. Dieses Struktogramm ist also wesentlich komplizierter als das vorige, bei dem die genaue Zahl der Wiederholungen von vornherein feststand; es muß jedoch auch mit viel weniger Informationen auskommen. Für diesen zweiten Fall der Wiederholung von Anweisungen, bei dem die Anzahl der Wiederholungen von a priori unbekannten Sachverhalten, hier von der Zahl der Eingabedaten, abhängt, gibt es in PL/1 die sogenannte DO-Anweisung mit Bedingung, die im übernächsten Abschnitt behandelt wird. Beiden Arten der DO-Anweisung gemeinsam ist die folgende allgemeine Form:

5. Kapitel: Steuerung des Programmablaufs

53

DO wiederholungsangaben; anweisungl; anweisung2;

END;

Die erste Zeile e n t h ä l t die D O - A n w e i s u n g ; die in ihr e n t h a l t e n e n W i e d e r h o l u n g s a n g a b e n w e r d e n weiter u n t e n erläutert. A u f die DOA n w e i s u n g f o l g e n die zu w i e d e r h o l e n d e n A n w e i s u n g e n ; diese w e r d e n mit E N D ; abgeschlossen, u m sie von d e n n a c h f o l g e n d e n A n w e i s u n g e n a b z u g r e n z e n . D i e G e s a m t h e i t dieser A n w e i s u n g e n w i r d Schleife g e n a n n t ; die D O - A n w e i s u n g , die die S c h l e i f e e i n l e i t e t , h e i ß t a u c h S c h l e i f e n k o p f . D i e zu w i e d e r h o l e n d e n A n w e i s u n g e n b i l d e n den S c h l e i f e n r u m p f , das a b s c h l i e ß e n d e E N D ; h e i ß t S c h l e i f e n ende.

5 . 2 . 1 . Die DO-Anweisung als Laufanweisung Die L a u f a n w e i s u n g ist d a d u r c h g e k e n n z e i c h n e t , d a ß e i n e V a r i a b l e , die s o g e n a n n t e L a u f v a r i a b l e , n a c h e i n a n d e r b e s t i m m t e Werte a n n i m m t . Der erste Wert d e r L a u f v a r i a b l e n h e i ß t A n f a n g s w e r t : d e r Wert, bei dessen Ü b e r s c h r e i t e n die Schleife b e e n d e t w i r d , ist d e r E n d w e r t . Der A b s t a n d zwischen zwei a u f e i n a n d e r f o l g e n d e n Werten d e r L a u f v a r i a b l e n heißt S c h r i t t w e i t e . Diese Werte w e r d e n wie f o l g t in d e r D O - A n w e i s u n g spezifiziert:

DO laufvariable = anfangswert TO endwert BY Schrittweite; Ein Beispiel soll v o r a b die Wirkungsweise d e r D O - A n w e i s u n g e r l ä u tern: Es sei die S u m m e d e r ganzen Z a h l e n von 1 bis 100 d u r c h f o r t l a u f e n d e s A u f s u m m i e r e n zu e r m i t t e l n . Das S t r u k t o g r a m m in A b b i l d u n g 5.4. ist recht e i n f a c h zu e n t w i c k e l n .

54

5. Kapitel: S t e u e r u n g des P r o g r a m m a b l a u f s

SUMME =

0

Wiederhole

für

ZAHL = 1 ,

2,

3,

100

SUMME = SUMME + ZAHL Gib

SUMME

aus

Abb. 5.4. Struktogramm "Summe der ganzen Zahlen von 1 bis 100" Das zugehörige PL/1-Programm folgt: SUMMIEREN: PROCEDURE O P T I O N S ( M A I N ) ; / * Summe d e r g a n z e n Z a h l e n v o n 1 b i s DECLARE ZAHL DECIMAL SUMME DECIMAL

FIXED(3,0), FIXED(4,0);

SUMME = 0 ;

SUMME a u f

/*

DO ZAHL = 1 TO 1 0 0 BY 1 ;

100

*/

0 setzen

*/

ZAHL l ä u f t v o n 1 b i s 100 i n Schritten von 1 */ SUMME = SUMME + ZAHL? / * S c h l e i f e n rumpf */ END; /* Schleifenende */ PUT L I S T ( ' S U M M E =

/*

SUMME); / * A u s g a b e d e r Summe * /

END SUMMIEREN; Das Ergebnis wird nicht verraten! Der genaue Ablauf des Programms wird recht ausführlich erläutert, weil sich SUMMIEREN grundlegend von den bisher entwickelten Programmen unterscheidet: Bei diesem Programm sind erstmalig die (statische) Niederschrift und der (dynamische) Ablauf sehr verschieden, weil die in ihm enthaltene Schleife (genauer: der Schleifenrumpf) nur einmal hingeschrieben, jedoch hundertmal ausgeführt wird. Dieses dynamische Verhalten bekommt man bei kleinen Programmen recht gut mit einem sogenannten Schreibtischtest in den

5. Kapitel: S t e u e r u n g des P r o g r a m m a b l a u f s

55

G r i f f . Ein Schreibtischtest ist die gedankliche Simulation eines P r o g r a m m a b l a u f s . Als Hilfsmittel ist eine Tabelle von Nutzen, die f ü r j e d e verwendete Variable eine Spalte vorsieht. In einer Spalte w e r den u n t e r e i n a n d e r die jeweils in der Variablen enthaltenen Werte eingetragen. Der Schreibtischtest des Programms SUMMIEREN l ä u f t wie folgt ab: 1) SUMME erhält den Wert 0. 2) Beim ersten Eintreten in die Schleife erhält ZAHL den A n f a n g s w e r t 1. ZAHL wird dann mit d e m Endwert 1 0 0 verglichen. Solange ZAHL kleiner oder gleich dem Endwert ist, wird der Schleifenrumpf a u s g e f ü h r t . Das ist hier der Fall. 3) Schleifenrumpf: Der neue Wert von SUMME ergibt sich aus der Addition des alten Werts von SUMME und ZAHL, also 0 + 1 . 4) Beim Erreichen des Schleifenendes wird automatisch zum Schleifenkopf zurückverzweigt. 5) Im Schleifenkopf wird die Laufvariable ZAHL um die Schrittweite 1 erhöht, hat also jetzt den Wert 2. ZAHL wird wieder mit dem E n d w e r t 1 0 0 verglichen; ZAHL ist kleiner als 1 0 0 . Wir betreten also wieder den Schleifenrumpf. 6) Der alte Wert von SUMME ist 1, der Wert von ZAHL ist 2. SUMME erhält also den neuen Wert 1 + 2 = 3. 7) Beim Schleifenende wird wieder zum Schleifenkopf z u r ü c k v e r zweigt. Die Schritte 5) bis 7) wiederholen sich nun mehrmals. Wir verfolgen noch die letzten Schritte. ZAHL habe den Wert 9 8 , SUMME habe d u r c h Addieren von 9 8 den Wert X erhalten. - In 5) wird ZAHL auf 9 9 erhöht, das ist kleiner als 1 0 0 . - In 6) wird SUMME auf ( X + 9 9 ) gesetzt. - Von 7) wird zu 5) zurückgesprungen. - ZAHL erhält den Wert 9 9 + 1 = 1 0 0 . Dieser Wert ist gleich d e m E n d w e r t ; wie unter 2) erläutert, wird der Schleifenrumpf noch einmal a u s g e f ü h r t . SUMME wird also zu ( X + 9 9 + 1 0 0 ) . - Von 7) wird zu 5) zurückgesprungen. - ZAHL erhält den Wert 1 0 1 . Dieser Wert ist erstmalig größer als der E n d w e r t ; der Schleifenrumpf wird also nicht noch einmal d u r c h l a u f e n . Stattdessen wird automatisch bei der ersten auf das Schleifenende folgenden Anweisung f o r t g e f a h r e n . - Die PUT L I S T - A n w e i s u n g wird a u s g e f ü h r t , d.h. der Wert von SUMME wird gedruckt. - Das Programm wird beendet. Die Tabelle der Werte von ZAHL und SUMME sieht also so aus:

56

5. Kapitel: S t e u e r u n g des P r o g r a m m a b l a u f s

ZAHL

1 2

98 99 100 101

SUMME 0 1 3

X X+99 X+99+100

Die Wirkungsweise der Laufanweisung und einige werden nachfolgend zusammengefaßt.

Erläuterungen

Wirkungsweise: - Die Laufvariable wird vor der ersten Ausführung des Schleifenrumpfs auf den Anfangswert gesetzt. Vor jedem weiteren Durchlauf wird sie um die Schrittweite erhöht. - Vor jeder Ausführung des Schleifenrumpfs (also auch vor der ersten!) wird geprüft, ob der Wert der Laufvariablen den Endwert überschreitet. Ist das der Fall, wird das Programm mit der auf das Schleifenende folgenden Anweisung fortgesetzt; im anderen Fall wird der Schleifenrumpf ausgeführt. Ausdrücklich ist auf den Sonderfall hinzuweisen, daß die Laufvariable bereits vor der ersten Ausführung des Rumpfs größer ist als der Endwert: In diesem Fall wird der Rumpf nullmal durchlaufen! Erläuterungen: - Anfangswert, Endwert und Schrittweite können sein: - Arithmetische Konstanten (wie im Beispiel), - Variablen, - Arithmetische Ausdrücke. Bei der Angabe von Variablen und arithmetischen Ausdrücken ist zu beachten, daß ihr Wert vor dem ersten Schleifendurchlauf ermittelt und für alle Wiederholungen gespeichert wird. Eine Änderung der verwendeten Variablen im Schleifenrumpf hat also keine Auswirkung auf die Zahl der Wiederholungen! - Anfangswert, Endwert und Schrittweite können auch negativ sein. Ist die Schrittweite negativ, sollte sinnvollerweise der Endwert kleiner als der Anfangswert sein. Die Schleife wird dann

5. Kapitel: Steuerung des Programmablaufs

-

-

57

beendet, wenn die Laufvariable erstmals den End wert unterschreitet. Wenn die Angabe BY S c h r i t t w e i t e fehlt, wird automatisch eine Schrittweite von 1 eingestellt. Wenn die Angabe TO e n d w e r t fehlt, entsteht eine sogenannte "Unendliche Schleife", da kein Abbruchkriterium vorhanden ist. Nach Beendigung der Schleife enthält die Laufvariable den Wert, der den Endwert erstmals überschritten hat; im obigen Beispiel also 1 0 1 . Die Laufvariable kann, muß aber nicht, im Schleifenrumpf verwendet werden. Man sollte ihr jedoch im Rumpf keine neuen Werte zuweisen, da damit die Anzahl der Wiederholungen beeinflußt wird.

Beispiele: Allen folgenden Beispielen gemeinsam seien die Vereinbarungen DECLARE (ANF_WERT, END_WERT, LAUF_VAR) DECIMAL F I X E D ( 3 , 0 ) ; 1)

ANF_WERT = 1 0 0 ; END_WERT = 50; DO LAUF_VAR = ANF_WERT TO END_WERT BY - 1 0 ; Diese Schleife wird sechsmal durchlaufen, für LAUF_VAR 100, 90, 80, 70, 60, 50.

=

2)

ANF_WERT = 7 ; DO LAUF_VAR = ANF_WERT TO ANF_WERT + 5 ; Schrittweite 1 wird automatisch ergänzt, der Endwert errechnet sich zu 1 2 . Die Schleife wird also sechsmal durchlaufen, LAUF_VAR nimmt die Werte 7, 8 , 9 , 1 0 , 1 1 , 1 2 an.

3)

Das eingangs erwähnte Problem, bei dem 100 Berechnungen des Rechnungsbetrags aus Warenwert, Rabatt und Fracht durchzuführen sind, wäre so zu formulieren:

58

5. Kapitel: Steuerung des Programmablaufs

RECHNUNG_3: PROCEDURE OPTIONS(MAIN); /* Erweiterung von RECHNUNG_2 für 100 Sätze von Eingabewerten */ DECLARE WARENWERT (RABATT,FRACHT) RECHNUNGSBETRAG ZAEHLER

DECIMAL DECIMAL DECIMAL DECIMAL

FIXED(5,2), FIXED(3,2), FIXED(6,2), FIXED(3);

DO ZAEHLER = 1 TO 100; GET LIST(WARENWERT, RABATT, FRACHT); RECHNUNGSBETRAG = WARENWERT * (1 - RABATT) + FRACHT; PUT LIST( 1 Rechnungsbetrag = 1, RECHNUNGSBETRAG); END; END RECHNUNG 3; 5 . 2 . 2 . Die DO-Anweisung mit Bedingung Die D O - A n w e i s u n g m i t B e d i n g u n g hat f o l g e n d e allgemeine F o r m :

DO WHILE(bedingung); Vor j e d e m D u r c h l a u f des S c h l e i f e n r u m p f s w i r d g e p r ü f t , o b die in K l a m m e r n s t e h e n d e B e d i n g u n g e r f ü l l t ist. Ist das so, w i r d d e r S c h l e i f e n r u m p f a u s g e f ü h r t . A n d e r n f a l l s wird h i n t e r das Schleif e n e n d e v e r z w e i g t . Die B e d i n g u n g e n t h ä l t also nicht das A b b r u c h k r i t e r i u m . s o n d e r n dessen logisches G e g e n t e i l , das F o r t s e t z u n g s k r i t e r i u m . A u c h bei dieser S c h l e i f e n f o r m ist es möglich, d a ß d e r R u m p f g a r n i c h t d u r c h l a u f e n w i r d , w e n n nämlich die B e d i n g u n g b e reits vor d e r ersten A u s f ü h r u n g e r f ü l l t ist. Ein (inhaltlich triviales) Beispiel soll diesen Sachverhalt illustrieren: E i n e u n b e k a n n t e A n z a h l von Werten ist einzulesen. A u s g e g e b e n w e r d e n soll n u r d e r Wert, d e r a u f d e n Wert 9 9 9 folgt. A n w e l c h e r Stelle im E i n g a b e s t r o m die 9 9 9 steht, ist ebenfalls u n b e k a n n t .

5. Kapitel: Steuerung des Programmablaufs

59

Bei der Lösung ist zu überlegen, daß die Einleseoperation solange wiederholt wird, wie die eingelesene Zahl ungleich 9 9 9 ist. Die Wiederholung bricht nach dem Einlesen der 9 9 9 ab; danach wird noch einmal eingelesen und dieser Wert wird ausgegeben. Das Struktogramm dazu findet sich in Abbildung 5.5. Lies

ZAHL

Wiederhole Lies Lies Gib

solange

ZAHL u n g l e i c h

999

ZAHL

ZAHL ZAHL

aus

Abb. 5.5. Struktogramm "Zahl nach 9 9 9 " In diesem Struktogramm wird durch das Vorauslesen berücksichtigt, daß bereits die erste Zahl der Eingabe die 9 9 9 sein kann. Das folgende PL/1-Programm verwendet die DO WHILE-Anweisung; zusätzlich wird angenommen, daß die Eingabewerte maximal vierstellige ganze Zahlen sind. ZAHL_NACH_999: PROCEDURE O P T I O N S ( M A I N ) ? / * Ausdrucken der Zahl, d i e i n den E i n g a b e w e r t e n a u f 999 f o l g t * / DECLARE ZAHL DECIMAL GET L I S T ( Z A H L ) ;

/*

FIXED(4,0); Vorauslesen

*/

DO WHILE(ZAHL 999); GET L I S T ( Z A H L ) ; END; / * G e s u c h t e Zahl l e s e n und d r u c k e n */ GET L I S T ( Z A H L ) ; PUT L I S T ( ' G e s u c h t e Z a h l i s t • , Z A H L ) ; END ZAHL_NACH_999; Betrachtung der DO WHILE-Anweisung zeigt, daß der Operator "ungleich" in PL/1 offenbar durch die Zeichenkombination dargestellt wird, wobei ~ für die (logische) Verneinung steht. Lesen Sie

60

5. Kapitel: Steuerung des Programmablaufs

bitte die Anmerkung zu dem Zeichen ~ in Anhang A I : "Der P L / 1 Zeichensatz". Einzelheiten zur Formulierung von Bedingungen in P L / 1 enthält der nächste Abschnitt.

5.2.2.1.

Formulierung von Bedingungen: Vergleichsoperatoren und logische Verknüpfungsoperatoren

Eine Bedingung ist ein P L / 1 - A u s d r u c k , der sich beim Ablauf des Programms auf genau einen der beiden Wahrheitswerte "wahr" oder "falsch" reduzieren läßt. Die im vorigen Programm enthaltene Bedingung heißt ZAHL ~ = 9 9 9 . Wenn dieses Programm abläuft, steht in ZAHL stets ein konkreter Wert. Ist dieser Wert z.B. 1 7 , dann gilt: 1 7 ist ungleich 9 9 9 , d.h. die Bedingung ist erfüllt oder "wahr". Enthält ZAHL den Wert 9 9 9 , dann ist die Bedingung "falsch", weil 9 9 9 nicht ungleich 9 9 9 ist. Z u r Formulierung solcher Bedingungen steht in PL/1 eine Anzahl von Vergleichsoperatoren zur Verfügung. Sie sind in Tabelle 5.1. zusammengestellt.

Bezeichnung

PL/1-Darstellung

Größer Kleiner Gleich Größer oder gleich Kleiner oder gleich Ungleich Nicht größer Nicht kleiner

>

< =

>= = 4 0 WARENWERT * ( 1 - RABATT) *< 0 Gelegentlich ist es nötig, in einer Bedingung mehr als einen V e r gleich unterzubringen. Eine E r w e i t e r u n g des obigen Beispiels v e r anschaulicht diese Notwendigkeit: Es soll wieder eine u n b e k a n n t e Anzahl von Werten eingelesen werden. Ausgegeben werden soll e n t weder der Wert, der auf die Zahl 9 9 9 folgt, oder der Wert, d e r auf die Zahl 0 folgt. Erscheint die 9 9 9 zuerst, wird der ihr f o l g e n d e Wert ausgegeben; k o m m t die Null zuerst, wird der auf sie f o l g e n d e Wert angezeigt. Die Struktur dieser A u f g a b e ist die gleiche wie im vorigen Beispiel, nur die Bedingung ist komplizierter. Die Schleife soll abgebrochen werden, wenn entweder der Wert 999 oder der Wert 0 gelesen wird; die Schleife wird also solange fortgesetzt, wie die gelesene Zahl nicht 999 und nicht 0 ist. Die Fortsetzungsbedingung lautet also

Wiederhole solange ZAHL~=999 u n d ZAHL~=0 Das "und" v e r k n ü p f t die beiden Bedingungen Z A H L " = 9 9 9 und Z A H L ~ = 0 zu einer neuen Bedingung, die genau dann wahr ist, wenn beide Teilbedingungen wahr sind. Dieses sogenannte Logische U n d wird in P L / 1 d u r c h das Zeichen & dargestellt. Als zweiten logischen V e r k n ü p f u n g s o p e r a t o r gibt es das Logische (nicht ausschließende) Oder, das in P L / 1 d u r c h den senkrechten Strich | repräsentiert wird. Eine aus zwei mit Oder v e r k n ü p f t e n Teilen zusammengesetzte Bedingung ist genau dann wahr, wenn eine oder beide der Teilbedingungen wahr sind. U n d und Oder sind zweistellige Operatoren, weil sie zwei B e d i n gungen verbinden. Der dritte logische Operator ist die Negation, die in P L / 1 d u r c h das schon bekannte Zeichen ~ dargestellt wird. Die Negation verkehrt eine Bedingung in ihr Gegenteil; sie ist ein e i n stelliger Operator. Die Wahrheitstafel in Tabelle 5.2. gibt f ü r alle K o m b i n a t i o n e n von Wahrheitswerten zweier Bedingungen A u n d B die Wahrheitswerte der mittels Negation, U n d und Oder e r z e u g b a ren Bedingungen an.

62

6. Kapitel: Steuerung des Programmablaufs

A

B

A

Wahr Wahr Falsch Falsch

Wahr Falsch Wahr Falsch

Falsch Falsch Wahr Wahr

A

A&B

A|B

Wahr Falsch Falsch Falsch

Wahr Wahr Wahr Falsch

Tab. 5.2. Wahrheitstafel

Rang

Operatoren

Bedeutung

1

+ * *

Vorzeichen Potenzierung Negation

2

*

-

Multiplikation Division

/

3

+

4

=
=

Vergleichsoperatoren

Tab. 5.3. ODeratorhierarchie (Operatoren gleichen Rangs werden in Rang 1 von rechts nach links, sonst von links nach rechts ausgewertet.)

Da in komplexen Bedingungen arithmetische, vergleichende und logische Operatoren vorkommen können, ist es nötig, die in Kapitel 2 aufgestellte Operatorhierarchie, die die Reihenfolge der Auswertung von arithmetischen Ausdrücken festlegte, auf die neu hinzugekommenen Operatoren auszudehnen. Die vollständige Operatorhierarchie

S. Kapitel: S t e u e r u n g des P r o g r a m m a b l a u f s

63

ist in Tabelle 5.3. wiedergegeben. Wie bereits erwähnt, kann durch Klammersetzung die Auswertungsreihenfolge beliebig verändert werden. In dieser Tabelle ist auch ein bislang unbekannter Operator enthalten: Der auf Stufe 5 stehende Verkettungsoperator bezieht sich auf Zeichenketten; er wird erst im nächsten Kapitel vorgestellt, kommt aber in der Tabelle aus Vollständigkeitsgründen bereits vor. Beispiel: Das eingangs erwähnte Beispiel, in dem die Ermittlung des R e c h nungsbetrags solange wiederholt wird, wie f ü r Warenwert ein Wert ungleich - 1 eingelesen wird (vgl. das Struktogramm in Abbildung 5.3.), kann jetzt in ein P L / 1 - P r o g r a m m umgesetzt werden. RECHNUNG_4: PROCEDURE OPTIONS(MAIN); / * E r w e i t e r u n g v o n R E C H N U N G _ 2 für e i n e unbekannte Zahl von Eingabewerten. Das E n d e d e r E i n g a b e d a t e n ist e r r e i c h t , w e n n für W A R E N W E R T - 1 e i n g e l e s e n w i r d . */ DECLARE WARENWERT (RABATT, F R A C H T ) RECHNUNGSBETRAG

DECIMAL DECIMAL DECIMAL

FIXED(5,2), FIXED(3,2), FIXED(6,2);

GET LIST(WARENWERT);

/* Vorauslesen

DO W H I L E ( W A R E N W E R T -1) ; GET LIST(RABATT, FRACHT); RECHNUNGSBETRAG = W A R E N W E R T * (1 - R A B A T T ) + P U T L I S T ( ' R e c h n u n g s b e t r a g = ', RECHNUNGSBETRAG); GET LIST(WARENWERT);

*/

FRACHT;

END; END RECHNUNG

4;

5.2.3. Schachtelung von DO-Anweisungen K o m m e n in einem Programm mehrere, voneinander abhängige DOAnweisungen vor, spricht man von geschachtelten Schleifen.

64

5. Kapitel: Steuerung des Programmablaufs

Beispiel: Eine Tabelle des K l e i n e n Einmaleins (bis 10 * 10) ist zu erzeugen.

1 2 3 4 5 6 7 8 9 10

2 4 6 8 10 12 14 16 18 20

3 6 9 12 15 18 21 24 27 30

4 8 12 16 20 24 28 32 36 40

5 10 15 20 25 30 35 40 45 50

6 12 18 24 30 36 42 48 54 60

7 14 21 28 35 42 49 56 63 70

8 16 24 32 40 48 56 64 72 80

9 10 18 20 27 30 36 40 45 50 54 60 63 70 72 80 81 90 90 100

Abb. 5.6. Das K l e i n e Einmaleins Bei der Problemanalyse stellt sich heraus, d a ß o f f e n b a r zwei V a r i ablen nacheinander verschiedene Werte annehmen: - Der Multiplikand n i m m t Werte von 1 bis 10 an; er wird bei jeder neuen Zeile u m 1 e r h ö h t . - Der Multiplikator l ä u f t ebenfalls von 1 bis 10; er nimmt i n n e r halb einer Zeile nacheinander diese Werte an; bei Beginn einer neuen Zeile m u ß er wieder bei 1 a n f a n g e n . Ein einzelnes Tabellenelement ergibt sich als Produkt von Multiplikand und Multiplikator. Die Struktur der Lösung stellt sich so dar: - Es sind insgesamt 100 Multiplikationen d u r c h z u f ü h r e n . - Diese 100 R e c h n u n g e n teilen sich in zehn G r u p p e n (entsprechend den Zeilen d e r Ausgabe) zu j e 10 Multiplikationen. - Innerhalb einer Zeile ist der Multiplikand fest; der Multiplikator l ä u f t von 1 bis 10. Ein Zeilenelement ist das Produkt beider Werte. - Von einer Zeile zur nächsten erhöht sich der Multiplikand um 1. Das S t r u k t o g r a m m ist in Abbildung 5.7. abgebildet. Vor dem Beginn einer neuen Zeile wird ein Zeilenvorschub a u s g e f ü h r t .

5. Kapitel: Steuerung des Programmablaufs

W i e d e r h o l e für M u l t i p l i k a n d =

65

1,2,...,10

Zeilenvorschub Wiederhole

für M u l t i p l i k a t o r =

1,2,...,10

Gib M u l t i p l i k a n d * M u l t i p l i k a t o r

aus

Abb. 5.1. Struktogramm "Kleines Einmaleins" Es liegen also zwei ineinander geschachtelte Schleifen vor. Der R u m p f der inneren (Multiplikator-)Schleife, der n u r aus der A u s g a beanweisung besteht, wird f ü r j e d e n Wert des M u l t i p l i k a n d e n z e h n mal a u s g e f ü h r t . Da d e r Multiplikand zehn Werte a n n i m m t , wird der D r u c k b e f e h l h u n d e r t m a l a u s g e f ü h r t , entsprechend den h u n d e r t v e r langten Multiplikationen. In dem folgenden Programm wird der M u l t i p l i k a n d I genannt, der Multiplikator J .

KLEINES_EINMALEINS: PROCEDURE OPTIONS(MAIN); /* Erstellung einer M u l t i p l i k a t i o n s t a b e l l e für das kleine Einmaleins */ DECLARE

(I, J) DECIMAL F I X E D ( 2 ) ;

DO 1=1 TO 10; PUT SKIP; DO J=1 TO 10; END;

PUT LIST(I*J);

/* M u l t i p l i k a n d e n S c h l e i f e */ /* Zeilenvorschub */ /* M u l t i p l i k a t o r S c h l e i f e */

END;

END

KLEINES_EINMALEINS;

Drei Dinge sind im Z u s a m m e n h a n g mit diesem P r o g r a m m a n z u m e r ken: 1) Drei END-Anweisungen treten a u f , je eine f ü r die beiden DOAnweisungen u n d eine am P r o g r a m m e n d e . Während durch die E i n r ü c k u n g des Programmtexts f ü r den menschlichen Leser e r kenntlich ist, zu welcher Anweisung welches END gehört, m u ß es doch eine Regel geben, die den P L / 1 - Ü b e r s e t z e r b e f ä h i g t ,

66

5. Kapitel: Steuerung des Programmablaufs

die ENDs richtig zuzuordnen. Diese Regel lautet: Das erste END schließt die letzte vorausgehende Anweisung, die ein END verlangt, ab, das zweite END die vorletzte, usw. Von den A n weisungen, die ein END verlangen, sind bisher die PROCEDURE- u n d die DO-Anweisung b e k a n n t . Weitere k o m men im Verlauf des Buchs dazu. Die Z u o r d n u n g der ENDs ist im nachfolgend noch einmal abgedruckten Programm K L E I N E S _ E I N M A L E I N S d u r c h Striche am linken R a n d d e u t lich gemacht.

-KLEINES_EINMALEINS: PROCEDURE OPTIONS(MAIN); /* Erstellung einer Multiplikationstabelle für das kleine Einmaleins */ DECLARE (I, J) DECIMAL FIXED(2); r—DO 1=1 TO 10; PUT SKIP; i—DO J=1 TO 10; —END; —END;

PUT LIST(I*J);

/* MultiplikandenSchleife */ /* Zeilenvorschub */ /* MultiplikatorSchleife */

-END KLEINES_EINMALEINS; 2) 3)

E m p f o h l e n w i r d , die Struktur der Schleifen d u r c h Einrücken der Programmzeilen schon optisch e r k e n n b a r zu machen. Wenn Sie das Beispielprogramm ausprobieren, kann es passieren, d a ß die Z a h l e n der Ausgabetabelle a u f g r u n d der mit dem PUT L I S T - B e f e h l v e r b u n d e n e n T a b u l i e r u n g weiter auseinander liegen als in Abbildung 5.6.; möglicherweise passen gar nicht alle zehn Zahlen in eine Zeile. Im übernächsten Kapitel werden Ausgabeanweisungen vorgestellt, mit denen sich die T a belle in k o m p r i m i e r t e r Form darstellen läßt.

5.3. Die I F - A n w e i s u n g zur Entscheidung Das letzte Konstruktionselement f ü r Programme ist die E n t s c h e i dung. Sie ist d a d u r c h gekennzeichnet, d a ß abhängig von einer Bed i n g u n g eine von zwei alternativen Anweisungen oder Anweisungs-

5. Kapitel: Steuerung des Programmablaufs

67

folgen ausgeführt wird. In PL/1 wird die Entscheidung durch die I F - A n w e i s u n g realisiert, die allgemein so aussieht: IF bedingung

THEN ELSE

anweisungl; anweisung2;

Die Bedingung muß dem gleichen Formalismus genügen wie die im Zusammenhang mit der DO WHILE-Anweisung besprochenen Bedingungen (vgl. Abschnitt 5.2.2.1.). I F , THEN und ELSE sind neue Schlüsselwörter. Wirkungsweise: Ist die Bedingung wahr, wird die auf THEN folgende Anweisung ausgeführt. Ist sie falsch, wird die auf E L S E folgende Anweisung ausgeführt. Die jeweils andere Anweisung wird ignoriert. Beispiel: Innerhalb eines Wochenlohnabrechnungsprogramms wird der Bruttolohn aus den geleisteten Arbeitsstunden und dem Stundenlohn berechnet. Wurden mehr als 40 Stunden gearbeitet, werden die über 40 hinausgehenden Stunden mit einem Zuschlag von 25 % auf den Stundenlohn vergütet. Für eine konkrete Stundenzahl sind also zwei Fälle zu unterscheiden: 1) Die Stundenzahl ist kleiner oder gleich 40. Dann berechnet sich der Bruttolohn als Produkt von Stundenzahl und Stundenlohn. 2) Die Stundenzahl ist größer als 40. Dann sind die ersten 40 Stunden normal, die restlichen Stunden mit 25 % Zuschlag zu bezahlen. Eine von zwei Formeln ist also anzuwenden: Brutto = Stundenzahl*Stundenlohn oder Brutto = 40*Stundenlohn + (Stundenzahl-4 0)*Stundenlohn*1.25 Abbildung 5.8. zeigt das zugehörige Struktogramm.

68

5. Kapitel: Steuerung des Programmablaufs

^ ^ ^ ^ ^ ^ ^

Stundenzahl

>

40

?

^ ^ ^ ^ ^ ^ Nein

Ja Brutto = 40 * Stundenlohn + (Stundenzahl - 40) Stundenlohn * 1.2 5

Brutto = Stundenzahl *

*

Stundenlohn

Abb. 5.8. Struktogramm "Überstundenzuschlag" Die entsprechende IF-Anweisung lautet: I F STUNDENZAHL > 4 0 THEN BRUTTO = 40*STUNDENLC>HN + (STUNDENZAHL-40)*STUNDENLOHN*1.25; E L S E BRUTTO = STUNDENZAHL*STUNDENLOHN; Eine einfachere Form der IF-Anweisung wird dann benutzt, wenn nur in einem der beiden möglichen Fälle eine Aktion durchgeführt werden soll, im anderen Fall jedoch nichts getan werden soll. Beispiel, ebenfalls aus der Lohnabrechnung: Jeder, der mehr als 20 Wochenstunden arbeitet, erhält einen steuerfreien Essenszuschuß von DM 5.00. Die beiden Fälle sind: 1) Die Stundenzahl ist größer als 20. Dann erhöht sich der Nettolohn um DM 5.00. 2) Die Stundenzahl ist kleiner oder gleich 20. Dann passiert nichts. Abbildung 5.9. enthält das Struktogramm. Stundenzahl Ja Netto

>

20

? Nein

=

Netto

+

5

Abb. 5.9. Struktogramm "Essenszuschuß" Es gibt zwei Möglichkeiten, diesen Sachverhalt in PL/1 auszudrücken: 1) Weglassen des E L S E und der nachfolgenden Anweisung; allgemein:

S. Kapitel: Steuerung des Programmablaufs

IF

2)

bedingung

THEN

69

anweisung;

Einfügen einer Leeranweisung hinter dem E L S E . Eine Leeranweisung besteht nur aus einem Semikolon. Sie hat keine Wirkung.

IF

bedingung

THEN a n w e i s u n g ; ELSE ;

Das Beispielproblem kann also auf eine der beiden folgenden Arten in P L / 1 formuliert werden: I F STUNDENZAHL > 2 0 THEN NETTO = N E T T O + 5 ; oder I F STUNDENZAHL > 2 0 THEN NETTO = N E T T O + 5 ; ELSE ;

5 . 3 . 1 . Schachtelung von IF-Anweisungen I F - A n w e i s u n g e n können ineinander verschachtelt werden, d.h. sowohl hinter THEN als auch hinter E L S E können wieder I F - A n weisungen stehen. Dieser PL/1-Möglichkeit entspricht in Struktogrammen die Schachtelung von Entscheidungssymbolen. Ein Beispiel findet sich in Abbildung 5.10. A = Ja

?

^

^

^

^ ^ ^ ^ ^ ^ ^ B

Ja C =

0

1

=

0

?

Nein C =

2

Abb. 5.10. Schachtelung von Entscheidungssymbolen - 1 Eine mögliche richtige Codierung dieses Struktogramms ist: I F A = 0 THEN I F B = 0 THEN C = 1 ; ELSE; ELSE C = 2 ;

^

^

Nein

^

70

5. Kapitel: Steuerung des Programmablaufs

Die Regel zur Z u o r d n u n g der E L S E - Z w e i g e zu den I F s lautet: Das erste E L S E wird d e m letzten I F , zu dem noch kein E L S E g e f u n den w u r d e , zugeordnet. Aus dieser Regel folgt, d a ß das obige E L S E mit d e r Leeranweisung notwendig ist. Würde es f e h l e n , d a n n w ü r d e das E L S E C = 2 ; d e m I F B = 0 zugeordnet. Die Codierung I F A = 0 THEN I F B = 0 THEN C = 1 ; ELSE C = 2 ; entspricht also nicht d e m Struktogramm in A b b i l d u n g 5.10., sondern d e m in A b b i l d u n g 5.11. A =

0

?

^

^

Ja

^

^

^

Nein B =

Ja C =

^

1

0

?

C =

^- ' f Nein 2

A b b . 5.11. Schachtelung von Entscheidungssymbolen - 2

5.3.2. Anweisungsgruppen Im THEN- und E L S E - Z w e i g kann jeweils nur eine P L / 1 - A n w e i sung angegeben w e r d e n . Diese Beschränkung ist bei vielen Problem e n hinderlich; wie das folgende Beispiel zeigt, müssen o f t nach Entscheidungen im einen oder anderen Fall m e h r e r e Anweisungen a u s g e f ü h r t werden. Beispiel: In einem A b r e c h n u n g s p r o g r a m m hängen der Rabatt und die F r a c h t kosten vom Warenwert ab. Ist der Warenwert höher als D M 500.00, wird ein Rabatt von 5 % gewährt und die Frachtkosten betragen D M 25.00. Bei einem Warenwert bis D M 500.00 sind Rabatt und Frachtkosten 3 % bzw. D M 10.00. Der R e c h n u n g s b e t r a g wird in beiden Fällen nach d e r bekannten Formel WARENWERT * ( 1 - RABATT) + FRACHT berechnet. A b b i l d u n g 5.12. enthält das Struktogramm der Lösung.

5. Kapitel: S t e u e r u n g des P r o g r a m m a b l a u f s

Warenwert > 500 ?

^ ^ ^ ^ ^ ^

^^^^^^

Ja Rabatt = 0.05

Rabatt = 0.03

Fracht

Fracht = 10

=25

71

Nein

Rechnungsbetrag = Warenwert * (1 - Rabatt) + Fracht Abb. 5.12. M e h r e r e Anweisungen in einer Entscheidung Für solche Fälle bietet P L / 1 die Möglichkeit, eine beliebige Anzahl von A n w e i s u n g e n so zusammenzufassen, d a ß sie als eine einzige A n w e i s u n g gelten. Dies geschieht, indem vor und hinter diese G r u p p e von Anweisungen die Anweisungen DO; und E N D ; gesetzt w e r d e n . Das obige Struktogramm wird also so codiert: I F WARENWERT > 5 0 0 THEN DO; RABATT = 0 . 0 5 ; FRACHT = 2 5 ; END; E L S E DO; RABATT = 0 . 0 3 ; FRACHT = 1 0 ; END; RECHNUNGSBETRAG = WARENWERT * ( 1 - RABATT) + F R A C H T ;

5.4. Ü b u n g e n 1.

Das in Abschnitt 5.2.1. vorgestellte Programm RECHNUNG_3 gibt n u r den Rechnungsbetrag aus. U m die Z u o r d n u n g dieser Beträge zu den entsprechenden A u f t r ä g e n zu erleichtern, soll das Programm so erweitert w e r d e n , d a ß es vor jedem Satz von E i n g a b e d a t e n eine siebenstellige, ganzzahlige A u f t r a g s n u m m e r einliest und diese vor dem Rechnungsbetrag wieder ausdruckt.

2.

G e n a u 20 maximal dreistellige, ganze Zahlen sind einzulesen. D e r e n Summe soll ermittelt w e r d e n , a u ß e r d e m ist der genaue M i t t e l w e r t zu berechnen. Ausgegeben werden die eingelesenen Z a h l e n , die Summe und der Mittelwert, jeweils mit e r l ä u t e r n d e n Texten.

72

5. Kapitel: Steuerung des Programmablaufs

3.

Die in Übung 2 formulierte Aufgabenstellung wird verändert: Statt 20 sollen beliebig viele Zahlen eingelesen werden. Das Ende der Eingabedaten wird daran erkannt, daß die Zahl 999 eingelesen wird. Diese Zahl soll nicht in die Summen- und Mittelwertberechnung eingehen.

4.

Erweitern Sie die Übung 3 aus Kapitel 2: Nach der Formel F = 1 . 8 * C + 32 sollen alle ganzzahligen Celsius-Grade von -20 bis +20 in die entsprechenden Fahrenheit-Grade umgerechnet werden. Ausgegeben werden soll eine Tabelle der Form Celsius Fahrenheit -20 -4.00

5.

Schreiben Sie ein Programm, das alle Kombinationen von 10 DM-Scheinen, 5 D M - , 2 D M - und 1 DM-Stücken bestimmt, die zusammen 20 D M ergeben. Ausgegeben werden soll eine Tabelle: 10 DM 5 DM 2 DM 1 DM

0 0

6.

0 0

0 1

20 18

Erstellen Sie ein Programm, das für Mitarbeiter eines Betriebs Treueprämien in Abhängigkeit vom Alter und von der Dauer der Betriebszugehörigkeit errechnet. In Tabelle 5.4. ist die zu zahlende Treueprämie als Prozentsatz vom Monatsgehalt angegeben. Pro Mitarbeiter werden drei Werte eingelesen: Monatsgehalt (fünfstellig, ganzzahlig), Betriebszugehörigkeit in Jahren (zweistellig, ganzzahlig), Alter in Jahren (zweistellig, ganzzahlig). Ausgegeben werden die eingelesenen Werte und die Treueprämie in D M .

S. Kapitel: Steuerung des Programmablaufs

Alter < 25 25 - < 40 40 - < 50 >= 50

10 Jahre 2 - 1 0 Jahre 10 20 30 40

20 30 40 50

Tab. 5.4. Treueprämien a.

Eine erste Version dieses Programms soll die Berechnung der Prämie f ü r einen Mitarbeiter durchführen.

b.

In der zweiten Version sollen die Prämien f ü r alle Mitarbeiter errechnet werden. Die Zahl der Mitarbeiter ist unbekannt; das Ende der Eingabedaten ist erreicht, wenn f ü r das Monatsgehalt der Wert 9 9 9 9 9 eingelesen wird. Hinweis: Es gibt - wie bei fast allen Problemen - eine große Zahl verschiedener richtiger Lösungen. Für die gestellte Aufgabe läßt sich eine Lösung angeben, die überraschend kurz ist. Sie nimmt u.a. auf die Anordnung der Werte in der Tabelle Bezug!

7.

In Kapitel 4 wurde ein Programm zur Ermittlung der reellen Lösungen der quadratischen Gleichung ax2 + bx + c = 0 vorgestellt, das nur unter den Voraussetzungen a ungleich Null und - 4 a c größer oder gleich Null b anwendbar ist. Erweitern Sie dieses Programm derart, daß diese Voraussetzungen im Programm selbst geprüft werden. Sind beide erfüllt, sollen wie bisher die reellen Lösungen errechnet und ausgegeben werden. Ist a gleich Null, soll nur der Text Es l i e g t k e i n e q u a d r a t i s c h e G l e i c h u n g v o r o ausgegeben werden. Ist b - 4 a c kleiner als Null, soll der Text Die Gleichung h a t komplexe Lösungen ausgegeben werden.

6.

Zeichenketten

Z e i c h e n k e t t e n sind bereits in K a p i t e l 2 a u f g e t r e t e n . Z e i c h e n k e t t e n K o n s t a n t e n sind seitdem dazu v e r w e n d e t w o r d e n , Ergebnisse mit erläuternden T e x t e n zu versehen, somit Programmausgaben insgesamt lesbarer zu gestalten. Es gibt in der betrieblichen Praxis j e d o c h auch e i n e g r o ß e Z a h l von Anlässen, bei denen variable T e x t e zu verarbeiten sind. Soll z.B. unser P r o g r a m m zur Ermittlung v o n R e c h n u n g s b e t r ä g e n in der Praxis zur Rechnungsschreibung e i n g e setzt w e r d e n , dann muß es in m e h r f a c h e r Hinsicht e r w e i t e r t w e r den: -

D i e B e z e i c h n u n g d e r Ware, f ü r d i e d i e R e c h n u n g gestellt w i r d , muß mit a u f g e f ü h r t werden. Dieser Warenname ist o f f e n s i c h t l i c h eine Z e i c h e n k e t t e .

-

N a m e und Rechnung.

-

A n g a b e n über Bankverbindungen, Versandarten, usw. können Bestandteile von R e c h n u n g e n sein.

Anschrift

des

Rechnungsempfängers

gehören

zur

Zahlungsfristen

Diese Daten können sich, genau w i e die numerischen Daten, von R e c h n u n g zu R e c h n u n g ändern. Sie müssen also ebenfalls als V a r i ablen in den P r o g r a m m e n v o r k o m m e n .

Lernziel: In diesem K a p i t e l w i r d ein neuer V a r i a b l e n t y p e i n g e f ü h r t , der als Werte nicht Z a h l e n , sondern Zeichen hat. Sie sollen lernen, mit d i e sen neuen V a r i a b l e n , f ü r d i e es spezielle Operationen gibt, u m z u g e hen.

6.1. Z e i c h e n k e t t e n - V a r i a b l e n V a r i a b l e n , deren Werte Zeichenketten sind, w e r d e n allgemein einbart mit:

DECLARE

name

ver-

CHARACTER(n);

C H A R A C T E R ist ein neues Attribut. D i e A n z a h l der Z e i c h e n , die in der Variablen gespeichert werden können, w i r d hinter d e m Wort

6. Kapitel: Zeichenketten

75

CHARACTER in K l a m m e r n angegeben; dieses n h e i ß t a u c h L ä n g e der Zeichenkette. So v e r e i n b a r t e Z e i c h e n k e t t e n - V a r i a b l e n n e n n t m a n Z e i c h e n k e t t e n f e s t e r L ä n g e , d a sie stets g e n a u n Z e i c h e n e n t h a l t e n . In vielen A n w e n d u n g e n sind d i e in e i n e r V a r i a b l e n a b z u s p e i c h e r n d e n Z e i c h e n k e t t e n - W e r t e j e d o c h von w e c h s e l n d e r Länge (z.B. N a m e n , A r t i k e l b e z e i c h n u n g e n ) ; f ü r diese Fälle gibt es in P L / 1 die Z e i c h e n k e t t e n v a r i a b l e r Länge: eine solche Variable w i r d v e r e i n b a r t mit:

DECLARE

name

CHARACTER(n)

VARYING;

Das zusätzliche A t t r i b u t V A R Y I N G gibt an, d a ß die L ä n g e der Z e i c h e n k e t t e n - V a r i a b l e n j e nach ihrem aktuellen Wert v a r i i e r e n kann; die A n g a b e n b e z e i c h n e t hier die maximal e r l a u b t e L ä n g e der Z e i chenkette. Beispiel: Mit d e n V e r e i n b a r u n g e n DECLARE NACHNAME_1 C H A R A C T E R ( 1 0 ) , NACHNAME_2 C H A R A C T E R ( 1 0 ) VARYING; w e r d e n zwei Z e i c h e n k e t t e n - V a r i a b l e n n a m e n s N A C H N A M E _ 1 u n d NACHNAME_2 angelegt. W ä h r e n d die in N A C H N A M E _ 1 g e s p e i c h e r ten Werte stets g e n a u 10 Z e i c h e n lang sind (wie das e r r e i c h t w i r d , ist G e g e n s t a n d des n ä c h s t e n A b s c h n i t t s ) , ist die L ä n g e von NACHNAME_2 v e r ä n d e r l i c h u n d abhängig v o m aktuellen Wert.

6.2. Verarbeitung von Zeichenketten Bevor in d e n n ä c h s t e n b e i d e n A b s c h n i t t e n O p e r a t i o n e n u n d F u n k t i o n e n b e h a n d e l t w e r d e n , die speziell f ü r Z e i c h e n k e t t e n gelten, w e r d e n zunächst die in d e n z u r ü c k l i e g e n d e n K a p i t e l n vorgestellten S p r a c h e l e m e n t e , soweit sie nicht auf n u m e r i s c h e G r ö ß e n b e s c h r ä n k t s i n d , hinsichtlich ihrer A n w e n d u n g auf Z e i c h e n k e t t e n u n t e r s u c h t . Die f o l g e n d e n S p r a c h e l e m e n t e sind auch auf Z e i c h e n k e t t e n a n w e n d bar: - Wertzuweisung, - E i n - und Ausgabe mit GET L I S T und PUT L I S T , - B e d i n g u n g e n (in DO W H I L E - und I F - A n w e i s u n g e n ) .

76

6. Kapitel: Zeichenketten

Wertzuweisung: Die allgemeine Form der Zuweisung variable

=

ausdruck;

gilt auch f ü r Zeichenketten-Variablen. Der Ausdruck auf der rechten Seite ist dann eine Zeichenkette oder ergibt nach seiner Auswertung eine solche. Daß eine Zeichenfolge in Apostrophe eingeschlossen wird, ist schon aus dem Abschnitt 2.4. über Zeichenketten-Konstanten bekannt. Diese Apostrophe gehören nicht zur Zeichenfolge, sondern begrenzen sie. Die Wirkung der Wertzuweisung ist bei Variablen fester und variabler Länge verschieden. Es gelten wieder die Vereinbarungen DECLARE NACHNAME_1 C H A R A C T E R ( I O ) , NACHNAME_2 CHARACTER(10) VARYING; NACHNAME

M e

i

e

1

(feste)

r

Länge 10

NACHNAME 2

M e

i

e

r

(aktuelle)

Länge 5

Abb. 6.1. Zeichenketten-Variablen fester und variabler Länge Die Zuweisungen NACHNAME_1 = ' M e i e r ' ; NACHNAME_2 = ' M e i e r ' ; bewirken: - In den ersten (linksbündigen) fünf Zeichen von NACHNAME_1 wird die Zeichenfolge M e i e r abgelegt. Die restlichen fünf Zeichen werden mit Leerzeichen (Blanks) gefüllt, so daß die feste Länge 10 erreicht wird.

6. Kapitel: Zeichenketten

77

-

In NACHNAME_2 wird die Zeichenfolge M e i e r gespeichert. Gleichzeitig wird automatisch die aktuelle Länge von NACHNAME_2 auf 5 gesetzt. (Auf diese aktuelle Länge kann mit der Standardfunktion LENGTH zugegriffen werden; vgl. A b schnitt 6.2.2.) Abbildung 6.1. stellt die Inhalte der beiden Variablen bildlich dar. Werden diesen Variablen Werte zugewiesen, die länger als 10 Zeichen sind, geschieht bei beiden Typen das Gleiche: Die über 10 hinausgehenden Zeichen werden - ohne Warnung! - rechts abgeschnitten. Nach den Zuweisungen NACHNAME_1 = 1 C o u r t s - M a h l e r • ; NACHNAME_2 = ' C o u r t s - M a h l e r ' ; steht in beiden Variablen die Zeichenfolge C o u r t s - M a h . Der Inhalt einer variabel langen Zeichenketten-Variable kann auch gelöscht werden, indem man ihr eine Zeichenkette der Länge 0 zuweist. Diese besondere Zeichenkette heißt Nullkette: sie wird dargestellt durch 1 1 , also durch zwei Apostrophe ohne dazwischenliegende Zeichen. Ein-/Auseabe: Zeichenketten werden, genau wie numerische Werte, mit GET L I S T - A n w e i s u n g e n eingelesen und mit PUT L I S T - A n w e i s u n g e n ausgegeben. Einzulesende Werte müssen in Apostrophe eingeschlossen werden. Ausgedruckt werden sie ohne Apostrophe. Bedingungen: In Vergleichen, wie sie in DO WHILE- oder I F - A n w e i s u n g e n a u f treten, können auch Zeichenketten-Variablen miteinander oder mit Zeichenketten-Konstanten verglichen werden. Dazu ist es erforderlich, die Vergleichsoperatoren auf Zeichenketten auszudehnen. Folgende Regeln gelten: - Zeichenketten werden zeichenweise, beginnend mit dem ersten (am weitesten links stehenden) Zeichen, verglichen. Der Vergleich endet, wenn eine Ungleichheit festgestellt wird, oder, wenn alle Zeichen übereinstimmen, am Ende der Zeichenketten. Im ersten Fall sind die Zeichenketten ungleich, im zweiten Fall gleich. Beispiel: Die beiden Zeichenketten ' M e i e r * und ' M e y e r 1 sind ungleich. Dieses Ergebnis wird im dritten Einzelvergleich erzielt, wenn die Zeichen i und y betrachtet werden.

78

-

6. Kapitel: Zeichenketten

Über Gleich und Ungleich hinaus gibt es noch eine K l e i n e r / Größer-Relation. Diese Relation wird durch die (willkürliche) Ordnung aller PL/1-Zeichen geschaffen. Einzelheiten dieser Ordnung können implementierungsabhängig sein. Üblich ist die folgende Ordnung der Zeichen: Sonderzeichen < 0 < 1 < ... < 9 < A < B < . . .