Informatik Programmieren 6.Klasse Inhalt 1. Datentypen ......................................................................................................................... 1 1.1. Grundlegenden Datentypen in Delphi: ....................................................................... 2 1.2. Deklaration .................................................................................................................. 2 1.3. Globale Variablen ........................................................................................................ 2 1.4. Lokale Variablen .......................................................................................................... 3 1.5. Initialisierung/Zuweiseung - Definition ....................................................................... 3 2. Typumwandlung: ................................................................................................................ 4 3. Teilbereichstypen ................................................................................................................ 5 3.1. Aufzählungstypen ........................................................................................................ 5 4. Mengentypen ...................................................................................................................... 5 5. Arrays .................................................................................................................................. 6 5.1. Dynamische Arrays ...................................................................................................... 7 5.2. Mehrdimensionale Arrays................................................................................................... 8 6. Records – Verbundvariablen ............................................................................................... 8 Übungsbeispiel Personendatenbank mit Records: ............................................................. 9 7. 6.1. Variante Records ....................................................................................................... 11 6.2. Records mit Methoden .............................................................................................. 12 Benutzerdefinierte Datentypen ........................................................................................ 12 7.1. Beispiel: Monate, Wochentage ................................................................................. 14 7.2. Beispiel: Roulette ....................................................................................................... 15 1. Datentypen http://www.delphi-treff.de/object-pascal/variablen-und-konstanten/ http://www.delphi-treff.de/object-pascal/datentypen/ Bevor eine Variable verwendet werden kann, sollte man sich darüber im Klaren sein, welche Werte sie aufnehmen soll. Variablen sind also Platzhalter oder "Container" für einen Wert, der Platz im Arbeitsspeicher belegt; der Datentyp ist dagegen der Bauplan, nach dem die Variable erstellt wird. [1] 1.1. Grundlegenden Datentypen in Delphi: 1.2. Deklaration Man kann eine Variable nicht einfach verwenden. Vorher muss sie dem Compiler bekannt gemacht werden, damit er beim Kompilieren entsprechende Typprüfungen durchführen kann. Diese Bekanntmachung nennt man Deklaration. Vor einer Deklaration wird das reservierte Wort var geschrieben. Als erstes kommt der Name der Variablen, hinter einem Doppelpunkt der Typ. Mehrere Variablennamen vom gleichen Typ können in einer Zeile, durch Kommata getrennt, stehen. Beispiel: var zahl1, zahl2, zahl3: integer; ergebnis: real; text, eingabe: string; An folgenden Stellen im Code ist das möglich, je nach Gültigkeitsbereich: 1.3. Globale Variablen Bei manchen Programmierern sind sie verpönt, trotzdem sind sie möglich: globale Variablen. Ihr Wert ist in der gesamten Unit verfügbar und in allen Units, die diese einbinden. Die Deklaration erfolgt am Anfang der Unit: unit Unit1; interface uses Windows, Messages, SysUtils,… type [2] TForm1 = class(TForm) private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; einezahl: integer; // Diese Variable gilt in der ganzen Unit und // in allen Units, die diese Unit einbinden implementation {$R *.DFM} var eine_andere_zahl: real; { Diese Variable gilt nur in dieser Unit Globale Variablen können bei ihrer Deklaration mit einem Startwert belegt werden: } einezahl: integer = 42; Diese Art der Zuweisung verwendet ein einfaches Gleichheitszeichen, nicht := Bei lokalen Variablen ist diese Initialisierung nicht möglich. 1.4. Lokale Variablen Das Gegenstück zu globalen Variablen sind die lokalen. Hierbei wird eine Variable zu Beginn einer Prozedur, Funktion oder Methode deklariert. Sie kann somit nur innerhalb dieses Abschnitts verwendet werden. Wird die Prozedur/Funktion verlassen, dann wird der Speicher für die Variablen wieder freigegeben, d. h. auf die Werte kann nicht mehr zugegriffen werden. So könnte eine lokale Variablendeklaration aussehen: procedure IchMacheIrgendwas; var text: string; begin ... //Irgendwas Sinnvolles end; 1.5. Initialisierung/Zuweiseung - Definition Bevor auf eine Variable zugegriffen wird, sollte sie initialisiert werden, es sollte ihr also ein Anfangswert zugewiesen werden. Strings enthalten zwar einen leeren String; alle anderen Variablentypen enthalten jedoch irgendwelche zufälligen Werte. Zuweisung von Werten an eine Variable erfolgt in Pascal durch die Symbolfolge : = ("ergibt sich aus"). Im Gegensatz zur Mathematik ist deshalb auch Folgendes möglich: x := x + 1; Das Laufzeitsystem berechnet hier die Summe von x und 1 und legt das Ergebnis dann wieder in x ab. x ergibt sich aus dem bisherigen x plus 1. Kurz: x wird um 1 erhöht. Für diesen Fall gibt es auch eine eigene Prozedur: inc(x). [3] 2. Typumwandlung: Im Gegensatz zu einigen anderen Sprachen ist Delphi bei Typen sehr streng. Es ist also nicht möglich, einer Integer-Variable eine Gleitkommazahl-Variable zuzuweisen. Dafür steht eine große Auswahl an Konvertierungsfunktionen zur Verfügung: [4] 3. Teilbereichstypen Einen weiteren Datentyp, der eigentlich gar kein eigener Datentyp ist, gibt es noch, nämlich den Teilbereichstyp, auch Unterbereichstyp genannt. Hierüber kann man Variablen z. B. zwar den Typ Integer zuordnen, aber nicht den kompletten Definitionsbereich, sondern nur einen Teilbereich davon: var kleineZahl: 0..200; Der Variablen kleineZahl lassen sich jetzt nur ganze Zahlen zwischen 0 und 200 zuweisen. Ähnlich lassen sich auch Strings begrenzen: var kleinerString: string[10]; Diese Variable kann nur zehn Zeichen aufnehmen, es handelt sich nun um einen ShortString, der auch Nachteile gegenüber einem "normalen" AnsiString hat. Mehr dazu aber in einem extra Abschnitt über Strings. 3.1. Aufzählungstypen Um das Ganze für einen Programmierer lesbarer zu machen, können statt Zahlen auch konstante Bezeichner verwendet werden: var farben: (blau, gelb, gruen, rot); Intern werden die Werte bei Null beginnend durchnummeriert und haben deshalb eine feste Reihenfolge. Über die Funktion ord lässt sich die Position bestimmen. Wichtige Funktionen zum Arbeiten mit Aufzählungstypen sind: ord pred succ low high gibt gibt gibt gibt gibt die den den den den Position des Bezeichners zurück Vorgänger zurück Nachfolger zurück niedrigsten Wert zurück höchsten Wert zurück Die Typen Integer und Char gehören ebenfalls zu den ordinalen (abzählbaren) Typen, d.h. die Werte lassen sich in einer Reihenfolge anordnen, weshalb o.g. Funktionen auf sie ebenfalls angewandt werden können. 4. Mengentypen Um in einer einzigen Variablen eine unterschiedliche Menge an Werten des gleichen Typs zu speichern, gibt es Mengentypen. Es ist eine Menge an möglichen Werten vorgegeben, aus der eine beliebige Anzahl (keiner bis alle) in der Variablen abgelegt werden kann. Folgendermaßen wird eine solche Mengenvariable deklariert: var zahlen: set of 1..10; [5] Damit können der Variablen zahlen Werte aus der Menge der Zahlen von 1 bis 10 zugewiesen werden - mehrere gleichzeitig oder auch gar keiner: zahlen zahlen zahlen zahlen zahlen := := := := := [5, 9]; []; [1..3]; zahlen + [5]; zahlen - [3..10]; // // // // // // zahlen enthält die Zahlen 5 und 9 zahlen enthält überhaupt keine Werte zahlen enthält die Zahlen von 1 bis 3 zahlen enthält die Zahlen 1, 2, 3, 5 die Zahlen von 3 bis 10 werden aus der Menge entfernt, es bleiben 1 und 2 Um nun zu prüfen, ob ein bestimmter Wert in der Menge enthalten ist, wird der Operator in verwendet: if 7 in zahlen then ... In einem Set sind nur Werte mit der Ordnungsposition von 0 bis 255 möglich. 5. Arrays Müssen mehrere Werte des gleichen Typs gespeichert werden, ist ein Array (zu deutsch Feld oder Liste) eine praktische Lösung. Ein Array hat einen Namen wie eine Variable, jedoch gefolgt von einem Index in eckigen Klammern. Über diesen Index kann man auf die einzelnen Werte zugreifen. Am einfachsten lässt sich das mit einer Straße vergleichen, in der sich lauter gleiche Häuser befinden, die sich jedoch durch ihre Hausnummer (den Index) unterscheiden. Eine Deklaration der Art var testwert: array [0..10] of integer; bewirkt also, dass wir quasi elf verschiedene Integer-Variablen bekommen. Man kann auf sie über den Indexwert zugreifen: testwert[0] := 15; testwert[1] := 234; //usw. Vorteil dieses Indexes ist, dass man ihn durch eine weitere Variable ersetzen kann, die dann in einer Schleife hochgezählt wird. Folgendes Beispiel belegt alle Elemente mit dem Wert 1: for i := 0 to 10 do testwert[i] := 1; Auf Schleifen wird jedoch in einem gesonderten Kapitel eingegangen. Bei dem vorgestellten Array handelt es sich genauer gesagt um ein eindimensionales, statisches Array. "Eindimensional", weil die Elemente über nur einen Index identifiziert werden, und "statisch", weil Speicher für alle Elemente reserviert wird. Legt man also ein Array für Indexwerte von 1 bis 10000 an, so wird für 10000 Werte Speicher reserviert, auch wenn während des Programmablaufs nur auf zwei Elemente zugegriffen wird. Außerdem kann die Array-Größe zur Programmlaufzeit nicht verändert werden. [6] 5.1. Dynamische Arrays Wenn schon so viel Wert auf die Eigenschaft statisch gelegt wird, muss es ja eigentlich auch etwas Dynamisches geben. Und das gibt es auch, zumindest seit Delphi 4: die dynamischen Arrays. Der erste Unterschied findet sich in der Deklaration: Es werden keine Grenzen angegeben. var dynArray: array of integer; dynArray ist nun prinzipiell eine Liste von Integer-Werten, die bei Index Null beginnt. Zum Hintergrundverständnis: Während statische Arrays direkt die einzelnen Werte beinhalten, enthält ein dynamisches Array nur Zeiger auf einen Arbeitsspeicherbereich. In der Anwendung ist das nicht zu merken, es ist keine spezielle Zeigerschreibweise nötig. Nur an einer Stelle bemerkt man das interne Vorgehen: Bevor man Werte in das Array stecken kann, muss man Speicher für die Elemente reservieren. Dabei gibt man an, wie groß das Array sein soll: SetLength(dynArray, 5); Nun kann das Array fünf Elemente (hier Integer-Zahlen) aufnehmen. Man beachte: Da die Zählung bei Null beginnt, befindet sich das fünfte Element bei Indexposition 4! Der Zugriff erfolgt ganz normal: dynArray[0] := 321; Damit es mit der Unter- und vor allem der Obergrenze, die ja jederzeit verändert werden kann, keine Probleme gibt (Zugriffe auf nicht (mehr) reservierten Speicher), lassen sich Schleifen am einfachsten so realisieren: for i := 0 to high(dynArray) do dynArray[i] := 0; Dadurch werden alle Elemente auf 0 gesetzt. high(dynArray) entspricht dem höchstmöglichen Index. Über length(a) lässt sich die Länge des Arrays ermitteln, welche immer high(dynArray)+1 ist. Dabei handelt es sich um den Wert, den man mit SetLength gesetzt hat. Da die Länge des Arrays jederzeit verändert werden kann, könnten wir sie jetzt mit SetLength(dynArray, 2); auf zwei verkleinern. Die drei hinteren Werte fallen dadurch weg. Würden wir das Array dagegen vergrößern, würden sich am Ende Elemente mit undefiniertem Wert befinden. [7] 5.2. Mehrdimensionale Arrays Wenn es eindimensionale Arrays gibt, muss es auch mehrdimensionale geben. Am häufigsten sind hier wohl die zweidimensionalen. Man kann mit ihnen z. B. ein Koordinatensystem oder Schachbrett abbilden. Die Deklaration ist wie folgt: var koordinate: array [1..10, 1..10] of integer; Es werden also 10x10=100 Elemente angelegt, die jeweils einen Integer-Wert aufnehmen können. Für den Zugriff auf einzelne Werte sind zwei Schreibweisen möglich: koordinate[1,6] := 34; koordinate[7][3] := 42; Und es gibt auch mehrdimensionale dynamische Arrays: var koordinate: array of array of Integer; Die Längenzuweisung erfolgt dann durch Angabe der Länge für jede Dimension: SetLength(koordinate, 10, 10); 6. Records – Verbundvariablen Records entsprechen von der Struktur her einem Datensatz einer Datenbank - nur dass sie, wie alle bisher aufgeführten Variablen, nur zur Laufzeit vorhanden sind. Wenn wir unterschiedliche Daten haben, die logisch zusammengehören, können wir sie sinnvollerweise zu einem Record zusammenfassen. Beispiel: Adressen. var Adresse: record name: string; plz: integer; ort: string; end; Die Variable Adresse wird also in drei "Untervariablen" aufgegliedert. Folgendermaßen greift man auf die einzelnen Felder zu: adresse.name := 'Hans Müller'; adresse.plz := 12345; adresse.ort := 'Irgendwo'; Damit das nicht (besonders bei vielen Elementen) in enorme Tipparbeit ausartet, gibt es dafür auch eine Abkürzung: with adresse do begin name := 'Hans Müller'; plz := 12345; ort := 'Irgendwo'; end; [8] Aufgabe: Schreibe Programm „Projektverwaltung“ welches 10 Datensätze Projektaufwand mit folgenden Einzelvariablen erfasst: Person (Name), den Projektnamen(ProjektName), die gearbeiteten Stunden(stunden) und die gearbeiteten Minuten(minuten). Danach soll ein String in ein Memofeld mit beispielsweise folgendem Wortlaut ausgegeben werden : „Insgesamt wurde am Projekt „Schiffe versenken“ 5 Stunden und 22 Minuten gearbeitet!“ Übungsbeispiel Personendatenbank mit Records: Grundlage für das Beispiel ist eine kleine Personaldatenbank, in welcher der Name, das Geburtsdatum, das Geschlecht und die Telefonnummer abgespeichert werden sollen. Bei der Umsetzung werden wir auf kein Standard-Datenbankformat (Paradox, dBase ...) zurückgreifen, sondern auf einen benutzerdefinierten Datentyp (Record). Die einzelnen Records werden in einem eindimensionalen Array abgespeichert, auf das bekanntlich über einen Feldindex (entspricht einer laufenden Nummer) zugegriffen werden kann. GUI Plazieren Sie (entsprechend der Abbildung) auf dem Startformular fünf Labels, drei Editierfelder, eine CheckBox und fünf Buttons: Quelltext Fügen Sie in den Private-Abschnitt von TForm1 die folgenden drei Methodendeklarationen ein: Private { Private-Deklarationen } procedure dsInit; // Methode zum Initialisieren aller Datensätze procedure dsSpeichern; // dto. zum Speichern eines Datensatzes procedure dsAnzeigen; // dto. zum Anzeigen Wir hätten auch auf obige Methodendeklarationen verzichten können und stattdessen drei ganz normale Prozeduren in den Implementation-Abschnitt einfügen können. Die gewählte Vorgehensweise ist aber eleganter und übersichtlicher (insbesondere im Hinblick auf die objektorientierte Programmierung). Im Implementation-Abschnitt definieren wir zunächst unseren Record, um dann eine eindimensionale Array-Variable mit der gewünschten Anzahl von Feldern (10) zu deklarieren: type TPerson = record // Typ der Strukturvariablen [9] name: string[20]; // max. 20 Buchstaben geburt: TDateTime; // Geburtsdatum geschlecht: Boolean; // männlich = True, weiblich = False nr: Integer // Telefonnummer end; const pmax = 10; // max. Anzahl von Personen = Größe des Arrays var personen: array[1..pmax] of TPerson; // Array-Variable index: Byte = 1; // aktueller Feldindex Nun zu den Methoden-Implementationen: procedure TForm1.FormCreate(Sender: TObject); // Programmstart begin dsInit; // initialisiert alle Datensätze dsAnzeigen // und zeigt den ersten an end; Es folgen die drei nutzerdefinierten Methoden: procedure TForm1.dsInit; // setzt alle Personen auf Standardwerte var i: Integer; begin for i := pmax downto 1 do with personen[i] do begin name := ''; geburt := StrToDate('31.12.99'); geschlecht := False; nr := 9999999 end end; Von der Anzeige in den Speicher: procedure TForm1.dsSpeichern; begin personen[index].name := Edit1.Text; if Edit2.Text <> '' then personen[index].geburt := StrToDate(Edit2.Text); personen[index].geschlecht := CheckBox1.Checked; personen[index].nr := StrToInt(Edit3.Text) end; Vom Speicher in die Anzeige: procedure TForm1.dsAnzeigen; begin Label1.Caption := IntToStr(index); // Index anzeigen Edit1.Text := personen[index].name; Edit2.Text := DateToStr(personen[index].geburt); CheckBox1.Checked := personen[index].geschlecht; Edit3.Text := IntToStr(personen[index].nr) end; Zu den vier Bewegungstasten: [10] procedure TForm1.Button3Click(Sender: TObject); // vorwärts (>) begin if index < pmax then begin dsSpeichern; Inc(index); dsAnzeigen; end; end; procedure TForm1.Button2Click(Sender: TObject); // rückwärts (<) begin if index > 1 then begin dsSpeichern; Dec(index); dsAnzeigen; end end; procedure TForm1.Button1Click(Sender: TObject); // zum Anfang (|<) begin dsSpeichern; index := 1; dsAnzeigen; end; procedure TForm1.Button4Click(Sender: TObject); // zum Ende (>|) begin dsSpeichern; index := pmax; dsAnzeigen; end; Nach Programmstart können die Standardwerte mit den Daten einzelner Personen überschrieben werden. Wie bei einem "richtigen" Datenbankprogramm bewegen Sie sich mit den Tasten durch die Datensätze. Damit enden aber schon die Gemeinsamkeiten, denn leider ist die ganze Mühe umsonst gewesen, wenn Sie das Programm verlassen. Dann wird auch der Inhalt des Arbeitsspeichers gelöscht, und die mühselig eingegebenen Personen sind beim Neustart auf Nimmerwiedersehen verschwunden. Aufgabe: Erweitere obenstehendes Übungsprogramm so, dass die eingegebenen Daten resistent gespeichert werden können (auf die Festplatte), sodass sie bei einem neuerlichen Programmstart wieder zu Verfügung stehen! 6.1. Variante Records Eine besondere Form der Records sind die varianten Records. Hier wird mittels caseUnterscheidung immer nur ein bestimmter Datenteil berücksichtigt. Beispiel: type person = record name: string; case erwachsen: boolean of [11] true: (personalausweisnr: integer); false: (kinderausweisnr: integer; erziehungsberechtigte: string); end; Das Record speichert in jedem Fall die Daten name und erwachsen. Abhängig von dem Wert erwachsen wird dann entweder die personalausweisnr (bei erwachsen=true) oder kinderausweisnr und erziehungsberechtigte (bei erwachsen=false) gespeichert. Ist erwachsen=false, sollte nicht auf den Wert personalausweisnr zugegriffen werden. Dadurch hat man eindeutige Beschreibungen von Feldwerten und kommt nicht in Gefahr, die Kinderausweisnr versehentlich als Personalausweisnr zu speichern. Wichtig ist noch zu bemerken, dass der variante Teil eines Records (also der case-Teil) immer am Ende stehen muss. Und case hat in diesem Fall auch kein schließendes end, wie sonst üblich. Die Teile hinter case teilen sich denselben Speicherbereich. Der Compiler reserviert so viel Platz wie die größte Variante benötigt. Deshalb können auch variante Records in typisierten Dateien verwendet werden. Variante Records können auch in Delphi für .NET-Programmen verwendet werden, werden dort allerdings als "unsicherer Typ" mit einer Warnung versehen. Nun wäre es praktisch, eine größere Menge solcher Variablen zu haben, da eine Adressverwaltung üblicherweise mehr als nur eine Adresse enthält. Die Lösung: Wir kombinieren Array und Record. Damit wir unseren neuen Adresstyp aber einfach weiterverwenden können, wollen wir zuerst einen eigenen Typ anlegen. 6.2. Records mit Methoden Seit Delphi 2006 können Records auch Methoden enthalten. Sie sind damit einer Klasse relativ ähnlich geworden. Vererbung und Polimorphismus sind allerdings nicht möglich. Während Variablen eines Klassentyps bei Funktionsaufrufen per Referenz übergeben werden, werden Records immer als Wert übergeben. Ein Record benötigt zur Erzeugung keinen Konstruktor. Dennoch ist es möglich, zur Initialisierung von Variablen einen zu implementieren, der aber mindestens einen Parameter haben muss. Einen Destruktor hingegen kann es nicht geben, da ein Record ja auch nach Gebrauch nicht wieder freigegeben werden muss - im Gegensatz zur Instanz einer Klasse. 7. Benutzerdefinierte Datentypen Wir erinnern uns: Variablendeklarationen enthalten auf der linken Seite einen Variablennamen und rechts vom Doppelpunkt einen zugehörigen Datentyp. Solche Typen können wir auch selbst definieren, beispielsweise obiges Record: [12] type TAdressRecord = record name: string; plz: integer; ort: string; end; Eine Typdefinition besteht also aus dem Schlüsselwort type gefolgt von einer Konstruktion, die einer Variablendeklaration ähnelt. Da aber statt einer Variablen ein Typ deklariert wird, ist das Folgende auch kein Variablen- sondern ein Typname. Typnamen beginnen in Delphi mit einem großen T, wenn sich der Programmierer an den Styleguide gehalten hat. Statt eines Doppelpunkts wird ein Gleichheitszeichen verwendet. Auf die folgende Weise kann solch ein Typ dann verwendet werden: var adresse: TAdressRecord; Diese Variablendeklaration entspricht der im obigen Beispiel für Records. Wollen wir nun noch ein Array daraus machen, dann geht das so: var adresse: array [1..50] of TAdressRecord; Der Zugriff erfolgt streng nach den Regeln für Arrays und Records: adresse[1].name := 'Hans Müller'; adresse[2].name := 'Susi Sorglos'; Will man einer Funktion oder Prozedur ein Array oder ein Record als Parameter übergeben, muss hierfür auch zuerst ein Typ definiert werden: type TMyArray = array of array of Integer; Anschließend kann "TMyArray" als Typ bei der Variablendeklaration oder bei der Implementierung von Funktionen und Prozeduren verwendet werden. [13] 7.1. Beispiel: Monate, Wochentage unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls; type MonatsTyp = (Januar, Februar, Maerz, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember); //0 1 2 3 4 Grossbuchstaben = 'A'..'Z'; // Teilbereiche herausnehmen Kleinbuchstaben = 'a'..'z'; // Teilbereiche ZZiffern = '0'..'9'; // Teilbereiche TTag = (Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag, Sonntag); Tage = Set of TTag; // Teilbereiche Ziffern = Set of 0..9; // Set of ZZiffern Zeichen = Set of Char; // String ist ein Set of Char TForm1 = class(TForm) Button1: TButton; Label1: TLabel; Label2: TLabel; Edit1: TEdit; procedure Button1Click(Sender: TObject); function MonatToStr (Monat: Monatstyp): String; function StrToMonat (Monat: String): Monatstyp; private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var Monat1, Monat2: Monatstyp; i : integer; Wochentage, Wochenende, Zweitage: Tage; // Tage ist ja Set of TTag begin Monat1 := StrToMonat(Edit1.Text); // StrToMonat Monat2 := Mai; if Monat1 < Monat2 then begin Label1.Caption := MonatToStr(Monat1); //successor-SUCC predecessor-PRED end; Wochentage := [Montag..Freitag]; Wochenende := [Samstag, Sonntag]; if Mittwoch in Wochentage then Label2.Caption := 'huhu'; end; [14] function TForm1.StrToMonat (Monat:String): Monatstyp; begin Case Monat of Januar: MonatToStr := Januar; //Result := 'Januar' Februar: MonatToStr :=Februar; Maerz: MonatToStr := Maerz; April: MonatToStr := April; Mai: MonatToStr := Mai; Juni: MonatToStr := Juni; Juli: MonatToStr := Juli; August: MonatToStr := August; September: MonatToStr := September; Oktober: MonatToStr := Oktober; November: MonatToStr := November; Dezember: MonatToStr := Dezember; end; end; function TForm1.MonatToStr (Monat: Monatstyp): String; begin Case Monat of Januar: MonatToStr := 'Januar'; //Result := 'Januar' Februar: MonatToStr := 'Februar'; Maerz: MonatToStr := 'Maerz'; April: MonatToStr := 'April'; Mai: MonatToStr := 'Mai'; Juni: MonatToStr := 'Juni'; Juli: MonatToStr := 'Juli'; August: MonatToStr := 'August'; September: MonatToStr := 'September'; Oktober: MonatToStr := 'Oktober'; November: MonatToStr := 'November'; Dezember: MonatToStr := 'Dezember'; end; end; end. 7.2. Beispiel: Roulette Wichtige Programmteile sind hier eingefügt: type roulettezahlen = 0..36; //die Gesamtmenge Roulette enthält 37 Zahlen roulette = Set of roulettezahlen; //roulette sind Teilmengen von r.z. TForm1 = class(TForm) Image1: TImage; Label1: TLabel; . . . var Form1: TForm1; one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirdteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty, twentyone, twentytwo, twentythree, twentyfour, twentyfive, twentysix, twentyseven, twentyeight, twentynine, thirty, thirtyone, thirtytwo, thirtythree, thirtyfour, thirtyfive, thirtysix, rote, schwarze, d, m, p, manque, passe, row1, row2, row3, pair, impair, zero: roulette; //alle Gewinne sind vom Typ Roulette zahl, kapital, gewinn, einsatz, i: integer; implementation [15] {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin randomize; kapital := 1000; //die einzelnen TeilMengen werden bestimmt rote := [1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36]; schwarze :=[2,4,6,8,10,11,13,15,17,20,22,24,26,28,29,31,33,35]; d := [25..36]; m := [13..24]; p := [1..12]; pair := [2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36]; impair := [1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35]; manque := [1..18]; passe := [19..36]; row1 := [1,4,7,10,13,16,19,22,25,28,31,34]; row2 := [2,5,8,11,14,17,20,23,26,29,32,35]; row3 := [3,6,9,12,15,18,21,24,27,30,33,36]; procedure TForm1.Button1Click(Sender: TObject); begin zahl := random(37); //Zufallszahl wird am Tisch “gedreht” einsatz := StrToInt(Combobox1.Text); if zahl in rote then //überprüfe ob Zahl in Teilmenge enthalten Label5.Font.Color := clred else Label5.Font.Color := clblack; Label5.Caption := IntToStr(zahl); if checkbet = true then begin if (zahl in rote) and (Checkbox42.Checked = true) then begin kapital := kapital + einsatz*2; Label2.Caption := IntToStr(kapital); end; end; if (zahl in schwarze) and (Checkbox39.Checked = true) then begin kapital := kapital + einsatz*2; Label2.Caption := IntToStr(kapital); end; . . . [16]