Ich versuche es mit der zweiten Frage. Zum Ersten, bitten einen Quelltext immer mit den reservierten Worten {delphi} ... {/delphi} (in eckigen Klammern!) eingrenzen. Dann ist der Quelltext besser vom restlichen Text zu unterscheiden:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| var eingabe, ausgabe: string;
procedure mach_es(position: integer); var buchstabe: char; begin buchstabe := eingabe[position]; ausgeben := ausgabe + buchstabe; if position < length(eingabe) then mach_es(position + 1); ausgabe := ausgabe + buchstabe; end;
procedure TForm1.Button1Click(Sender: TObject); begin label2.caption := ' '; eingabe := Edit1.Text; ausgabe := ' '; mach_es(1); label2.caption := ausgabe; end; |
Also das Programm ruft beim Click auf den Button die Prozedur mach_es auf, welche dann sich selber solange wieder aufruft, bis der Parameter die Länge des im Editfeld angegebenen Textes erreicht hat. Das nennt man rekursive Prozeduraufrufe.
Wie das Programm das Ganze abarbeitet, kannst Du am Besten daran sehen, wenn Du in dem Programm einen Haltepunkt setzt. Und zwar in der Zeile "Ausgabe :=". Das Programm behält die Informationen für die Variable Buchstabe (lokale Variable der Prozedur mach_es) bei jedem Aufruf bei. Und gibt diese Variable am Ende der Bedingung - Position = Length(Eingabe) - der Reihe nach wieder aus. Das Ergebnis ist dann der in umgekehrter Reihenfolge erzeugte Text im Editfeld.
Ein weiteres Beispiel für rekursive Prozeduraufrufe ist die Auflistung von Dateien in Unterverzeichnissen. Das läuft nach dem gleichen Muster ab.
Für solche rekursiven Prozeduraufrufe gibt es allerdings eine große Gefahr, nämlich wenn die Abbruchbedingung nie erreicht wird. Dann wird das Programm irgendwann einmal mit einen Stackoverflow abbrechen oder im Nirwana verschwinden, weil es ja nie endet. Schließlich muss ja jeder Prozeduraufruf mindestens seine Variablen zwischenspeichern.
Die eckigen Klammern sind zur Unterscheidung zwischen Indices und Prozedurparametern.
Sicher hast Du schon mal was von Arrays gehört. Das sind Speicherbereiche, welche mit gleichen Variablentypen belegt sind, wo einzelne Variablen dann über Indices angesprochen werden. z.B. die Monate des Jahres:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| Var Monat : Array[1..12] of string = ('JAN','FEB','MRZ','APR','MAI','JUN','JUL','AUG','SEP','OKT','NOV','DEZ'); AktuellerMonat : string; i : integer; begin AktuellerMonat := Monat[3]; for i := 1 to 12 do WriteLn(Monat[i]); end; |
Vorteil dabei ist, Du kannst den Speicherbereich mit den Daten beliebig ansprechen, indem Du den Index benutzt (Wie die Seiten eines Buches). Siehe das kleine Beispiel.
Die Daten im Array können im Übrigen jede x-beliebige - im Programm definierte! - Struktur haben.
z.B.:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| type Adresse = Record Vorname, Name : string[50]; Strasse : string[90]; PLZ : string[5]; Ort : string[90]; Geburtstag : TDateTime; end;
var Kunde : Array [1..200] of Adresse; |
Dann kannst Du mit dem Index i (Kunde[i]) den i-ten Kunden direkt ansprechen. Vorausgesetzt, Du hast da etwas eingegeben. Für eine Datenbank allerdings ist dieses Verfahren nicht geeignet, nur so im Voraus, weil ja nur 200 Kunden möglich sind.
Die Eckigen Klammern bei string[90] sind hier keine Indices, sonder Speicherbegrenzungen. Das heißt, für PLZ sind maximal 5 Zeichen möglich, für Ort maximal 90 usw. Der Typ TDateTime ist speziell für Datums- und Zeitangaben gedacht. Schau hier einfach mal in der Delphi-Hilfe nach.
Toleranz ist eine Grundvoraussetzung für das Leben.