Lazarus/Verzweigungen
Inhaltsverzeichnis
Wenn-Dann-Sonst (If-then-else)
Bisher wurden die Computerprogramme strikt von oben nach unten abgearbeitet. Das ist aber nicht immer wünschenswert. Zum Beispiel kann es sein, dass bestimmte Programmteile nur dann ausgeführt werden, wenn bestimmte Bedingungen auch erfüllt sind. Wir alle kennen z.B. Passwort-Abfragen, bei denen Funktionen eines Programms oder einer Website nur dann funktionieren, wenn man das richtige Passwort angibt.
Beispiel
Wir betrachten das einfache Beispiel eines Lazarus-Programms mit zwei Edit-Feldern, Edit1 und Edit2 und einem Button Button1. Wenn der Button1 gedrückt wird, soll der Computer die Eingabe in Edit1 überprüfen. Steht darin das richtige Passwort ("geheim"), so soll in Edit2 angezeigt werden: "Sie sind angemeldet!"
1 unit passwort;
2
3 {$mode objfpc}{$H+}
4
5 interface
6
7 uses
8 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
9 ExtCtrls;
10
11 type
12
13 { TForm1 }
14
15 TForm1 = class(TForm)
16 Button1: TButton;
17 Edit1: TEdit;
18 Edit2: TEdit;
19 procedure Button1Click(Sender: TObject);
20 private
21 { private declarations }
22 public
23 { public declarations }
24 end;
25
26 var
27 Form1: TForm1;
28
29 implementation
30
31 {$R *.lfm}
32
33 { TForm1 }
34
35 procedure TForm1.Button1Click(Sender: TObject);
36 begin
37 if Edit1.Text='geheim'
38 then Edit2.Text:='Sie sind angemeldet';
39 end;
40
41 end.
Das Programm ist allerdings noch nicht besonders benutzerfreundlich. Gibt der Benutzer z.B. ein falsches Passwort ein, so erhält er gar keine Nachricht. Es passiert einfach nichts.
Das kann man ändern. Im Falle, dass die Eingabe nicht 'geheim' lautet, soll in Edit2 die Bemerkung: 'Falsches Passwort' ausgegeben werden.
35 procedure TForm1.Button1Click(Sender: TObject);
36 begin
37 if Edit1.Text='geheim'
38 then Edit2.Text:='Sie sind angemeldet'
39 else Edit2.Text:='Falsches Passwort';
40 end;
Wichtige Anmerkungen
- Achtung: vor "else" steht nie ein Semiklon. Das Semikolon beendet einen Befehl; die ganze If-then-else-Konstruktion ist jedoch im Grunde ein einzelner Befehl; das Semikolon steht erst danach.
- Man beachte das Gleichheitszeichen in if Edit1.Text='geheim'. Es ist ein einzelnes Gleichheitszeichen ohne Doppelpunkt. Es beschreibt auch etwas ganz anderes als eine Wertzuweisung: Es beschreibt einen Bedingung. Es gibt nur zwei Möglichkeiten: Die Bedingung ist erfüllt (wahr, engl. true) oder eben nicht (falsch, engl. false).
- Wenn Du Dich an das Kapitel Lazarus/Variablen_und_Komponenten erinnerst, kamen da Variablen vom Typ boolean vor, die genau diese beiden möglichen Werte hatten. Tatsächlich könnte man einer Variable b vom Typ boolean mit b:=(Edit1.Text='geheim'); einen Wert zuweisen, je nachdem, ob der Text der richtige war oder nicht.
Mehrere Anweisungen zu einem Block gruppieren
Bisher wird in jedem der beiden Fälle genau eine einzelne Anweisung ausgeführt. Es kann aber leicht sein, dass nur im Fall einer erfüllten (oder auch nicht erfüllten) Bedingung gleich mehrere Anweisungen ausgeführt werden sollen. Im nächsten Beispiel soll z.B. bei einer falschen Eingabe auf dem Button die Beschriftung zu 'Nochmal versuchen' geändert weden:
36 procedure TForm1.Button1Click(Sender: TObject);
37 begin
38 if Edit1.Text='geheim'
39 then Edit2.Text:='Sie sind angemeldet'
40 else begin
41 Edit2.Text:='Falsches Passwort';
42 Button1.Caption:='Nochmal versuchen';
43 end
44 end;
Die beiden Anweisungen zum Verändern von Edit2.Text und Button1.Caption sind durch ein begin und ein end umrahmt. Manche Leute sprechen von einem Programm-Block. Natürlich kann auch hinter then ein Programm-Block stehen: Aber Vorsicht: Hinter diesem end steht dann wieder kein Semikolon.
Vergleiche von Zahlen
Natürlich kann man nicht nur Zeichenketten miteinander vergleichen, sondern auch Zahlen. Neben der reinen Gleichheit gibt es auch andere Vergleichsoperatoren:
Vergleichsoperator | Bedeutung |
---|---|
= | gleich |
<= | kleiner oder gleich |
>= | größer oder gleich |
<> | ungleich |
Verknüpfung von Bedingungen
In einer if-Abfrage können auch Bedingungen abgefragt werden, die aus mehreren Teilbedingungen bestehen, die durch logische Verknüpfungen verbunden sind. Diese Verknüpfungen sind
Vergleichsoperator | Bedeutung |
---|---|
Bedingung1 and Bedingung2 | Gilt dann und nur dann, wenn beide Bedingungen erfüllt sind. |
Bedingung1 or Bedingung2 | Gilt bereits dann, wenn eine der beiden Bedingungen erfüllt sind, aber auch dann, wenn beide erfüllt sind. |
Bedingung1 xor Bedingung2 | Gilt dann und nur dann, wenn genau eine der beiden Bedingungen erfüllt sind, aber nicht dann, wenn keine oder beide erfüllt sind. |
not Bedingung | Gilt dann, wenn die Bedingung selbst genau nicht gilt. |
Es ist generell sinnvoll, die einzelnen Bedingungen jeweils in Klammern zu setzen. Erstens erhöht es die Übersichtlichkeit und zweitens kann es bei fehlenden Klammern auch zu Problemen mit dem Compiler kommen.
Mehrfach-Fallunterscheidungen
Bisher wurde nur immer eine Bedingung geprüft und je nachdem ob sie erfüllt war (oder auch nicht) eine bestimmte Abfolge von Befehlen ausgeführt. Damit lassen sich im Grunde alle möglichen Abfragen realisieren, wenn auch manchmal recht umständlich. Angenommen, man wollte für einen Monat (angegeben wäre die Nummer des Monats im Jahr) wissen, wie viele Tage er hat (wir vernachlässigen Schaltjahre). Folgendes Programmstück könnte die Aufgabe lösen. Trotzdem erscheint es eben etwas umständlich mit den ganzen or-Verknüpfungen zwischen den Einzelbedingungen.
1 procedure TForm1.Button1Click(Sender: TObject);
2 var nummer, anzahltage : integer;
3 begin
4 nummer:=StrToInt(Edit1.Text);
5 if (nummer=2) then anzahltage:=28
6 else if ((nummer=4)
7 or (nummer=6)
8 or (nummer=9)
9 or (nummer=11)) then anzahltage:=30
10 else anzahltage:=31;
11 label1.Caption:=IntToStr(anzahltage);
12 end;
Das Gleiche tut jedoch auch folgendes Programm, das für die Werte der Variablen "nummer" eine entsprechende Fallunterscheidung vornimmt.
1 procedure TForm1.Button1Click(Sender: TObject);
2 var nummer, anzahltage : integer;
3 begin
4 nummer:=StrToInt(Edit1.Text);
5 case nummer of
6 2: anzahltage:=28;
7 4,6,9,11 : anzahltage:=30;
8 else anzahltage:=31;
9 end; // Das "case" ist sozusagen das zugehörige "begin"
10 label1.Caption:=IntToStr(anzahltage);
11 end;
- Einführung
- Technisches
- Komponenten, Eigenschaften, Ereignisse
- Computer-Mathematik
- Verzweigungen
- Spielen mit dem Zufall
- Schleifen
- Computer-Graphik
- Geschachtelte Verzweigungen und Verzweigungen in Schleifen
- Prozeduren, Funktionen und Bibliotheken
- Felder (Arrays)
- Zeichen (Char) und Zeichenkette (String)
- Dateien
- Graphische Komponenten