Home » Tutorials » Object Pascal/RTL » Delphi-Crashkurs

Delphi-Crashkurs

Kontrollstrukturen

Kontrollstrukturen sind eine der wichtigsten Bestandteile jeder Programmiersprache. Kontrollstrukturen bieten dem Programmierer die Möglichkeit, den Fluss des Programmes zu beeinflussen. Ein Programm kann mittels Kontrollstrukturen gewisse Passagen mehrmals ausführen, ohne dass diese Passagen mehrmals geschrieben werden müssen. Es ist auch möglich, Verzweigungen in ein Programm einzubauen, sodass unter bestimmten Bedingen mal die eine und mal die andere Passage ausgeführt wird.
Bevor man jedoch eine dieser Kontrollstrukturen vorstellen kann, muss man sich erst einmal anschauen, wie man überhaupt eine solche „Passage“ definiert, denn das Programm kann ja nicht wissen, welche Programmzeilen man als Einheit betrachtet. Dies macht man mit den Befehlen „begin“ und „end“.

„begin“ und „end“

Zu diesem Zeitpunkt des Crashkurses wird Ihnen die Verwendung von „begin“ und „end“ wahrscheinlich noch sehr abstrakt vorkommen, da die Kontrollstrukturen, welche auf diese beiden Befehle angewiesen sind, noch nicht klar sind. Aber das sollte kein Problem darstellen, denn die beiden Befehle erklären sich sowieso fast von alleine.
Wenn man ein Programm schreibt, arbeit man oft mit Programmteilen, die man gerne als Einheit betrachten möchte. Dies sieht man z.B. an den Quelltexten, welche Sie für die Button-Klicks geschrieben haben. Dort erscheint erst einmal die Deklaration der Variablen und dann sollen alle nachfolgenden Befehle in einem ausgeführt werden.
Und dort kommen auch schon „begin“ und „end“ zum Einsatz. Denn mit ihnen macht man dem Programm klar, welche Programmzeilen zu dem Button-Klick gehören. Dies macht man, indem man einen Bereich definiert, in dem sich die zugehörigen Programmzeilen befinden. Den Anfang dieses Bereichs markiert man mit einem „begin“ und das Ende dieses Bereichs mit einem „end“.
Und so macht man es mit allen Quellcode-Passagen, die man bestimmen will. Anfang und Ende werden mit „begin“ und „end“ markiert. Dabei sieht der Quelltext so aus:

begin
  befehl1;
  befehl2;
  {...}
  befehl21;
  befehl22;
end;

Bitte beachten Sie, dass niemals ein Semikolon hinter ein „begin“ kommt. Eine so klare Aussage kann man für das Semikolon hinter dem „end“ nicht treffen. In den allermeisten Fällen macht man ein Semikolon dahinter, in Ausnahmen jedoch nicht. Auf diese Ausnahmen wird an den jeweiligen Stellen hingewiesen.
Nachdem „begin“ und „end“ nun klar sein sollten, sollen nun ein paar der wichtigsten Kontrollstrukturen hier vorgestellt werden. Den Anfang macht dabei die Verzweigungen. Diese werden primär mittels einer if-Anweisung realisiert, manchmal auch mit der case-Anweisung.

if, case und Bool’sche Ausdrücke

if-Anweisung – Die Erste

