Erste Programme mit Delphi Einführung in die Entwicklungsumgebung Grundelemente der Programmiersprache Objekt-Pascal Übungen Helmut Paulus Speyer, 08.05.09 Teil 1 Einführung in die Entwicklungsumgebung Grundelemente der Programmiersprache Objekt-Pascal Problem 3 Mit einem Programm soll der BodyMass-Index BMI berechnet werden. Eingaben: Gewicht in Kg, Körpergröße in m Ausgabe: BMI-Index Ablauf: Ereignisgesteuert 4 Delphi 4 – Entwicklungsumgebung KomponentenPalette (GUI-Objekte) Formular (GUI) Objektinspektor Die Benutzungsoberfläche wird mit Hilfe der Komponentenpalette erstellt. 5 Bearbeiten eines Delphi-Projekts GUI-Objekte haben einen Namen und gehören einer Klasse an. PAnzeige : TPanel LInfo : TLabel GUI : TGUI Formular EdGroesse: TEdit BtBrechnen : TButton Mit Hilfe des Objektinspektors kann man sich die Eigenschaften (Attribute) der GUI-Objekte anschauen und deren Werte verändern. Bearbeiten eines Delphi-Projekts 6 Das Formular enthält Komponenten (GUI-Objekte) vom Typ: • TForm, TEdit, TButton, TLabel, TPanel Delphi gibt den GUI-Objekte automatisch Namen, z. B. TForm1, Label1, Button1, Button2 Die Objekte sollten im Objektinspektor mit sinnvollen Namen (nach Konventionen) belegt werden; z. B.: je nach Typ des Objekts einen Präfix: Brechnen B für Button EGroesse E für Edit PAusgabe P für Panel LErgebnis L für Label … Standardattribute (Eigenschaften) der GUI-Objekte: • Caption Beschriftung einer Komponente (Aufschrift eines Buttons, Labels, Panels,…) • Text Inhalt eines Textfeldes (Edit) • Name Name des Objekts, mit dem es im Programm angesprochen wird 7 Formulardatei „uGUI.dfm“ Ein Blick hinter die Kulissen object GUI: TGUI Left = 202 Top = 137 Width = 420 Height = 253 Caption ='Body MasterIndexberechnen … object EdGroesse: TEdit Left = 112 Top = 136 Width = 57 Height = 21 TabOrder = 2 end object Btberechnen: TButton Left = 184 Top = 136 Width = 89 Height = 25 Caption = 'BMI berechnen' TabOrder = 3 OnClick = BtberechnenClick end end Die Formulardatei uGUI.dfm speichert die Attributwerte der Objekte. Das Formularobjekt GUI enthält alle anderen Objekte als Unterobjekte Diese Datei wird automatisch erzeugt und gepflegt. In älteren Delphi-Versionen als Delphi 4 wird sie als Binärdatei abgespeichert, was zu Kompatiblitätsproblemen führt. Konvertierung: http://hsg.regionkaiserslautern.de/faecher/inf/material/misc/d6_2_d4.php Quelltext-Unit „uGUI.pas“ 8 unit uGUI; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls, ExtCtrls; type TGUI = class(TForm) PAnzeige: TPanel; LInfo: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; EdGewicht: TEdit; EdGroesse: TEdit; Btberechnen: TButton; Btloeschen: TButton; PAusgabe: TPanel; procedure BtloeschenClick(Sender: TObject); procedure BtberechnenClick(Sender: TObject); private { Private-Deklarationen} public { Public-Deklarationen} end; var GUI: TGUI; Einbinden von Systemunits (automatisch) Deklaration des Formulars mit GUI-Objekten (automatisch) 9 Quelltext-Unit „uGUI.pas“ unit uGUI; interface ... var GUI: TGUI; Ereignisbehandlung implementation procedure TGUI.BtberechnenClick(Sender: TObject); var gewicht, groesse, BMI : real; begin Zugriff auf Attribute //Eingabe gewicht := StrToFloat(EdGewicht.Text); groesse := StrToFloat(EdGroesse.Text); //Verarbeitung BMI := gewicht/groesse/groesse; //Ausgabe PAnzeige.Caption := FloatToStrF(BMI,ffFixed,6,2); end; end. Quelltext des Hauptprogramms 10 program BMI; uses Forms, uGUI in 'uGUI.pas' {GUI}; {$R *.RES} begin Application.Initialize; Application.CreateForm(TGUI, GUI); Application.Run; end. Hier findet sich u. a. die Einbindung von Units und Ressourcen die Erzeugung des Fensterobjektes den Start des Programms Diese Datei wird automatisch vom System gepflegt! 11 Ereignisverarbeitung Ein Klick auf den Button soll die Berechnung des BMI-Wertes auslösen. Durch Doppel-Klick auf den Button wird eine neue Prozedur erzeugt: Ereignis OnClick Ereignisprozedur DoppelKlick Diese Prozeduren nie per Hand löschen, sondern nur den Prozedurrumpf. procedure TGUI.BtBerechnenClick(Sender: TObject); begin Das System entfernt den Rest beim nächsten Start! end; Ereignisverarbeitung 12 Implementierung procedure TGUI.BtberechnenClick(Sender: TObject); var Lokale Variablen gewicht, groesse, BMI : real; begin //Eingabe – Übernahme der Daten vom GUI-Objekt gewicht := StrToFloat(EdGewicht.Text); groesse := StrToFloat(EdGroesse.Text); //Verarbeitung BMI := gewicht/groesse/groesse; //Ausgabe – Übergabe der Daten ans GUI-Objekt PAusgabe.Caption := FloatToStrF(BMI,ffFixed,6,2); end; Verarbeitungschema • Eingabe • Verarbeitung • Ausgabe Ein-/ Ausgabesystem mit lokalen Variablen als temporären Zwischenspeichern! Bearbeiten eines Delphi-Projekts 13 Delphi erzeugt eine ganze Reihe von Dateien zur Verwaltung eines Programmierprojektes. Diese Dateien sollte man immer in einem eigenen Ordner speichern. (Quellcodedateien werden als Units bezeichnet.) Vorbereitungsschritte: 1. In Delphi in neues Projekt anlegen: Datei->Neu->Anwendung 2. Projektdateien am besten sofort speichern: 3. Ordner für das neue Projekt anlegen (z. B. BMI) (1) Datei - Alles speichern wählen (2) Die automatisch vorgeschlagen Namen unit1.pas und project1.dpr umbenennen. (z. B.: uGUI.pas und BMI.dpr) u – für Unit Implementierung der Ereignisverarbeitung Neben den oben genannten beiden Dateien werden automatisch im Projektordner viele weitere Dateien angelegt und laufend von Delphi verwaltet. Beim Kompilieren wird aus den Projektdateien ein lauffähiges Programm BMI.exe erzeugt, das anschließend ausgeführt werden kann. Delphi-Hilfen 14 Kontextsensitive Hilfe mit F1 (auch im Fehlerfenster) Laufzeit Debugger Haltepunkte im Quelltext setzen, an den Stellen an, denen das Programm halten soll (in den Rahmen links neben der Quelltextzeile klicken) sobald das Programm anhält, kann mit Hilfe der Maus der Zustand der Variablen angezeigt werden 15 Aufgabe Ergänzen Sie das Programm mit einer Bewertung des BMI nach Alter. Benutzen Sie dazu die folgenden Grundlagen und die Delphi-Hilfe. Die Tabelle zeigt die „wünschenswerte“ BMI-Werte für verschiedene Altersgruppen: Alter 19-24 Jahre BMI 19-24 25-34 Jahre 20-25 35-44 Jahre 21-26 45-54 Jahre 22-27 55-64 Jahre 23-28 >64 Jahre 24-29 Weitere Informationen unter: https://www.uni-hohenheim.de/wwwin140/info/interaktives/bmi.htm Pascal-Grundlagen 16 Variablendeklaration Bezeichner Wertzuweisung Kommentar procedure TGUI.BtberechnenClick(Sender: TObject); var gewicht, groesse, Datentyp BMI : real; begin //Eingabe Trennzeichen gewicht := StrToFloat(EdGewicht.Text); Anweisungen groesse := StrToFloat(EdGroesse.Text); //Verarbeitung BMI := gewicht/groesse/groesse; //Ausgabe PAusgabe.Caption := FloatToStr(BMI); end; string Variablendeklaration var <Bezeichner> : Datentyp; Typumwandlung real Wertzuweisung a := b ; Die Variablen müssen zuweisungskompatibel sein! Pascal-Grundlagen 17 Struktur einer (Ereignis-) Prozedur procedure <Bezeichner>(Parameterliste); var lokale Variablen; Deklarationsteil Die Parameterliste kann auch fehlen begin Anweisungen; Anweisungsteil end; Eine Prozedur (Variable) kann nur verwendet werden, wenn sie deklariert wurde! Konventionen für Bezeichner Es dürfen nur folgende Zeichen verwendet werden Buchstaben (aber keine Umlaute) Zahlen, diese aber erste nach mindestens einem Buchstaben Unterstrich (auch am Anfang) ansonsten keine Sonderzeichen wie „,“, „;“ … Beachte: Delphi ist nicht kontextsensitiv! Pascal-Grundlagen 18 Elementare Datentypen integer : real : boolean : string : Ganze Zahlen (17, -12) Fließkommazahlen (2.675 ) Wahrheitswerte (true, false) Zeichenkette (‘Hallo‘) Typumwandlungen Bei der Ein- und Ausgabe von Daten mit Hilfe von GUI-Objekten müssen häufig Datentypen konvertiert werden. Delphi stellt folgende Funktionen zur Verfügung: Funktion : Ergebnistyp Beispiel StrToInt(<Variable>) : integer groesse := StrToInt(EGroesse.Text) IntToStr(<Variable>) : string PAusgabe.Caption := FloatToStr(BMI); StrToFloat(<Variable>) : real FloatToStr(<Variable>) : string Formatierte Ausgabe: FloatToStrF() : string Siehe Delphi-Hilfe PAusgabe.Caption := FloatToStrF(BMI,ffnumber,8,2); Pascal-Grundlagen 19 Arbeiten mit Zeichenketten Zeichenkettentexte werden in einfachen Anführungszeichen geschrieben. Beispiel: var Ausgabe : string; Ausgabe := ‘Du hast ‘; Zeichenketten kann man mit ‚+‘ aneinander hängen. Ausgabe := Ausgabe + ‚‘leider verloren‘; Die Länge einer Zeichenkette bestimmt man mit der vordefinierten Operation „length“. Der Zugriff auf die einzelnen Zeichen einer Zeichenkette erfolgt über einen Index. Ausgabe[2] ‚u‘ Arithmetische Operatoren : integer / real +, -, *, / Division ( liefert einen Realtyp bei Anwendung auf Integer z. B. 12/4) integer div mod ganzzahlige Division (schneidet Nachkommastellen ab) Rest einer ganzzahligen Division (Beispiel: a := 4 mod 3; 1 a) Pascal-Grundlagen 20 Vergleichsoperatoren : = gleich <> < ungleich kleiner <= > kleiner gleich größer >= größer gleich Kontrollstrukturen Sequenz (Anweisungsblock) begin … Anweisung; … end; Fallunterscheidung Logische Operatoren : AND OR NOT true : wenn beide Operanden wahr true : wenn einer oder beide Operanden wahr Negation des Operanden ( NOT a) Einseitig If Bedingung then begin Anweisung; end; zweiseitig Beispiel: var x : integer; teilbar : boolean; … teilbar := (x mod 3 = 0) AND (x mod 5 = 0); If Bedingung then begin Anweisung; end else begin Anweisung; end; 21 Pascal-Grundlagen Kontrollstrukturen Wiederholung mit Anfangsbedingung Zählschleife while Schleife For –Schleife while Bedingung do begin Anweisung; end; for i := 1 to n do begin Anweisung; end; Wiederholung mit Endbedingung Repeat – Schleife repeat Anweisung; until Bedingung; Reihung / Array Deklaration var Bezeichner : array[StartIndex..EndIndex] of Datentyp; Indizes vom Typ Integer (Aufzählungstyp) Beispiele: var augen : array[1..6] of integer; Der Zugriff auf die einzelnen Felder erfolgt mit Hilfe des Index for i := 1 to 6 do augen[i] := i; Das so definierte Array ist statisch, d. h. die Anzahl der Elemente kann nicht mehr verändert werden. 22 Pascal-Grundlagen Prozeduren und Funktionen Im Unterschied zu Prozeduren liefern Funktionen ein Ergebnis zurück. Schema: function <Bezeichner>(<Parameter>) : <Datentyp>; var <lokale Variablen> begin Anweisung; result := <Ergebnis>; end; Zuweisung des Ergebniswertes an die Funkionsvariabble result Prozeduren und Funktionen können (wie Ereignisprozeduren) als Methoden des Formulars deklariert werden. Beispiel: Die Funktion Max als Funktion des GUI-Objektes function TGUI.Max(z1, z2 : integer): integer; begin if (z1 < z2) then result := z2 else result := z1; end; TGUI = class(TForm) private { Private-Deklarationen} function Max(z1, z2 : integer): integer; public { Public-Deklarationen} end; Projekt Zahlenraten 23 Aufgabe: Es ist ein Programm zu entwickeln, das ein Zahlenratespiel simuliert. Anforderungen: 1. Der Computer bestimmt eine Zufallszahl (1..100), die der Spieler zu erraten hat. 2. Der Spieler hat er beliebig viele Versuche. 3. Nach jeder Zahleneingabe wird angegeben, ob die Zahl zu groß oder zu klein ist. 4. Hat der Spieler die Zahl erraten, so wird die Anzahl der Versuche und eine Bewertung ausgegeben. 5. Alle Ausgaben werden gelöscht, wenn ein neues Spiel begonnen wird. Datenmodell Anzahl der Versuche: Versuchszahl : integer Zu erratende Zahl: Ratezahl : integer Zahlen raten 24 Problem Eingabe der Spieldaten in lokale Variablen aus den GUI-Objekten ist ineffektiv!!! Lösung: Die Daten werden als private Attribute von TGUI deklariert. Damit werden sie zu globalen Variablen (innerhalb des GUI-Objekts1). Hinweise: TGUI = class(TForm) … procedure FormCreate(Sender: TObject); procedure TGUI.BtEingabeClick(Sender: TObject); private RateZahl : integer; public { Public-Deklarationen} end; Beispiel: z := random(20); ganzzahlige Zufallszahl z mit 0 z < 20 { Private-Deklarationen} Versuchszahl : integer; Zufallszahlen können mit der Funktion random erzeugt werden. Spieldaten als private Attribute des Formulars Zahlen raten 25 Initialisierung des Zufallszahlengenerators: Damit der Zufallsgenerator nicht bei jedem Start dieselbe Zahlenfolge erzeugt, wird er durch Aufruf der Prozedur randomize initialisiert. Für solche Initialisierungen wird üblicher-weise Ereignisprozedur FormCreate benutzt, die automatisch beim Start des Programms aufgerufen wird. procedure TGUI.FormCreate(Sender: TObject); begin randomize; end; Das Prozedurgerüst von FormCreate wird bei einem Doppelklick auf das Formular angelegt. Alternativ kann die Prozedur mit dem Objektinspektors erzeugt werden. Mögliche Erweiterungen: 1. 2. Bauen Sie eine Sicherheitsprüfung ein, dass die Eingabe einer Ratezahl nicht über der Feldgröße und nicht unter 0 liegt. Erweitern Sie das Programm so, dass die Feldgröße über ein Edit-Feld eingelesen wird. Teil 2 Übungen Helmut Paulus Speyer, 08.05.09 27 Aufgabe 1 Das Schaltjahr-Problem Die Schaltjahresregelung unseres Kalenders (Gregorianischer Kalender) lautet: Ein Schaltjahr ist ein Jahr, dessen Jahreszahl durch 4 ohne Rest teilbar ist. Ausgenommen davon sind die Jahrhundertwechsel, es sei denn, deren Jahreszahl ist durch 400 ohne Rest teilbar. Es kommt also alle 400 Jahre vor, dass ein Jahrhundertwechsel ein Schaltjahr erzeugt. Das Jahr 2000 ist ein solches Jahr. Zu entwickeln ist ein Programm, das nach Eingabe einer gültigen Jahreszahl prüft, ob dieses Jahr ein Schaltjahr ist. Aufgabe 2 28 Die Entwicklung der Weltbevölkerung schreitet rasch voran: Im Jahr 2006 wurde die 6,6 Milliardengrenze überschritten. Zur Zeit wächst die Weltbevölkerung jährlich um ca. 1,2 %. Mit Hilfe eines kleinen Programms soll die jährliche Entwicklung verfolgt werden. Datenmodell: Jahr Population WFaktor : integer; : real; : real; Interaktionen :Aktuelle Werte eingeben und die Population des nächsten Jahres berechnen und anzeigen Aktuelle Werte eingeben und die Population des vorherigen Jahres berechnen und angezeigen Population in 10-Jahresschritten vorausoder zurückberechnen Aufgabe 3 29 Projekt 17 und 4: Es ist ein Programm zu entwickeln, das das bekannte Kartenspiel simuliert. Anforderungen 1. Spielkarten werden durch einen Würfel ersetzt (Wertbereich [1;...;6]). 2. Es werden Zahlen gewürfelt und aufsummiert. Der Spieler kann nach jedem Spielzug entscheiden, ob er aufhört oder weiter spielen will. 3. Ist die Summe größer als 21, so hat der Spieler verloren. Hört der Spieler bei einer Summe kleiner oder gleich 21 auf, wird noch eine Zahl gewürfelt. Ist die neue Summe immer noch kleiner oder gleich 21, so hat der Spieler verloren, andernfalls gewonnen. 4. Alle Ausgaben werden gelöscht, wenn ein neues Spiel begonnen wird. 30 Links und Literatur E. Modrow: Informatik mit Delphi, Band 1/2, Dümmler-Stam 1998-2000. P. Damann, J. Wemßen: Objektorientierte Programmierung mit Delphi, Band 1. Klett-Verlag 2001. U. Bänisch: Praktische Informatik mit Delphi, Band 1/2. Cornelsen 2001. Frischalowski: Delphi 5.0, Band 1/2, Herdt-Verlag 1999. Pohl: Schülerübungen / Klausuren in Delphi, Heft 1/2, Verlag J. Pohl 1997-2001. K. Merkert: http://hsg.region-kaiserslautern.de/faecher/inf/material/delphi/index.php R. Mechling: http://www.gk-informatik.de/ K. Heidler: http://www.friedrich.fr.schule-bw.de/delphi/delphi.htm Hessischer Bildungsserver: http://lernen.bildung.hessen.de/informatik/ S. Spolwig: http://oszhdl.be.schule.de/gymnasium/faecher/informatik/delphi/index.htm Weitere Hinweise unter: http://www.delphi-source.de Einsteiger-Tutorial http://www.delphi-treff.de/content/tutorials/einsteigerkurs/