Programmierkurs -
Schuljahr 2008/2009
Delphi 7 - Programmcode
Beenden eines Programms (z. B. durch Klick auf den Ende-Button)
application.terminate;
Beschriften eines Buttons
Button1.Caption:='Neue Aufschrift';
Analog können auch andere Komponenten beschriftet werden.
Rechnen mit Werten, die in Edit-Komponenten stehen
Addieren der in Edit1 und Edit2 eingegebenen Werte und Speichern der Summe in Edit3.
Edit3.Text:=IntToStr(StrToInt(Edit1.Text)+StrToInt(Edit2.Text));
Definition von Variablen
Variable werden definiert (=festgelegt) durch
var <Variable1 , Variable2 , Variable3> : <typ> ;
Das Wort "var" zeigt an, dass jetzt die Variablendefinition folgt.
Es
folgen die Namen der Varibalen, die alle den gleichen Typ haben werden,
jeweils getrennt durch ein Komma.. Es darf auch nur ein einziger
Variablenname sein.
Danach folgt ein Doppelpunkt.
Dann wird der Typ genannt. Kennengelernt haben wir die Typen
integer : ganze Zahl, z. B. -23, 0, 123
extended : Fließkommazahl bzw. Dezimalzahl, z. B. 3.14 oder -6.1324657
große oder kleine
Zahlen werden mit einem Zusatz (Zehner-Potenz) geschrieben, der angibt,
um wie viel Stellen der Dezimalpunkt verschoben werden muss
Beispiele: 3.16854E3
= 3168.54 ; 6.24365E-4 = 0.000624365
Es folgt abschließend ein Semikolon.
Grundrechenarten mit Variablen
Die Inhalte zweier Edit-Komponenten werden als Variable gespeichert und dann mit einer Grundrechenart verknüpft.
Das Ergebnis wird in einer dritten Edit-Komponente ausgegeben.
Als Typ wird extended gewählt, damit man auch dividieren kann.
var x1, x2, y : extended;
begin
x1:=StrToFloar(Edit1.Text);
x2:=StrToFloat(Edit2.Text);
y:=x1+x2;
(oder y:=x1-x2;
oder y:=x1*x2; oder y:=x1/x2;)
Edit3.Text:=FloatToStr(y);
end;
Berechnung von Termen
Ein Term y, der aus einer Berechnung mit der Variablen x besteht, wird in Edit2 ausgegeben. In Edit1 wird der x-Wert eingegeben.
Beispiel: 
var x, y : extended;
begin
x:=StrToFloat(Edit1.Text);
y:=(3*x-7)/((5*x+2)*(6*x-4));
Edit2.Text:=FloatToStr(y);
end;
for-Schleife
Soll
ein bestimmter Programmcode (eine oder mehrere Anweisungen) eine
bestimmte Anzahl mal wiederholt werden, so kann sinnvoll die
for-Schleife verwendet werden.
Aufbau einer for-Schleife:
for <integer-Variable> := <Anfangswert> to <Endwert> do <Anweisung>
for,
:=, to und do sind Schlüsselworte und müssen mit mindestens 1
Leerzeichen Abstand zu den benachbarten Werten geschrieben werden.
Die
<integer-Variable> erhält zu Beginn den Wert von
<Anfangswert> und wird bei jeder Wiederholung der
<Anweisung> um 1 vergrößert, bis sie den
<Endwert> erhalten hat.
In <Anweisung> kann der Wert von
<integer-Variable> verwendet werden. Im ersten Durchlauf ist das
der Wert <Anfangswert>, im letzten Durchlauf der Wert
<Endwert>.
Soll mehr als eine Anweisung wiederholt werden,
werden die zu wiederholenden Anweisungen zwischen begin und end
gestellt (siehe Beispiel).
Beispiel 1 (Das kleine Einmal-Sieben wird im Memo-Fenster zeilenweise ausgegeben):
var i,Zahl:integer;
begin
Zahl:=7;
for i:=1 to 10 do
Form1.Memo1.Lines.Add(IntToStr(7*i));
end;
Beispiel 2 (ein Muster wird auf der Image1-Komponente ausgegeben):
var i:integer;
begin
for i:=0 to 100 do
begin
Form1.Image1.Canvas.moveto(0,4*i);
Form1.Image1.Canvas.lineto(400,400-4*i);
end;
end;
Anwendungen zur for-Schleife
Summenbildung (kleiner Gauss)
Der junge Gauss soll vom Lehrer die Aufgabe erhalten haben, die ersten 100 natürlichen Zahlen zusammenzuzählen.
Er hat dazu eine Formel entwickelt und konnte sehr bald das Ergebnis nennen.
Der Rechner erledigt diese Aufgabe mit einer for-Schleife:
var Zahl,Summe:integer;
begin
Summe:=0; //verwendete Variablen zuerst initialisieren (Anfangswert geben)
for Zahl:=1 to 100 do
Summe:=Summe+Zahl;
Form1.Edit1.Text:=IntToStr(Summe);
end;
Berechnen einer Fakultät
Das
Produkt der ersten natürlichen Zahlen nennt man Fakultät und
schreibt es als Zahl mit einem Ausrufezeichen:
6!=1·2·3·4·5·6
Das Programm
berechnet zu den Zahlen in Edit1 die Fakultät und zeigt sie samt
allen vorherigen Berechnungen in einer Memo-Komponente an.
var Zahl, Produkt, Wert : integer;
begin
Produkt:=1;
Zahl:=StrToInt(Edit1.Text);
for Wert:=1 to Zahl do
Produkt:=Produkt*Wert;
Form1.Memo1.Lines.Add(IntToStr(Zahl)+'! = '+IntToStr(Produkt));
end;
Zeichnen auf Image1
Folgende Zeichenelemente haben wir kennen gelernt:
- Stiftfarbe einstellen auf Rot
Form1.Image1.Canvas.Pen.Color:=clred; - Flächenfüll-Modus auf "voll ausgefüllt" setzen
Form1.Image1.Canvas.Brush.Style:=bssolid; - Flächenfüll-Modus auf Farbe Rot setzen
Form1.Image1.Canvas.Brush.Color:=clred; - Bewegen des Cursors zum Punkt (x,y) ohne zu zeichnen
Form1.Image1.Canvas.MoveTo(x,y) - Bewegen des Cursors zum Punkt (x,y) einschließlich Zeichnen der Verbindungsstrecke
Form1.Image1.Canvas.LineTo(x,y) - Rechteck zeichnen: Obere linke Ecke bei (x1,y1) und untere rechte Ecke bei (x2,y2)
Form1.Image1.Canvas.Rectangle(x1,y1,x2,y2) - Ellipse zeichnen: Obere linke Ecke des umgebenden Rechtecks bei (x1,y1) und untere rechte Ecke bei (x2,y2)
Form1.Image1.Canvas.Ellipse(x1,y1,x2,y2)
Ist das umgebende Rechteck ein Quadrat, so ist die Ellipse ein Kreis. - Rechteck
mit abgerundeten Ecken zeichnen: Obere linke Ecke bei (x1,y1) und
untere rechte Ecke bei (x2,y2). r1 und r2 geben die Radien der
Abrundung in x- bzw. y-Richtung an.
Form1.Image1.Canvas.RoundRect(x1,y1,x2,y2,r1,r2) - Punkt auf der Zeichenfläche einfärben: Der Punkt an den Koordinaten (x/y) wird rot eingefärbt.
Form1.Image1.Canvas.Pixels[x,y]:=clred;
Zufallszahlen
- Erzeugen von Zufallszahlen aus dem Bereich [0,1): Die Zufallszahl mi 0<=x<1 wird in der Variable x gespeichert:
x:=random; - Erzeugen
von ganzen Zahlen als Zufallszahlen aus dem Bereich von 0 bis zu einer
wählbaren oberen Grenze: Obere Grenze ist die angegebene Zahl
minus 1.
x:=random(n); erzeugt ganze Zahlen einschließlich 0 und n-1 - "Mischen" des Zufallszahlengenerators, so dass eine neue Zahlenfolge generiert wird:
randomize;
Beispiel: Füllen eines rechteckigen Bereiches der Breite 300 und der Höhe 100 mit zufällig verteilten Punkten
var i:integer;
begin
for i:=1 to 1000 do
Form1.Image1.Canvas.Pixels[random(300),random(200)]:=clblack;
end;
Warteschleife
- procedure
delay(x:integer);
-
var
StartZeit,StopZeit:TTimeStamp; //
Zeit mit 1/100 sec. Genauigkeit
-
Differenz:integer;
-
begin
//
now fragt die aktuelle Zeit ab,
-
StartZeit:=DateTimeToTimeStamp(now);
//
hier die Startzeit
-
repeat
-
StopZeit:=DateTimeToTimeStamp(now);
//
hier die aktuelle Zeit
-
Differenz:=StopZeit.Time-StartZeit.Time;
-
application.ProcessMessages;
//
hier Notausstieg bei zu langer
-
if Ende then exit;
//
Wartezeit
-
until
Differenz>x;
-
end;
Anmerkung: Der Aufruf sleep(<Zeit>)
leistet das gleiche. Statt <Zeit> setzt man als Parameter
die Anzahl der Millisekunden ein, während derer gewartet werden
soll.
repeat-until-Schleife
Weiß
man nicht, wie oft eine Schleife durchlaufen werden soll und ist das
Verlassen der Schleife durch eine Bedingung gegeben, so kann man
günstig die repeat-until-Schleife benutzen.
Zwischen den festgelegten Worten repeat und until stehen die ANweisungen, die immer wieder wiederholt werden sollen.
Nach until folgt eine Bedingung. Ist diese Bedingung erfüllt, so wird die Schleife nicht mehr durchlaufen.
Beispiel:
Addiert man die natürlichen Zahlen immer weiter (1+2+3+...), so
wird die Summe irgendwann die Grenze 1000 überschreiten. Bei
welcher natürlichen Zahl ist das der Fall?
var Zahl,Summe:integer;
begin
Zahl:=0;
Summe:=0;
repeat
Zahl:=Zahl+1;
Summe:=Summe+Zahl;
until Summe>1000;
Edit1.Text:=IntToStr(Zahl);
Division
In delphi gibt es 2 Divisionen:
Bei 27/5 wird das Ergebnis durch eine Zahl mit Dezimalpunkt ausgegeben: 27/5=5.4
Bei 27 div 5 wird 27 durch 5 geteilt und der ganzzahlige Teil ist das Ergebnis: 27 div 5 = 5
Der Rest wird durch 27 mod 5 ermittelt: 27 mod 5 = 2
Verzweigung mit if ... then ... else
Hängt
von eienr Bedingung ab, mit welcher Anweisung das Programm weiter
machen soll, eignet sich die if ... then ... else-Anweisung:
Der Aufbau dieser Anweisung folgt diesem Schema:
if <Bedingung>
then begin <Anweisungen, die ausgeführt werden sollen, wenn die Bedingung erfüllt ist> end
else begin <Anweisungen, die ausgeführt werden sollen, wenn die Bedingung nicht erfüllt ist> end;
Beispiel: Ulam-Folge: Es werden nacheinander Zahlen aufgeschrieben, die nach folgender Regel gebildet werden:
Ist eine Zahl x gerade, so wird die nächste Zahl gebildet aus x div 2.
Ist eine Zahl ungerade, so wird die nächste Zahl gebildet aus 3·x+1
var Zahl,Nummer:integer;
begin
try
Zahl:=StrToInt(Edit1.Text);
Nummer:=1;
Memo1.Lines.Add(IntToStr(Nummer)+' '+IntToStr(Zahl));
repeat
if round(Zahl/2)*2=Zahl
then Zahl:=Zahl div 2
else Zahl:=3*Zahl+1;
Nummer:=Nummer+1;
Memo1.Lines.Add(IntToStr(Nummer)+' '+IntToStr(Zahl));
until Zahl<2;
except
showmessage('Edit1 enthält keine Zahl');
end;
end;
Bewegen einer Figur über den Bildschirm
Nach folgendem Schema kann man Figuren über den Bildschirm bewegen:
1. Den Bildschirm mit einer vorhandene Figur löschen
2. Die Koordinaten der Figur neu einstellen
3. Die Figur zeichnen.
4. bei 1. weiter machen
Es
ist günstig, alle Punkte der Figur relativ zu einem einzigen Punkt
anzugeben. Wird dieser Punkt auf dem Bildschirm verschoben, werden alle
anderen Punkte und damit die Figur auch verschoben.
var x,i:integer;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
image1.Canvas.Brush.Style:=bssolid;
image1.Canvas.Brush.Color:=clyellow;
image1.Canvas.Rectangle(0,0,image1.Width,image1.Height);
if (x<0) or (x>image1.Width) then i:=-i;
x:=x+i;
image1.Canvas.Brush.Color:=clred;
image1.Canvas.Rectangle(x,round(sin(x/10)*100)+150,x+30,150);
end;
initialization
x:=0;
i:=1;
Bewegen eines "Balls" über den Bildschirm
Der Ball wird an den Kanten des Bildschirms reflektiert.
Vergleiche auch den oben stehenden Programmcode.
var x,y,dx,dy:integer; // Diese Variablen gelten im gesamten Programm
const Breite=20; // Breite ist als Konstante festgelegt
// Breite kann man nicht
als Variable benutzen
procedure TForm1.BEndeClick(Sender: TObject);
begin
application.Terminate;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
image1.Canvas.Brush.Style:=bssolid;
image1.Canvas.Brush.Color:=clwhite;
image1.Canvas.Ellipse(x,y,x+Breite,y+Breite);
image1.Canvas.Brush.Color:=clred;
x:=x+dx;
y:=y+dy;
if x<0 then dx:=-dx;
if y<0 then dy:=-dy;
if x+Breite>image1.Width then dx:=-dx;
if y+Breite>image1.Height then dy:=-dy;
image1.Canvas.Ellipse(x,y,x+Breite,y+Breite); // Löschen des Balls
// oder
image1.Canvas.Rectangle(0,0,image1.width,image1.height); um
den genzen Bildschirm zu löschen
end;
procedure TForm1.Button1Click(Sender: TObject);
begin // mit diesem Programmteil kann man den Timer an- und abschalten
timer1.Enabled:=not(timer1.Enabled);
if Button1.Caption='Pause'
then Button1.Caption:='Weiter'
else Button1.Caption:='Pause';
end;
initialization
x:=10;
y:=10;
dx:=2;
dy:=2;
Die logischen Operatoren "and" und "or"
Wird im Programm eine Bedingung erwartet
(Beispiel: if <Bedingung> then <Anweisung1> else <Anweisung2>;),
so können mehrere Bedingungen mit den Operatoren "and" und "or" verbunden werden.
"and"
steht dafür, dass beide angegebenen Teil-Bedingungen erfüllt
sein müssen, damit die Bedingung insgesamt erfüllt ist.
Beispiel:
(a=6) and (b>3) ist dann richtig, wenn die Variable a genau
den Wert 6 hat und die Variable b eine Zahl enthält, die
größer als 3 ist.
a=6 und b=1 erfüllt die Bedingung nicht.
a=2 und b=8 erfüllt die Bedingung auch nicht.
a=6 und b=12 erfüllt die Bedingung.
"or"
steht dafür, dass wenigstens eine der angegebenen Teil-Bedingungen
erfüllt ist, damit die Bedingung insgesamt erfüllt ist.
Beispiel:
(a=6) or (b>3) ist dann richtig, wenn die Variable a genau den
Wert 6 hat oder die Variable b eine Zahl enthält, die
größer als 3 ist oder sowohl a=6 ist als auch b eine Zahl
größer 3 ist.
a=6 und b=1 erfüllt die Bedingung, da a=6 zutrifft.
a=2 und b=8 erfüllt die Bedingung auch, da b>3 ist.
a=6 und b=12 erfüllt die Bedingung auch, da beide Teilbedingungen erfüllt sind.
a=2 und b=1 erfüllt die Bedingung nicht, da a nicht 6 ist und b nicht größer als 3 ist.
procedure
Einzelne Anweisungen kann man zu einem Modul kapseln und sie von anderer Stelle aus durch ihren Namen aufrufen.
Aufbau einer solchen Prozedur:
procedure <Name>;
begin
<Anweisungen>
end;
Hinter
<Name> kann noch in Klammern eingeschlossen eine Liste mit
Variablennamen angeführt werden, deren Werte beim Aufruf der
Prozedur übergeben werden.
Beispiel:
procedure Zeichne(x,y,Laenge,Hoehe:integer; Farbe:tcolor);
begin
with form1.Image1.Canvas do
begin
brush.Color:=Farbe;
rectangle(x,y,x+Laenge,y+Hoehe);
end;
end;
procedure TForm1.BZeichneClick(Sender: TObject);
var i:integer;
begin
for i:=1 to 10 do
Zeichne(10*i,20*i,50*i,110-10*i,100000*i);
end;
Ausgabe des Programms: 
Herunterladen des Programms mit Klick auf den Link oder das Bild.
Parameterübergabe bei Prozeduren und Funktionen
Zunächst eine vollständige Prozedur zur Berechnung von Potenzen der Art ab :
procedure ahochb (a:extended; b:integer; var Potenz:extended);
var i:integer;
begin
Potenz:=1;
for i:=1 to b do
Potenz:=Potenz*a;
end;
An einer anderen Stelle im Programm kann man diese Prozedur aufrufen z.B. durch
ahochb (Basis, Exponent, Ergebnis);
wobei die Variablen "Basis" und "Ergebnis" als extended und "Exponent" als integer deklariert werden.
Beim Aufruf müssen "Basis" und "Exponent" gültige Werte beinhalten.
"Ergebnis" bekommt seinen Wert aus der Prozedur.
In der Reihenfolge, wie es beim Aufruf in der Klammer angegeben ist, erhalten die Variablen in der Prozedur ihre Werte.
Die
Werte a und b können in der Prozedur ruhig verändert werden.
Im Hauptprogramm bleiben die Variablenwerte für "Basis" und
"Exponent" erhalten.
Vor "Potenz" steht var. Das bedeutet, dass
diese Variable zunächst den Wert von "Ergebnis" bekommt und dann
den neuen Wert an "Ergebnis" übergibt. Dabei wird der alte Wert
von "Ergebnis" überschrieben.
Man kann die Prozedur auch als Funktion schreiben. Dann muss die Kopfzeile heißen:
function ahochb (a:extended; b:integer) : extended;
Das heißt, dass dem Funktionsnamen ein Datentyp zugeordnet wird.
Aufgerufen wird dann die Funktion z.B. bei der Rechnung y=3+25-7 durch
y:=3 + ahochb(2,5) - 7
Felder
Sollen
in einem Programm Messreihen verarbeitet werden, macht es wenig Sinn,
für jeden Messwert eine eigene Variable zu definieren.
Man fasst stattdessen viele Werte unter einem Variablennamen zusammen und unterscheidet die Werte durch Indizes.
Beispiel:
var Werte:array[0..10] of integer;
Eine
Variable mit Namen "Werte" wird definiert, unter der auf 11
verschiedene Speicherstellen zugegriffen werden kann: Werte[0],
Werte[1], ... ,Werte[9], Werte[10]
In allen 11 Speicherstellen kann jeweils eine integer-Zahl abgelegt werden.