Zuerst ein bisschen Praxis. Bauen Sie noch einmal ein Programm zusammen, welches dem obigen äußerlich exakt gleicht, tippen Sie jedoch noch keinen Quelltext ein. Der kommt erst gleich. Dieses mal soll nämlich keine Addition der beiden Werte erfolgen, sondern es soll herausgefunden werden, welche der beiden Zahlen die Größere ist.
Dazu müssen zuerst einmal wieder die Zahlen deklariert werden (also die Auflistung nach „var“). Dies können Sie schonmal erledigen, die Summe brauchen wir diesmal nicht. Sie sollten die Variablen dieses mal auch nicht als Integer deklarieren, sondern als Real, denn dieses Mal sollen auch nicht-ganze Zahlen verarbeitet werden. Und auch die Zeilen, um die Zahlen aus den Edit-Felder einzulesen, können Sie schonmal hinschreiben. Der Befehl, den Sie statt StrToInt verwenden sollten, lautet für nicht-ganze Zahlen StrToFloat. Die Verwendung ist die Gleiche.
So, nachdem das erledigt ist, geht es an die Fallunterscheidung. Wie soll diese genau aussehen? So!

  • Wenn die beiden Zahlen gleich sind, soll das Label „gleich“ anzeigen.
  • Ist „zahl1“ kleiner als „zahl2“, so soll das Label „kleiner“ anzeigen.
  • Ist „zahl2“ kleiner als „zahl1“, so soll das Label „größer“ anzeigen.

Im Grunde genommen soll im Label also das Verhältnis des ersten Wertes zum Zweiten angezeigt werden. Dies kann man so machen:

procedure TForm1.Button1Click(Sender: TObject);
var zahl1, zahl2 : Real;
begin
  zahl1 := StrToFloat(edit1.text);
  zahl2 := StrToFloat(edit2.text);

  if zahl1 = zahl2 then
    label1.caption := 'gleich';

  if zahl1 < zahl2 then
    label1.Caption := 'kleiner';

  if zahl2 < zahl1 then
    label1.Caption := 'größer';
end;

Hier können Sie auch gleich mal kontrollieren, ob die Deklaration und das Einlesen der Werte bei Ihnen richtig ist. 😉
Die ersten Zeilen müssen nicht mehr erklärt werde, da sie im Grunde genommen die selben wie im vorigen Abschnitt sind, mit ganz kleinen Änderungen. Der erste (und einzige) Code-Abschnitt, der erklärt werden solllte, ist folgender:

if zahl1 = zahl2
  then label1.caption := 'gleich';

Dies ist eine if-Anweisung. In der momentanen Fassung kann man dabei noch nicht von einer Verzweigung, sondern nur von einer Bedingung sprechen, doch die Verzweigung wird im Laufe dieses Abschnitts noch eingeführt. Um eine if-Anweisung zu verstehen, muss man sich erst einmal mit den so genannten „Bool’schen Ausdrücken“ beschäftigen.

Exkurs – Bool’sche Ausdrücke

Ein Bool’scher Ausdruck ist ein Wahrheitswert (in Delphi durch den Variablentyp „Boolean“ vertreten). Er ist entweder „wahr“ oder „falsch“. Dazwischen gibt es nichts. Die Aussage „Es regnet im Moment!“ ist entweder wahr oder falsch. Aber nichts dazwischen. Genauso ist die Aussage „Ich habe genauso viel Geld im Portemonnaie wie Sie!“ wahr oder falsch. Nun kann man das Geld in meinem Portemonnaie mit „zahl1“ bezeichnen und das in Ihrem mit „zahl2“. Dann erhält man aus obiger Aussage die Gleichung: „zahl1 = zahl2“.
Bool’sche Ausdrücke sind jedoch nicht immer so einfach. Denn man kann aus zwei Bool’schen Aus­drücken wiederrum einen dritten Bool’schen Ausdruck bilden, indem man die beiden verknüpft. Wie man das macht ist völlig intuitiv verständlich:

procedure TForm1.Button1Click(Sender: TObject);
var newBoolean, boolean1, boolean2 : Boolean;
begin
  newBoolean := boolean1 and boolean2;
  newBoolean := boolean1 or boolean2;
  newBoolean := not boolean1;
  newBoolean := boolean1 xor boolean2;
end;

