Claus SchönleberHitchhacker´s Guide To PASCAL [Vol. 1] |
||||||||||
|
[ Start | Beispielprogramme Download | Home ] | |||||||||
InhaltCompilerProgrammieren Datentypen, Variablen, Standardfunktionen Logik Verzweigung, Strukturierung Schleifen Felder (Arrays) Verteiler: CASE Zeichenketten (Strings) Textdateien Module (Prozeduren, Funktionen) Anhang (Operatoren, abgeleitete Funktionen)
|
SchleifenAußer Verzweigungen braucht man häufig Konstruktionen, die viele Wiederholungen der gleichen oder einer ähnlichen Anweisungsliste ermöglichen. Das erledigen Schleifen.
ZählschleifenDie erste Schleife, die Sie kennenlernen sollen, ist die Zählschleife, die auch manchmal "FOR-Schleife" genannte wird.Eine "FOR-Schleife" sieht folgendermaßen aus: FOR <variable> := <ausdruck> TO <ausdruck> DO <block>Dabei wird die <variable> Laufvariable genannt, welcher der erste <ausdruck> als Startwert zugewiesen wird. Im zweiten <ausdruck> wird der Endwert dargestellt. Meist bestehen beide Ausdrücke nur aus Konstanten oder einzelnen Variablen. Der Typ von <variable> kann integer, boolean, char oder jeder selbst definierte Typ sein (siehe später). Die Schrittweite ist vordefiniert (+1) und in dieser Art der Schleife nicht änderbar! Der Startwert muß natürlich kleiner sein als der Endwert. Die Alternative ist einzig eine umgekehrte Zählweise. Wenn die Schleife abwärts zählen soll, tauscht man einfach das TO gegen ein DOWNTO aus. Damit wählt man die Schrittweite -1. In diesem Fall muß der Startwert größer sein als der Endwert. Ein erstes kleines Beispiel für eine Zählschleife: PROGRAM for_schleife; VAR index,finish : integer; BEGIN finish := 10; writeln ('Zählschleifenbeispiel'); FOR index := 1 TO finish DO writeln ('Inhalt von index: ',index); writeln ('Ende der Schleife'); writeln ('index nach der Schleife: ',index); END.Die Funktionsweise dieser Schleife ist wie folgt:
Es ist nicht nur schlechter Programmierstil, es ist auch abhängig vom Compiler, ob und auf welche Weise das funtkioniert. Das bedeutet, daß Sie innerhalb einer Schleife der Laufvariablen keinen Wert zuweisen dürfen. Wenn Sie innerhalb einer Schleife den Wert der Laufvariablen unbedingt ändern müssen, benutzen Sie am besten eine der anderen Schleifenkonstruktionen und bauen dort selbst eine Zählvariable ein. Auch "FOR-Schleifen" kann man schachteln. Vielleicht ist an dieser Stelle noch nicht einsehbar, warum man das machen müßte, aber man sollte sich wenigstens mit der Funktionsweise vertraut machen. PROGRAM doppel_schleife; VAR a,b,finish : integer; BEGIN finish := 10; writeln ('Zählschleifenbeispiel'); FOR a := 1 TO finish DO BEGIN writeln ('Die innere Schleife beginnt erneut...'); FOR b := 1 TO finish DO writeln ('a = ',a,' b = ',b); END; writeln ('Ende der Schleife'); END.Wie funktioniert das? Ganz einfach! Der Inhalt der äußeren Schleife ist, abgesehen von der Textausgabe, die 10 mal ausgeführt wird, die innere Schleife. Somit wird die innere Schleife 10 mal vollständig abgearbeitet. Die innere Schleife einmal vollständig abzuarbeiten bedeutet, die "writeln"-Prozedur 10 mal auszuführen. Ergo dessen wird die "writeln"-Prozedur 10 mal 10 gleich 100 mal ausgeführt. Die Voraussetzung für solche Zählschleifen ist die Kenntnis der Anzahl der Durchläufe. Nur wenn auf irgendeine Weise vor dem Beginn der Schleife berechenbar ist, wie oft der Schleifenblock durchzuführen ist, kann sie eingesetzt werden. Das ist aber nicht immer möglich. Dann kommen die beiden anderen Schleifenarten zum Einsatz. Die WHILE-SchleifeDiese Schleife benötigt ebenfalls einen logischen Ausdruck, der aber jetzt explizit hingeschrieben werden muß. Bei der Zählschleife war das nicht notwendig, da die Schleife den Vergleich zwischen Inhalt der Laufvariablen und Endwert selbständig vornimmt.Hier kann man jede beliebige Bedingung verwenden. Das sieht dann so aus: WHILE <logischer ausdruck> DO <block>Die Funktionsweise ist wiederum höchst einfach. Solange die Auswertung von <logischer ausdruck> das Ergebnis true liefert, wird der <block> wiederholt ausgeführt. Kommt als Ergbenis false heraus, wird mit der dem Schleifenblock folgenden Anweisung weitergemacht. Wichtig an dieser Schleifenart ist die Tatsache, daß die Abbruchbedingung vor dem Eintritt in die Schleife geprüft wird. Das bedeutet, daß die Schleife gar nicht erst ausgeführt wird, wenn die Abbruchbedingung schon von Anfang an false liefert. Man braucht das in vielen Fällen, um Fehlfunktionen zu verhindern. Solche Schleifen heißen abweisend. Ein Beispiel. Das Programm soll zunächst nichts anderes machen als das vorige "FOR"- Beispiel (allerdings nur dreimal, stat zehnmal): Da wir die WHILE-Schleife hier als Zählschleife "mißbrauchen", müssen wir eine Laufvariable selbst definieren und auch selbst verwalten. Das bedeutet, sie muß initialisiert werden (mit einem Anfangswert versehen werden), sie muß explizit durch eine Anweisung hochgezählt werden (a := succ (a)) und es muß die Abbruchbedingung explizit aufgeführt werden. Hier ist es jedoch möglich die Schrittweite beliebig zu wählen. Indem wir den Typ der Variablen "a" auf real ändern, ist es sogar möglich, in gebrochenen Schritten zu arbeiten.PROGRAM while_schleife; VAR a,finish : integer; BEGIN finish := 3; writeln ('Die 1. WHILE-Schleife'); a := 1; WHILE (a <= finish) DO BEGIN writeln ('a = ',a:2,' Abbruchbed.: ',a <= finish); a := succ (a); END; writeln ('Werte nach dem Ende der Schleife:'); writeln ('a = ',a:2,' Abbruchbed.: ',a <= finish); END. Um Ihnen zu zeigen, wie die Auswertung der Abbruchbedingung abläuft,
wird das Ergebnis des logischen Ausdrucks jedesmal in der Schleife und
einmal nach dem Schleifenende angezeigt. Was dann ausgegeben wird? Ganz
einfach! Es werden die Werte true oder false ausgegeben, je nach Ergebnis.
Die Bildschirmausgabe sieht dann so aus:
Nun ist der Sinn der WHILE-Schleife ja nicht gerade im Zählen zu
suchen; dafür gibt es die FOR-Schleife. Wir wollen also ein zwar
PROGRAM while_schleife2; VAR zahl : integer; zeichen : char; buchstabe : boolean; BEGIN zahl := 1; writeln ('Beliebigen Buchstaben (A..Z) eingeben: '); readln (zeichen); buchstabe := (zeichen >= 'A') AND (zeichen =< 'Z'); IF NOT buchstabe THEN writeln ('Das war kein großer Buchstabe!') ELSE BEGIN WHILE (chr (zahl + 64) < zeichen) DO zahl := succ (zahl); writeln ('Der Buchstabe war: ',zeichen); writeln ('Nummer ',zahl,' im Alphabet.'); END; END.Was das Programm macht? Es zählt auf sehr umständliche Weise, an wievielter Stelle ein Großbuchstabe im Alphabet steht. Da nicht bekannt ist, welcher Buchstabeeingegeben wird, kann man keine FOR-Schleife verwenden (es sind natürlich auch andere Lösungen möglich). Sobald der Buchstabe erreicht ist, kann mit dem Zählen aufgehört werden. Eine kleine Bemerkung zu den beiden logischen ausdrücken: Die Variable buchstabe: Hier wird geprüft, ob das eingegebene Zeichen im erlaubten Bereich ('A'..'Z') liegt. Wenn nicht, erfolgt eine Fehlermeldung. Andernfalls erfolgt die Bearbeitung. Solche Fehlerbehandlungen sind notwendig und müssen in jedem Programm dafür sorgen, daß der Anwender nicht mit einem unbeabsichtigten und fehlerhaften Programmende konfrontiert wird. Wir werden noch andere kennenlernen. Die Funktion chr (zahl + 64): Um von der bisher berechneten Nummer auf den Code des dazugehörenden Buchstabens zu schließen, muß die Konstante 64 addiert werden, da die Codes der Großbuchstaben im Bereich 65 bis 90 liegen. Dadurch können wir auf den bisher erreichten Buchstaben schließen und ihn mit dem eingegebenen vergleichen. Die REPEAT..UNTIL-SchleifeDiese Form der Schleife hat sehr viel mit der WHILE-Schleife gemeinsam. Es gibt jedoch zwei gravierende Unterschiede, und der ist es, der die REPEAT-Schleife rechtfertigt. Um die Unterschiede zwischen beiden Schleifenarten klar zu machen, seien sie hier in einer Tabelle gegenübergestelllt:
Man sieht es deutlich in der Tabelle: Die REPEAT- Schleife arbeitet,
bis die Abbruchbedingung wahr ist, die WHILE-Schleife arbeitet,
Im übrigen gibt es hier noch eine Besonderheit: Der Schleifenblock muß nicht in BEGIN und END eingeschlossen werden, da die beiden PASCAL-Worte REPEAT und UNTIL den Block schon eindeutig klammern! Hier können wir also auf die übliche Blockklammerung verzichten, was die Übersichtlichkeit, so finde ich jedenfalls, wieder erhöht, da diese Form der Schleife sofort im Quelltext erkannt werden kann. Nun also auch ein Beispiel für eine REPEAT..UNTIL- Schleife. Solche Schleifen haben den Vorteil, daß Variablen in der Abbruchbedingung nicht initialisiert werden müssen, weil sie ihren Wert oft erst in der Schleife bekommen! Deswegen wird diese Schleife gerne bei Eingabroutinen verwendet, um fehlerhafte Eingaben zu vermeiden und die Eingabeaufforderung wiederholen zu können. PROGRAM repeat_beispiel; VAR c : char; buchstabe : boolean; BEGIN writeln ('Simples REPEAT-Beispiel:'); REPEAT write ('Buchstaben eingeben: '); readln (c); buchstabe := ((c >= 'A') AND (c =< 'Z')) OR ((c >= 'a') AND (c =< 'z')) UNTIL buchstabe; writeln ('Herzlichen Glückwunsch!'); END.Zugegeben, das Programm tut nicht sehr viel. Aber wie immer in solch einem Fall wollen wir ja nur die Funktionsweise der besprochenen Struktur erkennen. Mit der Variablen "buchstabe" prüfen wir die Einhaltung des Bereichs, diesmal große und kleine Buchstaben. Versuchen Sie als Übung nachzuvollziehen, wie der logische Ausdruck arbeitet. Mit REPEAT..UNTIL werden oft ganze Programme oder große Teile eingeschlossen, um eine Wiederholung zu ermöglichen, wie wir noch sehen werden.
|
|||||||||
|
(c) 2001 Schoenleber.com |