Wie man sieht, kann man Bool’sche Ausdrücke über „und“, „oder“ und „nicht“ miteinander verknüpfen. Dies geschieht, wie wir es im Alltag gewohnt sind und muss wohl nicht erklärt werden. Das einzige, was eventuell kurz angerissen werden sollte, ist „xor„. Dies steht für „exclusive or„, also „ausschließendes oder„. Im Alltag nutzt man es durch die Satzkonstruktion „entweder … oder“, was deutlich macht, wie es funktioniert: „newBoolean“ ist nur dann wahr, wenn entweder „boolean1“ oder „boolean2“ wahr sind, aber nicht beide.
Selbstverständlich kann man auch zusammengesetzte Bool’sche Ausdrücke wieder zusammensetzen, oder Konstruktionen mit mehreren Verknüpfungsoperatoren machen. Dabei sollte man jedoch immer darauf achten, dass klar ist, welche Ausdrücke in welcher Reihenfolge verknüpft werden sollen. Zum Beispiel ist folgender Ausdruck missverständlich:

boolean1 and boolean2 or boolean3

Dies wird von Delphi zwar akzeptiert, ist aber für einen menschlichen Leser verwirrend und dem Programmverständnis nicht förderlich. Es sollte daher vermieden werden. Man sollte obigen Ausdruck mit Klammern schreiben, sodass klar ist, welche Verknüpfungen hier gewünscht werden:

(boolean1 and boolean2) or boolean3

Aber wie hätte Delphi diesen Ausdruck ausgewertet, wäre er ohne Klammern geschrieben? Für Delphi ist jeder Ausdruck eindeutig auswertbar, dafür sorgen zwei Regeln: Zum einen ist das die Präzedenz der Operatoren, sozusagen die Stärke der „Bindung“ eines Operators. Zum anderen die Reihenfolge der Auswertung, bei Operatoren gleicher Präzedenz. Sie erfolgt von links nach rechts.
Die Präzendenz (oder auch „Rangfolge“) von Operatoren mag Ihnen zuerst etwas merkwürdig erscheinen, jedoch kennt sie jeder, der weiß, dass Punkt- vor Strichrechnung geht. Damit wird nämlich genau angegeben, dass die Punktrechnung (also die Operatoren der Multiplikation und Division) eine höhere Präzedenz haben als die Strichrechnung (also die Operatoren der Addition und Subtraktion).
Die Präzedenz der Bool’schen Operatoren ist wie folgt: not, and, or, xor. Bei Operatoren gleicher Präzedenz wird von links nach rechts ausgewertet, ansonsten hat die Präzedenz Vorrang vor der Reihenfolge (wie bei „Punkt vor Strich“). Folgende Schreibweise wäre also äquivalent zu obigem Ausdruck:

boolean3 or boolean1 and boolean2

Die Auswertung von links nach rechts kann man sich beim so genannten Kurzschlussverfahren zu Nutze machen. Dieses wird bei der Auswertung von and- und or-Ausdrücken verwendet. Dabei wird ein solcher Ausdruck von links nach rechts ausgewertet und abgebrochen, sobald das Ergebnis fest steht. Zum Beispiel: Wenn bei einer and-Verknüpfung von zwei Ausdrücken der erste Ausdruck bereits „falsch“ ist, so muss auch der Gesamtausdruck „falsch“ sein. Der zweite Ausdruck muss gar nicht mehr kontrolliert werden und Delphi lässt das dann auch sein.
Dies ist sehr nützlich, wenn man diese Ausdrücke über eine Funktion bezieht. Dann nähme man als ersten Ausdruck die Funktion, welche besonders schnell ist und als zweiten Ausdruck die Funktion, welche langsamer ist. Der Vorteil: wenn die erste Funktion „falsch“ zurückgibt, dann wird die Zweite (langsamere) gar nicht mehr ausgeführt, weil Delphi erkennt, dass dies nicht nötig ist. Bei der vollständigen Auswertung würde dagegen ein Ausdruck auch dann vollständig ausgewertet, selbst wenn sein Ergebnis bereits fest steht. Dies kann auch nützlich sein, zum Beispiel dann, wenn ein Teil des Ausdrucks Auswirkung auf das Programm hat, also z.B. eine Funktion ist, die eine globale Variable ändert. Man redet dann auch von einer Funktion mit Nebeneffekten.
Nun wurde genug über Bool’sche Ausdrücke geredet, jetzt wird noch einmal die if-Anweisung beleuchtet.

if-Anweisung – Die Zweite

Die Struktur der if-Anweisung, die bisher verwendet wurde, kann man also so schreiben:

if {Bool'scher Ausdruck} then
  {Block1}

„{Block1}“ bedeutet, dass dort eine Anweisung stehen kann (wie im obigen Beispiel) oder aber ein kompletter Anweisungsblock, der, wie oben beschrieben, durch ein „begin“ und ein „end“ beschränkt wird. Dieser Block wird genau dann ausgeführt, wenn der Bool’sche Ausdruck „wahr“ ist. Ist er „falsch“, wird bei dieser Anweisung nichts ausgeführt.
Dieses Verhalten ist jedoch nicht immer gewünscht. Oft möchte man, dass auch für den Fall, dass der Bool’sche Ausdruck „falsch“ ist, eine Anweisung oder ein Block von Anweisungen ausgeführt wird. Und dies wäre dann die Verzweigung, von der ich eingangs geschrieben habe. Dies kann man wohl auch wieder am Besten anhand eines Beispiels erklären:

procedure TForm1.Button1Click(Sender: TObject);
var zahl1, zahl2 : Real;
begin
  zahl1 := StrToFloat(edit1.text);
  zahl2 := StrToFloat(edit2.text);

  if zahl1 < zahl2 then
    label1.capion := 'kleiner'
  else
    label1.caption := 'größer oder gleich';
end;

Dieser Quelltext ähnelt dem aus dem ersten Teil zu if-Anweisungen, ist von der Funktion her jedoch nicht komplett identisch. Folgendes tut dieser Quelltext: wenn „zahl1“ kleiner als „zahl2“ ist, so wird dies im Label1 angezeigt, sonst wird in Label1 angezeigt, dass „zahl1“ größer oder gleich „zahl2“ ist. Und dies ist die gesuchte Verzweigung, da immer nur einer der beiden Befehle ausgeführt wird.
Bitte beachten Sie Folgendes: der letzte Befehl vor einem „else“ wird niemals mit einem Semikolon abgeschlossen. Dies gilt auch für den Fall, dass der letzte Befehl das abschließende „end“ eines Codeabschnitts ist!
Nun ist der obige Quelltext jedoch nicht äquivalent mit dem vorherigen Quelltext. Er gibt dem Benutzer weniger Informationen, da er nicht zwischen „größer“ und „gleich“ unterscheiden kann. Dies kann man, wenn man mit else arbeiten will, mit einer verschachtelten if-Anweisung lösen:

if zahl1 < zahl2 then
    label1.capion := 'kleiner'
  else
    if zahl2 < zahl1 then
      label1.caption := 'größer'
    else
      label1.caption := 'gleich';

Hieran sieht man zweierlei: zum einen die oben genannte Verschachtelung und zum anderen, dass die if-Anweisung ab dem „if“ bis inklusive zum Block hinter dem „else“ als eine Anweisung gilt und sie somit nicht mit „begin“ und „end“ als Abschnitt gekennzeichnet werden muss. Nicht ganz klar, wie das gemeint ist? Anhand eines Beispiels wird es klarer. Folgendes muss man nicht machen:

if zahl1 < zahl2 then
    label1.capion := 'kleiner'
  else begin
    if zahl2 < zahl1 then
      label1.caption := 'größer'
    else
      label1.caption := 'gleich';
  end;

Dies liegt daran, dass folgendes als eine Anweisung verstanden wird:

if zahl2 < zahl1 then
      label1.caption := 'größer'
    else
      label1.caption := 'gleich';

Zusammenfassend kann man die if-Anweisung also so charakterisieren: Die if-Anweisung ist ein Anweisungsgerüst, welches als eine einzige Anweisung betrachtet wird und wie folgt aufgebaut ist.

if {Bool'scher Ausdruck} then
  {Block1}
else
  {Block2}

Dabei ist die letzte Zeile optional, wird sie jedoch verwendet, so darf der letzte Befehl von „{Block1}“ nicht mit einem Semikolon abgeschlossen werden.
Ich habe mich nun sehr lange mit der if-Anweisung und dem drum herum aufgehalten und den ein oder anderen hat inzwischen die Langeweile gepackt. Jedoch ist dies eine der wichtigsten Dinge, die es in Delphi gibt und Sie werden selten ein Programm schreiben, in dem keine if-Anweisung vorkommt. Und damit es dort keine Probleme gibt, bin ich lieber auf Nummer sicher gegangen und war lieber zu ausführlich als zu knapp.

Die case-Anweisung

Nun ist jedoch die if-Anweisung nicht die einzige Kontrollstruktur, welche eine Verzweigung des Programmes erlaubt.Es gibt auch noch die so genannte „case-Anweisung“. Was versteht man darunter? Wozu braucht man die?
Eigentlich braucht man sie nicht wirklich. Aber sie ist sehr praktisch. Stellen Sie sich vor, Sie lassen den Benutzer eine ganze Zahl zwischen Null und Fünf eingeben. Und je nachdem, welche Zahl eingegeben wurde, möchten Sie eine Aktion ausführen lassen. Dies könnten Sie so lösen:

if zahl = 0 then
  anweisung1;
if zahl = 1 then
  anweisung2;
if zahl = 2 then
  anweisung3;
if zahl = 3 then
  anweisung4;
if zahl = 4 then
  anweisung5;
if zahl = 5 then
  anweisung6;

Offensichtlich ist dies nicht sehr elegant, es kommt sehr viel Code darin vor, der sich ähnelt und das ist etwas, das einem guten Programmierer die Augen bluten lässt. Eine Lösung bietet eine Case-Anweisung:

case zahl of
  0: anweisung1;
  1: anweisung2;
  2: anweisung3;
  3: anweisung4;
  4: anweisung5;
  5: anweisung6;
end;

Dies sieht doch sehr viel besser aus, oder? Man kann es auch noch auf die Spitze treiben und der Case-Anweisung Mengen anstatt nur Zahlen übergeben. Ein Beispiel wie dies geht, folgt auf dem Fuße und zeigt auch die Verwendung eines Else-Zweiges in Case-Anweisungen:

case zahl of
  0..3, 5: anweisung1;
  4: anweisung2;
else
  anweisung3;
end;

Doch alles, was so viele Vorteile besitzt, besitzt meist auch Nachteile. So leider auch die Case-Anweisung:

  1. Es können nur konstante Ausdrücke als Vergleichswerte angegeben werden. Anstatt der Zahlen dürfte man oben also keine Variablennamen eintragen.
  2. Man kann mittels der Case-Anweisung nur die Werte von Variablen überprüfen, welche einen „ordinalen“ Typ haben. Ein Datentyp ist dann „ordinal“, wenn man in aufzählen kann. Alle Werte dieses Datentyps müssen einen eindeutigen Vorgänger (Ausnahme: der erste Wert) und einen eindeutigen Nachfolger (Ausnahme: der letzte Wert) besitzen. Ein ordinaler Typ ist zum Beispiel der Integer. Dies ist einsichtig, Integer enthält nur ganze Zahlen in einer definierten Reihenfolge, z.B. …,4,5,6,7,… Dagegen nicht aufzählbar ist der Datentyp String, daher kann ein String nicht mit der Case-Anweisung verwendet werden.

Übrigens müssen in der case-Anweisung nicht einzelne Anweisungen stehen, sondern man kann auch mehrere durch „begin“ und „end“ eingeschlossene Anweisungen einfügen.

Schleifen

Schleifen sind extrem wichtige und praktische Kontrollstrukturen einer Programmiersprache. Sie bieten einem Programmierer die Möglichkeit, eine Aktion mehrmals auszuführen, ohne zu der Zeit, zu der er das Programm schreibt, schon zu wissen, wie oft diese Aktion genau ausgeführt werden soll.
Dabei bieten Schleifen verschiedene Möglichkeiten anzugeben, wann die Ausführung der Anweisung gestoppt werden soll, so z.B. neben der Angabe einer Anzahl von Schleifendurchläufen auch eine Bedingung, welche zum Abbruch führt.

Die for-do-Schleife

Die for-do-Schleife stellt eine Möglichkeit dar, festzulegen, wie oft eine Anweisung ausgeführt wird. Dies wird mit einem so genannten „Zähler“ in Form einer „Schleifenvariable“ gemacht. Erst einmal ein Beispiel:

for i:=0 to 5 do
  anweisung;

Hierbei ist „i“ eine Variable vom Typ Integer. Die for-do-Schleife macht Folgendes: Zuerst wird „i“ der Wert 0 zugeordnet. Dann wird die Anweisung ausgeführt. Dann wird „i“ um 1 erhöht, besitzt nun also den Wert 1. Die Anweisung wird wiederrum ausgeführt, usw. Die letzte Ausführung der Anweisung findet statt, wenn „i“ den Wert 5 hat. Zu diesem Zeitpunkt wurde die Anweisung sechs Mal ausgeführt. Und zwar für die Werte von „i“: 0,1,2,3,4,5.
Dabei ist „i“ aber nicht auf die Rolle des Platzhalters zur Angabe der Anzahl beschränkt. Die Wertzuweisung zu „i“ macht durchaus Sinn, denn während die Anweisung ausgeführt wird, kann man innerhalb dieser Anweisung (die natürlich wie immer auch aus mehreren Anweisung, welche durch „begin“ und „end“ eingeschlossen sind, bestehen kann) auf den aktuellen Wert von „i“ zugreifen.

var i : Integer;
    myString : String;
begin
  myString := '';

  for i:=0 to 5 do
    myString := myString + IntToStr(i);
end;

Dieser Quellcode macht folgendes: er legt zwei Variablen an, „i“ und „myString“. Dann wird „myString“ auf einen leeren Wert gesetzt. Schließlich kommt die Schleife: in dieser durchläuft „i“ die oben bereits genannten Werte. In jedem Schleifendurchlauf wird der aktuelle Wert von „i“ in einen String umgewandelt und an „myString“ angehängt.
Das Addieren von Strings geschieht dabei ganz intuitiv, sodass die Addition von ‚a‘ und ‚b‘ den String ‚ab‘ ergeben würde. Nach dem die Schleife komplett durchlaufen wurde, wurden also alle Zahlen von 0 bis 5 an einen zu Anfang leeren String angehängt. Also hat „myString“ nun den Wert ‚012345‘.
Nachdem das Prinzip der for-do-Schleife nun klar sein sollte, folgen nun noch ein paar Anmerkungen:

  1. Die Zeile „for … do“ nennt man den Schleifenkopf, die Anweisungen, welche ausgeführt werden, den Schleifenrumpf. Diese Bezeichnungen werden auch bei allen anderen Schleifen verwendet!
  2. Im Schleifenrumpf darf die Zählervariable (in unserem Fall das „i“) nicht verändert werden. (Der Compiler verhindert das, wenn man ihn nicht austrickst.)
  3. Sowohl Anfangs- als auch Endwert einer Schleife dürfen Variablen sein.
  4. Es gibt zwei Arten for-do-Schleifen: eine for-to-do-Schleife und eine for-downto-do-Schleife. Die ?to?-Variante zählt hoch, die ?downto?-Variante zählt herunter. Dies beinhaltet, dass der Rumpf einer Schleife der ?to?-Variante nur dann ausgeführt wird, wenn der Startwert kleiner als der Endwert ist. Das leuchtet ein: eine heraufzählende Schleife kann nur dann arbeiten, wenn man den Endwert durch erhöhen des Anfangswertes erreichen kann. Analog wird der Rumpf der ?downto?-Variante nur ausgeführt, wenn der Startwert größer als der Endwert ist.
  5. Wird die Schleife regulär verlassen, also durch erreichen des Endwertes, so ist der Wert der Zählervariable im Allgemeinen nicht mehr definiert. Bei einem nicht-regulären Verlassen (wie das geht kommt am Ende dieses Abschnittes) enthält die Zählervariable den Wert, den sie zuletzt in der Schleife besaß.

Die repeat-until-Schleife

Nachdem Sie nun die Schleife kennen gelernt haben, welche den Abbruch über die Anzahl der Schleifendurchläufe regelt, wird nun eine der beiden Schleifen beschrieben, welche den Abbruch an eine Bedingung knüpfen.
Dabei sagte die Übersetzung des Namens bereits, wie die Schleife aufgebaut ist: „wiederhole … bis“. Und dort, wo momentan noch drei Punkte stehen, kommt die Anweisung hin. Und auch hier muss nicht unbedingt eine einzelne Anweisung stehen, sondern es können auch mehrere sein. Aber Sie brauchen kein „begin“ und „end“. Weshalb das so ist, sehen Sie im nachfolgenden Beispiel.

var i, wert, max : Integer;
begin
  {...}
  i := 0;
  wert := 1;
  repeat
    i := i + 1;
    wert := wert * i;
  until wert >= max;
  {...}
end;

Dieser Quelltext berechnet das „i“, mit dem „i!“ (i! = i*(i-1)*…*1) größer oder gleich „max“ ist. Dabei werden die Befehle, welche zum Schleifenrumpf gehören, bereits durch die Schlüsselwörter „repeat“ und „until“ begrenzt, „begin“ und „end“ sind also nicht mehr nötig.
Die Anweisungen werden mindestens einmal ausgeführt, denn die Überprüfung, ob die Bedingung erfüllt ist oder nicht, steht ja am Ende. Die Schleifenbedingung ist ein Bool’scher Ausdruck, wie er bereits besprochen wurde. Sobald dieser Bool’sche Ausdruck wahr ist, wird die Schleife verlassen.

Die while-do-Schleife

Die while-do-Schleife („während … mache …“) ist der repeat-until-Schleife sehr ähnlich und bietet praktisch die gleichen Funktionen. Daher werde ich hier nur auf die Unterschiede eingehen:

  1. Die Bedingung wird am Schleifenkopf geprüft. Die Schleife wird also nicht unbedingt einmal ausgeführt, sondern es kann auch sein, dass die Schleife kein Mal ausgeführt wird. Dies passiert dann, wenn die Bedingung schon ganz am Anfang nicht mehr erfüllt ist.
  2. Sollen mit einer while-do-Schleife mehrere Anweisungen ausgeführt werden, müssen diese mit „begin“ und „end“ eingegrenzt werden.
  3. Die Schleifenbedingung ist ein Bool’scher Ausdruck, jedoch wird im Gegensatz zur repeat-until-Schleife die Schleife dann verlassen, wenn der Ausdruck nicht wahr ist.

Und weil es so schön ist, gibt es auch noch ein Beispiel:

var i, max : Integer;
    richtig : Boolean;
begin
  {...}
  i := 2;
  richtig := true;
  while richtig do
  begin
    i := i*i;
    richtig := i < max;
  end;
  {...}
end;

An diesem Beispiel kann man auch noch einnmal die Verwendung von Bool’schen Ausdrücken sehen: „i < max“ ist entweder wahr oder falsch und kann deswegen auch einer Variable von Typ Boolean zugewiesen werrden. Damit es keine Verwirrung gibt: der Code hat nichts mit „i!“ zutun!

2 Gedanken zu „Delphi-Crashkurs“

  1. Guten Morgen,

    erst einmal vielen Dank für die ausführlichen Erklärungen!

    Im ersten Beispiel zur Darstellung von Zahlen im Rechner müsste es heißen

    4 mal 1 = 4*10^0

    statt

    4 mal 1    = 4*10

     

    1. Vielen Dank für den Hinweis.
      Ich habe es entsprechend korrigiert.
      Auch Deinen weiteren Hinweis habe ich eingearbeiotet.

Kommentare sind geschlossen.