Powerpoint-Präsentation Teil 2

Werbung
Einführung in die
Software-Entwicklung mit Delphi
Teil 2
Klaus Becker
2005
Miniprojekt „Chiffrierung“
2
PYLZFOWBNQCYBUVNCBLGYCHY
AYBYCGMWBLCZNYHNTCZZYLN
VDOYHFDHVDU





Datenmodelle entwickeln
Zeichen und Zeichenketten verarbeiten
Schnittstellenbeschreibungen lesen
Vordefinierte Komponenten benutzen
Module testen und Fehler suchen
3
Teil 1
Ein einfaches Chiffriersystem
Chiffrierung nach Caesar
4
PYLZFOWBNQCYBUVNCBLGYCHY
AYBYCGMWBLCZNYHNTCZZYLN
VDOYHFDHVDU
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
Quelltext:
SALVECAESAR
Schlüssel: 3
Geheimtext:
VDOYHFDHVDU
Chiffriersystem
5
Schlüssel
Schlüssel
3
3
SALVECAESAR
VDOYHFDHVDU
Quelltext
Geheimtext
Verschlüsselung
SALVECAESAR
Quelltext
Entschlüsselung
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
6
Zielsetzung
Ziel ist es, ein System zu entwickeln, mit dem der Benutzer Texte nach der
Caesar-Methode verschlüsseln und wieder entschlüsseln kann.
7
Anforderungen
/1/ Der Benutzer kann Texte selbst eingeben.
/2/ Der Benutzer kann den Schlüssel (0..25) vorgeben.
/3/ Der verschlüsselte Text wird angezeigt und kann auch wieder
entschlüsselt werden.
/4/ Erweiterung: Das Programm bereitet den Text geeignet vor: entfernt
Leerzeichen; wandelt Umlaute um etc.
...
Erweitertes Datenmodell
8
Schlüssel
Schlüssel
3
3
SALVECAESAR
VDOYHFDHVDU
Quelltext
Geheimtext
Verschlüsselung
quelltext: string;
geheimtext: string;
schluessel: integer;
procedure verschluesseln;
procedure entschluesseln;
SALVECAESAR
Quelltext
Entschlüsselung
Daten
Operationen auf den Daten
9
Implementierung
unit Unit1;
interface
uses
Windows, ...;
type
TForm1 = class(TForm)
...
BVerschluesseln: TButton;
BEntschluesseln: TButton;
procedure
BVerschluesselnClick(Sender: TObject);
procedure BEntschluesselnClick(Sender: TObject);
private
{ Private-Deklarationen }
quelltext: string;
geheimtext: string;
schluessel: integer;
Erweitertes Datenmodell
procedure verschluesseln;
procedure entschluesseln;
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
10
Implementierung
implementation
{$R *.DFM}
procedure TForm1.verschluesseln;
begin
// ...
end;
Algorithmus zur Operation
procedure TForm1.BVerschluesselnClick(Sender: TObject);
begin
// Daten aktualisieren
schluessel := StrToInt(ESchluessel.Text);
quelltext := EQuelltext.Text;
// Daten verarbeiten
verschluesseln;
Ausführung der Operation
// Benutzungsoberfläche aktualisieren
EGeheimtext.Text := geheimtext;
end;
...
end.
Exkurs: Datentyp „char“
11
Mit Hilfe des Datentyps „char“ werden in Delphi / Pascal Zeichen
beschrieben. Die zulässigen Zeichen und ihre Nummerierung werden durch
den ASCII-Code festgelegt.
Code
...
10
...
13
...
65
66
...
90
...
97
98
...
122
...
Zeichen
...
LF
...
CR
...
'A'
'B'
...
'Z'
...
'a'
'b'
...
'z'
...
ASCII-Zeichensatz
Beachte:
Darstellung mit Hochkommata
Zulässige Zeichen
http://de.selfhtml.org
/inter/zeichensaetze.htm
Exkurs: Datentyp „char“
12
Mit Hilfe der Operationen „ord“ und „chr“ kann man die Zuordnung
zwischen Code und Zeichen wechselseitig bestimmen.
Code
...
10
...
13
...
65
66
...
90
...
97
98
...
122
...
Zeichen
...
LF
...
CR
...
'A'
'B'
...
'Z'
...
'a'
'b'
...
'z'
...
Operation „Kodieren“
ord: char  {0 ... 255}
ord('A')
 65
Operation „Dekodieren“
chr: {0 ... 255}  char
chr(65)  'A'
Exkurs: Datentyp „string“
13
Mit Hilfe des Datentyps „string“ werden in Delphi / Pascal Zeichenketten
beschrieben.
'Hallo'
'SALVE CAESAR!'
Beachte:
Darstellung mit Hochkommata
'Delphi 8.0'
''
Leere Zeichenkette
Zeichenkette mit
Steuerzeichen für
Zeilenumbrüche
'unit Unit1;[LF][CR]interface[LF][CR]uses [LF][CR]Windows, Messages,
SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
ExtCtrls, Spin;'
Im voreingestellten Status kann eine Zeichenkette vom Datentyp „string“ bis
etwa 231 Zeichen lang sein.
14
Exkurs: Datentyp „string“
var
quelltext: string;
c: char;
n: integer;
Längenbestimmung
quelltext := 'Hallo!';
// quelltext: 'Hallo!'
n := length(quelltext);
// n: 6
c := quelltext[1];
quelltext[1] := 'h';
Zugriff auf
Zeichen
// c: 'H'
// quelltext: 'hallo '
quelltext := quelltext + ' Caesar'
// quelltext: 'hallo Caesar'
n := length(quelltext);
// n: 12
Konkatenation
Der Zugriff auf die einzelnen Zeichen einer Zeichenkette erfolgt über einen
Index.
Die Länge einer Zeichenkette bestimmt man mit der vordefinierten
Operation „length“:
Zeichenketten kann man mit dem Konkatenationsoperator „+“ aneinander
hängen.
Verschlüsselungsalgorithmus
15
Wir gehen zunächst davon aus, dass der Quelltext nur aus Großbuchstaben
besteht.
Code
verschluesseln
...
65
geheimtext := ''
66
67
68
69
70
FÜR i VON 1 BIS length(quelltext)
c := quelltext[i]
n := ord(c)
...
Zeichen
...
'A'
'B'
'C'
'D'
'E'
'F'
...
n := n + schluessel
n > 90
ja
nein
n := n - 26
ord: char  {0; ...; 255}
ord('B')
 66
d := chr(n)
geheimtext := geheimtext + d
chr: {0; ...; 255}  char
chr(69)  'E'
Implementierung als Unterprogramm
16
Ein Unterprogramm ist eine Programmeinheit, die Anweisungen zur
Lösung eines Teilproblems zu einer neuen Einheit zusammenfasst.
Deklaration des Unterprogramms
verschluesseln
geheimtext := ''
FÜR i VON 1 BIS length(quelltext)
c := quelltext[i]
n := ord(c)
n := n + schluessel
procedure TForm1.verschluesseln;
var i, n: integer;
begin
geheimtext := '';
for i := 1 to length(quelltext) do
begin
n := ord(quelltext[i]);
n := n + Schluessel;
if n > 90 then n := n-26;
geheimtext := geheimtext + chr(n);
end
end;
n > 90
ja
nein
n := n - 26
d := chr(n)
geheimtext := geheimtext + d
...
Aufruf des Unterprogramms
begin
...
verschluesseln;
...
end;
17
Aufgabe
Ergänzen Sie den Algorithmus zum Entschlüsseln.
Code
...
65
66
67
68
69
70
...
Zeichen
...
'A'
'B'
'C'
'D'
'E'
'F'
...
ord: char  {0; ...; 255}
ord('B')
 66
chr: {0; ...; 255}  char
chr(69)  'E'
18
Aufgabe
Implementieren Sie die Algorithmen. Ergänzen Sie hierzu das bereits
erstellte Programmfragment im Verzeichnis „Caesar1-GrundprogrammAufgabe“.
19
Aufgabe
Das Programm soll anschließend wie folgt verbessert werden:
- Im Quelltext sollen alle Kleinbuchstaben in Großbuchstaben umgewandelt
werden.
- Im Quelltext sollen alle Umlaute durch Vokalkombinationen ersetzt
werden.
- Im Quelltext sollen alle Sonderzeichen (wie Leerzeichen, Satzzeichen etc.)
gelöscht werden.
Beispiel: Ich würde gerne dösen.  ICHWUERDEGERNEDOESEN
Hierzu soll ein zusätzlicher Button eingeführt werden (vgl. nächste Folie).
20
Aufgabe
21
Teil 2
Schnittstelle eines Unterprogramms
22
Zielsetzung
Die Vorbereitung des Quelltextes lässt sich auch mit Hilfe vordefinierter
String-Operationen (Length, Pos, Delete, Insert) implementieren. Hierzu
muss man genau wissen, wie diese String-Operationen benutzt werden
können. Alle Informationen, die man zur Benutzung einer Operation
benötigt, werden in einer sog. Schnittstellenbeschreibung festgelegt. Ziel ist
es hier, den Umgang mit Schnittstellenbeschreibungen kennen zu lernen.
23
Schnittstellenbeschreibungen
function Length(S: string): integer;
Delphi-Hilfe
Beschreibung:
Length gibt die Anzahl der im angegebenen String vorhandenen Zeichen zurück.
Beispiel:
Anzahl := Length('Delphi');
{Anzahl: 6}
function Pos(Substr: string; S: string): integer;
Delphi-Hilfe
Beschreibung:
Pos sucht in dem String S nach dem Teilstring Substr. Wird der Teilstring gefunden, gibt Pos
den Integer-Index des ersten Zeichens von Substr in S zurück. Die Groß/Kleinschreibung wird
von Pos nicht berücksichtigt. Ist Substr nicht vorhanden, wird der Wert 0 zurückgegeben.
Beispiele:
Position := Pos('hi', 'Delphibuch');
{Position: 5}
Position := Pos('Hi', 'Delphibuch');
{Position: 5}
Position := Pos('hihi', 'Delphibuch');
{Position: 0}
24
Schnittstellenbeschreibungen
procedure Delete(var S: string; Index, Count: integer);
Beschreibung:
Delete entfernt, beginnend mit S[Index], Count Zeichen aus dem String S. Ist der Wert von
Index größer als die Länge von S, werden keine Zeichen gelöscht. Werden mit Count mehr
Zeichen angegeben, als beginnend bei S[Index] im String vorhanden sind, wird der Rest des
Strings gelöscht.
Beispiel:
{Wort: 'Delphibuch'}
Delete(Wort, 4, 3);
{Wort: 'Delbuch'}
Delphi-Hilfe
procedure Insert(Source: string; var S: string; i: integer);
Beschreibung:
Insert fügt Source in S an der Position S[i] ein.
Beispiel:
{Wort: 'Delbuch'}
Insert('phi', Wort, 4);
{Wort: 'Delphibuch'}
Delphi-Hilfe
25
Schnittstellenbeschreibungen
function Copy(S: string; Index, Count: Integer): string;
Beschreibung:
S ist ein Ausdruck des Typs String. Index und Count sind Integer-Ausdrücke. Copy gibt einen
Substring zurück, das Count Zeichen oder Elemente ab S[Index] enthält. Ist Index größer als
die Länge von S, gibt Copy einen leeren String zurück. Gibt Count mehr Zeichen oder ArrayElemente an, als verfügbar sind, werden nur die Zeichen oder Elemente von S[Index] bis zum
Ende von S zurückgegeben.
Beispiel:
{Wort: 'Delphibuch'}
Teilwort := Copy(Wort, 7, 4);
{Wort: 'Delphibuch'; Teilwort: 'buch'}
Delphi-Hilfe
26
Funktionen / Prozeduren
Eine Prozedur ist ein Unterprogramm ohne Rückgabewert, eine Funktion
ein Unterprogramm mit Rückgabewert.
function Length(S: string): integer;
Typ des Rückgabewerts
Beschreibung:
Length gibt die Anzahl der im angegebenen String vorhandenen Zeichen zurück.
Beispiel:
Anzahl := Length('Delphi');
{Anzahl: 6}
Aufruf nur mit Weiterverarbeitung des
Rückgabewerts
procedure Insert(Source: string; var S: string; i: integer);
Beispiel:
{Wort: 'Delbuch'}
Insert('phi', Wort, 4);
{Wort: 'Delphibuch'}
Aufruf als eigenständige
Anweisung
27
Parameter
Mit Hilfe von Parametern kann man Daten zur Laufzeit an das betreffende
Unterprogramm übergeben. Bei der Deklaration werden für die zu
übergebenden Daten Platzhalter (formale Parameter) eingeführt, denen zur
Laufzeit dann bestimmte Werte (aktuelle Parameter) übergeben werden.
Formale Parameter
(Platzhalter)
procedure Delete(var S: string; Index, Count: integer);
Beispiel:
{Z: ['Baumschule']}
Delete(Z, 5, 6)
{Z: ['Baum']}
Aktuelle Parameter
(übergebene Daten)
Parameter
28
procedure Delete(var S: string; Index, Count: integer);
Beispiel:
{Z: ['Baumschule']}
Delete(Z, 5, 6)
{Z: ['Baum']}
Aktuelle Parameter
(übergebene Daten)
Delete
Z
var S: string
Import/Export-Situation
5
Index: integer
Import-Situation
6
Count: integer
Import-Situation
Formale Parameter
(Platzhalter)
Parameterübergabemechanismen
29
{Z: ['Baumschule']}
Delete(Z, 5, 6)
Delete
Z: ['Baumschule']
5
6
Adresse
Wert
Wert
[ ]:S
Referenzbildung
[5]:Index
Wertübergabe
[6]:Count
Wertübergabe
Delete
Z: ['Baum']
[ ]:S
5
[ ]:Index
6
[ ]:Count
{Z: ['Baum']}
Parameterübergabemechanismen
30
Übergabemechanismen:
call-by-value: Der Wert des aktuellen Parameters wird an den
Werteparameter übergeben.
call-by-reference: Es wird eine Referenz zwischen dem aktuellen Parameter
und dem Referenzparameter erzeugt.
Prozeduraufruf:
Delete(Z, 5, 6)
aktuelle Parameter
Übergabesituation:
Z: ['Baumschule']
5
6
Delete
Adresse
Wert
Wert
Referenzparameter
[ ]:S
Referenzbildung
[5]:Index
Wertübergabe
[6]:Count
Wertübergabe
Werteparameter
Datenaustauschsituationen
31
Daten-Import:
t
Daten-Export:
y
Daten-Transport:
y
P
x
P
var x
P
var x
Der aktuelle Parameter kann ein
Term sein. Der Wert des Terms wird
durch call-by-value an den
Werteparameter übergeben.
Der aktuelle Parameter muss eine
Variable sein. Der Referenzparameter
wird durch call-by-reference an den
aktuellen Parameter gebunden.
Der aktuelle Parameter muss eine
Variable sein. Der Referenzparameter
wird durch call-by-reference an den
aktuellen Parameter gebunden.
32
Aufgabe
Ziel ist es, eine Prozedur zu entwickeln, mit der man innerhalb einer
Zeichenkette eine Zeichenkette durch eine neue Zeichenkette ersetzen kann.
Bsp.: Ersetze `Hans` durch `Peter` innerhalb von `Hans im Glück‘
Spezifizieren Sie zunächst den Datenaustausch / die Parameter der
Prozedur.
Lösungsvorschlag
33
Datenaustausch:
Ersetze
'ß'
alt: string
'SS'
neu: string
hilf
var text: string
Deklaration:
procedure Ersetze(alt: string; neu: string; var text: string);
Verhaltensbeschreibung:
Die Prozedur „Ersetze“ ersetzt innerhalb der Zeichenkette „text“ die Zeichenkette „alt“
durch die neue Zeichenkette „neu“.
Beispiel:
{hilf: ['Hans im Glück']}
Ersetze('Hans', 'Peter', hilf);
{hilf: ['Peter im Glück']}
34
Aufgabe
Sie finden unten einen Implementierungsvorschlag für die Prozedur
„ersetze“. Analysieren Sie den zu Grunde liegenden Algorithmus und
beschreiben Sie ihn möglichst verständlich.
procedure ersetze(alt: string; neu: string; var text: string);
var
stelle: integer;
hilfstext: string;
begin
hilfstext := '';
stelle := pos(alt, text);
while stelle > 0 do
begin
hilfstext := hilfstext + Copy(text, 1, stelle-1) + neu;
Delete(text, 1, stelle+length(alt)-1);
stelle := pos(alt, text);
end;
hilfstext := hilfstext + text;
text := hilfstext;
end;
35
Lösungsvorschlag
36
Modultest
Mit einem Modultest überprüft man, ob eine Programmeinheit (z. B. eine
Prozedur) das gewünschte Verhalten zeigt.
Tipps:

Modultests auf jeden Fall durchführen.

Mit Modultests so früh wie möglich beginnen.

Modultests möglichst isoliert durchführen.

Möglichst alle relevanten Testfälle prüfen.

Auch Sonderfälle prüfen.
37
Testumgebung
program Project1;
{$APPTYPE CONSOLE}
uses
sysutils;
DelphiKonsolenanwendung
var
meinText: string;
ersetzeText: string;
durchText: string;
procedure ersetze(alt: string; neu: string; var text: string);
...
begin {Hauptprogramm}
write('alter Text: '); readln(meinText);
write('ersetze: '); readln(ersetzeText);
write('durch: '); readln(durchText);
ersetze(ersetzeText, durchText, meinText);
write('neuer Text: '); writeln(meinText);
readln;
end.
38
Aufgabe
Starten Sie das Testprogramm im Verzeichnis
„KonsolenanwendungErsetzen“
Testen Sie, ob die Prozedur „ersetze“ das gewünschte Verhalten zeigt.
Testen Sie insbesondere auch extreme Testfälle (z. B.: das zu ersetzende
Zeichen kommt auch in der neuen Zeichenkette vor).
Fertigen Sie ein Testprotokoll an (vgl. nächste Folie).
39
Testprotokoll
{vorher:
meinText: 'Hans im Glück'
ersetzeText: 'Hans'
durchText: 'Peter'
}
ersetze(ersetzeText, durchText, meinText);
{nachher:
meinText: 'Peter im Glück'
}
40
Schnittstelle eines Unterprogramms
Für die Benutzung eines Unterprogramms muss man nur die Signatur und
das Verhalten des Unterprogramms kennen. Diese legen die sog.
Schnittstelle des Unterprogramms fest.
ersetze
alt: string
neu: string
var text: string
Signatur:
procedure Ersetze (
string;
string;
string)
Verhaltensbeschreibung:
Die Prozedur „Ersetze“ ersetzt innerhalb der Zeichenkette „text“ die Zeichenkette „alt“ durch
die neue Zeichenkette „neu“.
41
Teil 3
Vordefinierte Komponenten
42
Die Programmoberfläche
soll benutzerfreundlicher
gestaltet werden:
/1/ Bei der Auswahl des
Schlüssels sollen die zur
Verfügung stehenden
Möglichkeiten
voreingestellt sein.
/2/ Für die Eingabe des
Quelltextes soll ein
mehrzeiliges Eingabefeld
zur Verfügung stehen.
/3/ Texte sollen auch
geladen und gespeichert
werden können.
Zielsetzung
43
Sichere Eingabe des Schlüssels
TSpinEdit-Komponente
Sichere Eingabe des Schlüssels
44
SpEdSchluessel: TSpinEdit
Attribute
MinValue = 0
MaxValue = 25
Value
=3
...
Ereignisse
OnChange: SpEdSchluesselChange
...
Methoden
...
procedure TForm1.SpEdSchluesselChange(Sender: TObject);
begin
schluessel := SpEdSchluessel.Value;
end;
45
Mehrzeilige Eingabe von Texten
TMemo-Komponente
Mehrzeilige Eingabe von Texten
46
MQuelltext: TMemo
Attribute
Text
= 'DASHANDELN... '
ScrollBars = ssVertical
Lines
= ...
...
Ereignisse
...
Methoden
...
Hinweis:
Der Gesamttext wird mit dem (nicht
vom Objektinspektor angezeigten)
Attribut „Text“ verwaltet. Dieser
Gesamttext enthält dann aber auch
Zeichen zur Darstellung von
Zeilenumbrüchen.
procedure
TForm1.BVerschluesselnClick
(Sender: TObject);
begin
// Daten aktualisieren
quelltext := MQuelltext.Text;
// Daten verarbeiten
verschluesseln;
// Benutzungsoberfläche aktualis.
MGeheimtext.Text := geheimtext;
end;
Mehrzeiliges Eingabefeld
47
Text
TMemo
TStrings
Attribute
Attribute
: string
Strings[Index: Integer]: string
ScrollBars : TScrollStyle
Count: Integer
Lines
...
: TStrings
Ereignisse
...
Ereignisse
...
Methoden
...
Methoden
...
Erweiterung:
Mit einem zusätzlichen Button soll der
Inhalt des TMemo-Feldes gelöscht
werden.
procedure Add(S: string)
procedure Clear
procedure Delete(Index: Integer)
procedure Insert(Index: Integer; S: string)
procedure LoadFromFile(FileName: string)
procedure SaveToFile(FileName: string)
...
Mehrzeilige Eingabe von Texten
48
Text
MQuelltext: TMemo
TStrings
Attribute
Attribute
= 'Hallo Caesar[LF][CR]wie ...'
Strings[Index: Integer]: string
ScrollBars = ssVertical
Count: Integer
Lines.Strings =
0: 'Hallo Caesar'
1: 'wie geht’s?'
...
2
...
Lines.Count =
Ereignisse
Methoden
...
procedure Add(S: string)
MQuelltext.Lines.Clear;
procedure Clear
MQuelltext.Lines.Add('Hallo ..');
procedure Delete(Index: Integer)
MQuelltext.Lines.Add('wie ...');
procedure Insert(Index: Integer; S: string)
zeilen := MQuelltext.Lines.Count;
procedure LoadFromFile(FileName: string)
MQuelltext.Lines.Delete(0);
procedure SaveToFile(FileName: string)
MQuelltext.Lines.Insert(0, '..');
...
Laden und Speichern
49
TOpenDialog-Komponente
TOpenDialog
Attribute
FileName: TFileName;
...
Ereignisse
...
Methoden
function Execute: Boolean;
...
Laden und speichern
50
TOpenDialog
BLadenQ:
TButton
MQuelltext:
TMemo
Attribute
FileName: TFileName;
FileName dient zur Speicherung des Dateinamens
OpenDialog1:
TOpenDialog
....
Ereignisse
...
Methoden
function Execute: Boolean;
...
Execute öffnet das Dialogfeld zur Auswahl von Dateien
und gibt True zurück, wenn der Benutzer eine Datei
ausgewählt und auf OK geklickt hat. Klickt der Benutzer
auf Abbrechen, liefert Execute False zurück.
procedure TForm1.BLadenQClick(Sender: TObject);
begin
if OpenDialog1.Execute then
MQuelltext.Lines.LoadFromFile(OpenDialog1.Filename);
end;
51
Aufgabe
Kopieren Sie das bisher entwickelte Delphi-Projekt in einen neuen Ordner.
Verändern Sie das Programm anschließend so, dass es die angesprochenen
benutzerfreundlichen Eigenschaften hat. Gehen Sie dabei schrittweise vor:
Schritt 1: Sichere Eingabe des Schlüssels mit einer „Spin-Edit-Komponente“
Schritt 2: Mehrzeiliges Textfeld mit Hilfe einer „Memo-Komponente“
Schritt 3: Laden und Speichern von Texten mit „Dialog-Komponenten“
52
Aufgabe
Analysieren Sie die Veränderungen, die man vornehmen muss. Ändert sich
das (erweiterte) Datenmodell? Was muss im Gesamtprogramm geändert
werden?
53
Trennung: Datenmodell – GUI
...
private
{ Private-Deklarationen }
quelltext: string;
geheimtext: string;
schluessel: integer;
procedure verschluesseln;
procedure entschluesseln;
procedure vorbereiten;
...
procedure TForm1.verschluesseln;
var i, n: integer;
begin
geheimtext := '';
for i := 1 to length(quelltext) do
begin
n := ord(quelltext[i]);
n := n + Schluessel;
if n > 90 then n := n-26;
geheimtext := geheimtext + chr(n);
end
end;
Keine Veränderung des
Datenmodells erforderlich
Veränderung und Erweiterung der
Benutzungsoberfläche
54
Trennung: Datenmodell – GUI
Ein grundlegendes Prinzip beim Entwurf von Software-Systemen besteht
heute in der klaren Trennung zwischen Benutzungsoberfläche und
Fachkonzept / Datenmodell.
(H. Balzert: Lehrbuch Grundlagen der Informatik. S. 123)
Die Benutzungsoberfläche ist für die Kontrolle (control) und Ansicht (view)
der Eingabe-/Ausgabe-Daten zuständig, während das Datenmodell (model)
zur internen Speicherung der Daten dient. Eine Trennung dieser Bereiche
erleichtert es, Programme zu warten und verändern.
55
Teil 4
Datenstruktur „Reihung“
56
Die Kodierung soll mit
einer beliebigen
Chiffriertabelle erfolgen.
Der Benutzer hat die
Möglichkeit, eine
beliebige Chiffriertabelle
selbst einzugeben.
Zielsetzung
Beliebige Chiffriertabelle
57
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
K L Q D T I G A Y U O H B W R F S X E N M Z V J P C
Reihung von Zeichen
Quelltext:
Schlüssel: K L Q D T I ...
SALVECAESAR
Geheimtext:
EKHZTQKTEKX
Zeichenkette
Quelltext:
SALVECAESAR
Schlüssel: KLQDTIGAY...
Geheimtext:
EKHZTQKTEKX
Reihung von Zeichen
58
Mit Hilfe der Datenstruktur Reihung werden gleichartige Daten (die also
vom gleichen Typ sind) zu einer Einheit zusammengefasst.
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
K L Q D T I G A Y U O H B W R F S X E N M Z V J P C
codeA:
K
codeB:
L
codeC:
Q
codeD:
D
codeE:
T
codeF:
I
Ungünstig!
Element
Index
Reihung
kodierung: K
L
Q
D
T
I
...
...
...
C
1
2
3
4
5
6
...
...
...
26
Element
Index
Reihung
...
codeZ:
C
kodierung: K
L
Q
D
T
I
...
...
...
C
A
B
C
D
E
F
...
...
...
Z
59
Deklaration einer Reihung
Indexbereich
Elementtyp
type
tKodierung = array [1..26] of char;
...
kodierung: tKodierung;
kodierung: K
L
Q
D
T
I
...
...
...
C
1
2
3
4
5
6
...
...
...
26
Indexbereich
Elementtyp
type
tKodierung = array ['A'..'Z'] of char;
...
kodierung: tKodierung;
kodierung: K
L
Q
D
T
I
...
...
...
C
A
B
C
D
E
F
...
...
...
Z
60
Deklaration einer Reihung
Eine Reihung des hier vorgestellten Typs hat eine feste Anzahl von
Elementen. Der Indexbereich wird dabei über eine Aufzählung festgelegt.
type
tKodierung = array [1..26] of char;
type
tKodierung = array ['A'..'Z'] of char;
type
tBuchstabe = 'A'..'Z';
tKodierung = array [tBuchstabe] of char;
61
Zugriff auf Elemente
Auf die Datenelemente einer Reihung kann man über den Index zugreifen.
type
tKodierung = array [1..26] of char;
var
kodierung: tKodierung;
kodierung[1] := '*';
kodierung[2] := '*';
kodierung[3] := '*';
...
var i: integer;
for i := 1 to 26 do
kodierung[i] := '*';
type
tKodierung = array ['A'..'Z'] of char;
var
kodierung: tKodierung;
kodierung['A'] := '*';
kodierung['B'] := '*';
kodierung['C'] := '*';
...
var c: char;
for c := 'A' to 'Z' do
kodierung[c] := '*';
62
Zugriff auf Elemente
Der Index kann innerhalb einer Anweisung auch zur Laufzeit berechnet
werden.
type
tKodierung = array ['A'..'Z'] of char;
var
kodierung: tKodierung;
kodierung['A']
kodierung['B']
kodierung['C']
...
kodierung['Z']
:= 'B';
:= 'C';
:= 'D';
:= 'A';
var i: integer;
for i := 65 to 89 do
kodierung[chr(i)] := chr(i+1);
kodierung[chr(90)] := chr(65);
Aufgabe
63
Passen Sie den Algorithmus an
die neue Datenstruktur an.
quelltext: string;
geheimtext: string;
schluessel: integer;
bisher
verschluesseln
geheimtext := ''
FÜR i VON 1 BIS length(quelltext)
c := quelltext[i]
n := ord(c)
n := n + schluessel
n > 90
ja
nein
n := n - 26
d := chr(n)
geheimtext := geheimtext + d
type tKodierung =
array ['A'..'Z'] of char;
quelltext: string;
geheimtext: string;
kodierung: tKodierung;
64
Aufgabe
Ändern Sie das Chiffriersystem so ab, dass man beliebige Kodierungen
vornehmen kann. Benutzen Sie das Programmgerüst aus dem Verzeichnis
„Chiffrierung1 – Programmgeruest“.
65
Teil 5
Fehlersuche und Fehlervermeidung
Ein merkwürdiges Ergebnis
66
Das Programm liefert ein (auf den ersten Blick) merkwürdiges Ergebnis,
wenn der Quelltext nicht vorbereitet ist.
Obelix
N0
67
Debugger
Wir untersuchen das Laufzeitverhalten des Programms mit dem DelphiDebugger.
Einzelne Anweisung
Aktuell bearbeitete
Anweisung
Gesamte Routine
68
Bereichsüberschreitung
Beim Verschlüsseln von Zeichenketten kann es zu Bereichsüberschreitungen
beim Zugriff auf die Elemente der Reihung „kodierung“ kommen.
type
tKodierung = array ['A'..'Z'] of char;
...
kodierung: tKodierung;
...
procedure TForm1.verschluesseln;
var
i: integer; quelle, geheim: char;
begin
geheimtext := '';
for i := 1 to length(quelltext) do
begin
quelle := quelltext[i];
geheim := kodierung[quelle];
geheimtext := geheimtext + geheim;
end;
end;
{quelltext: 'Obelix'}
i := 2;
quelle := quelltext[2];
{quelle: 'b'}
geheim := kodierung[quelle];
{geheim: ?}
Bereichsüberschreitung
69
Bereichsüberprüfung
Mit der Direktive $R kann die Generierung von Bereichsprüfungscode aktiviert und deaktiviert
werden. Im Status {$R+} werden alle Ausdrücke, die Arrays und Strings indizieren,
dahingehend überprüft, ob sie sich innerhalb der festgelegten Grenzen befinden. Der gleichen
Prüfung werden alle Zuweisungen an skalare Variablen und Teilbereichsvariablen unterzogen.
Das Fehlschlagen der Bereichsprüfung führt zu einer ERangeError-Exception (bzw. zum
Programmabbruch, wenn die Exception-Behandlung nicht aktiviert ist).
Die Aktivierung der Bereichsprüfung vergrößert und verlangsamt ein Programm. Setzen Sie den
Schalter {$R+} deshalb nur zum Testen mit dem Debugger ein.
{$R+}
procedure TForm1.verschluesseln;
var
i: integer; quelle, geheim: char;
begin
geheimtext := '';
for i := 1 to length(quelltext) do
begin
quelle := quelltext[i];
geheim := kodierung[quelle];
geheimtext := geheimtext + geheim;
end;
end;
Delphi-Hilfe
70
Fehlerbehandlung
<Tools> <Debugger-Optionen> <Sprach-Exceptions> Bei Delphi-Exceptions stoppen []
Vorbereitung
{$R+}
procedure TForm1.verschluesseln;
var
i: integer; quelle, geheim: char;
begin
geheimtext := '';
for i := 1 to length(quelltext) do
begin
quelle := quelltext[i];
try
geheim := kodierung[quelle];
except
geheim := ' ';
showmessage('Quelltext nicht vorbereitet!');
end;
geheimtext := geheimtext + geheim;
end;
end;
71
Teil 5
Zusammenfassung
Erweiterte Datenmodelle
72
Ein Datenmodell sollte nicht nur die Daten der Miniwelt, sondern auch die
hiermit durchzuführenden Operationen erfassen.
Schlüssel
Schlüssel
3
3
VDOYHFDHVDU
Quelltext
Verschlüsselung
quelltext: string;
geheimtext: string;
schluessel: integer;
procedure verschluesseln;
procedure entschluesseln;
Geheimtext
SALVECAESAR
Quelltext
Entschlüsselung
Daten
Operationen auf den Daten
73
Trennung: Datenmodell – GUI
Der Vorteil der Trennung zwischen Datenmodell und GUI zeigt sich, wenn
ein Programm verändert werden soll.
GUI verändern
Datenmodell bleibt unverändert
quelltext: string;
geheimtext: string;
schluessel: integer;
procedure verschluesseln;
procedure entschluesseln;
74
Schnittstelle eines Unterprogramms
Für die Benutzung eines Unterprogramms muss man nur die Signatur und
das Verhalten des Unterprogramms kennen. Diese legen die sog.
Schnittstelle des Unterprogramms fest.
ersetze
alt: string
neu: string
var text: string
Signatur:
procedure Ersetze (
string;
string;
string)
Verhaltensbeschreibung:
Die Prozedur „Ersetze“ ersetzt innerhalb der Zeichenkette „text“ die Zeichenkette „alt“ durch
die neue Zeichenkette „neu“.
75
Schnittstelle einer Komponente
Für die Benutzung einer Komponente benötigt man eine genaue
Beschreibung der Attribute, Methoden und Ereignisse. Eine Übersicht über
die zur Verfügung stehende Attribute, Methoden und Ereignisse erhält man
mittels eines Klassendiagramms.
SpEdSchluessel: TSpinEdit
Attribute
MinValue = 0
MaxValue = 25
Value
=3
...
Ereignisse
OnChange: SpEdSchluesselChange
...
Methoden
...
76
Teil 6
Vertiefende Übungen
77
Aufgabe
Entwickeln Sie ein System, mit dem man eine Zahlenfolge erzeugen und
auswerten kann.
/1/ Der Benutzer kann eine Folge von 20 Zufallszahlen aus einem
vorgegeben Bereich erzeugen lassen.
/2/ Auf Wunsch wird die kleinste und größte vorkommende Zahl der Folge
bestimmt.
/3/ Auf Wunsch wird die
Position der kleinsten und
größten vorkommenden Zahl
der Folge bestimmt und
angezeigt.
78
Aufgabe
Hilfen:
Ergänzen Sie zunächst das
Datenmodell.
Entwickeln Sie anschließend
Algorithmen für die benutzten
Operationen.
Implementieren Sie abschließend
das entwickelte System.
type tZahlenreihe =
array
zahlenreihe: tZahlenreihe;
min, max: integer;
minPos, maxPos: integer;
erzeugen;
auswerten;
79
Aufgabe
Entwickeln Sie ein System, mit dem man Würfelserien erzeugen und
statistisch auswerten kann.
/1/ Der Benutzer kann eine Würfelserien mit einer vorgegeben Länge
erzeugen.
/2/ Der Benutzer kann die Würfelserie auswerten lassen. Für jede
Augenzahl wird die absolute (relative) Häufigkeit innerhalb der Würfelserie
bestimmt.
/3/ Die Würfelserie wird angezeigt.
/4/Die Häufigkeiten werden angezeigt.
80
Aufgabe
Hilfen:
Ergänzen Sie zunächst das
Datenmodell.
Entwickeln Sie anschließend
Algorithmen für die benutzten
Operationen.
Implementieren Sie abschließend
das entwickelte System.
type tAugen = 1..6;
type tWuerfelserie =
array
type tHaeufigkeiten =
array
wuerfelserie:
haeufigkeiten:
erzeugen;
auswerten;
81
Aufgabe
Informieren Sie sich, wie das Verschlüsselungsverfahren nach Vigenère
funktioniert. Ändern Sie das Chiffriersystem nach Caesar entsprechend ab.
82
Aufgabe
Bei einer beliebig eingegeben Chiffriertabelle kann es leicht vorkommen,
dass ein Geheimtextbuchstabe mehrfach benutzt wird. Das Chiffriersystem
soll so erweitert werden, dass dieser Fall erkannt / verhindert wird.
B kommt mehrfach vor!
83
Aufgabe
Bei einer beliebig gewählten Chiffrierung fällt es schwer, sich den Schlüssel
(d. h. die Chiffriertabelle) zu merken. Man könnte sich die Sache etwas
erleichtern, wenn man wie folgt verfährt: Man wählt ein (langes)
Schlüsselwort, z. B. SCHOKOLADENOSTERHASE. Dann streicht man alle
mehrfach vorkommenden Buchstaben: SCHOKLADENTR. Diese Buchstaben
bilden den Anfang des Geheimtextalphabets. Abschließend füllt man ab der
letzten Stelle mit den noch zur Verfügung stehenden Buchstaben des
Alphabets auf.
Klartextalphabet
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
S C H O K L A D E N T R U V W X Y Z B F G I J M P Q
Geheimtextalphabet
Entwickeln Sie ein Programm, bei dem man nur das Schlüsselwort eingeben
muss. Die Erzeugung der zugehörigen Chiffriertabelle wird vom Programm
selbst übernommen.
84
Aufgabe
Das Chiffriersystem soll um einen Statistikbaustein erweitert werden. Mit
Hilfe dieses Bausteins kann man eine Häufigkeitsanalyse durchführen.
85
Aufgabe
Entwickeln Sie ein System, mit dem eine Art Stilanalyse bei Texten
vorgenommen werden kann. Das System soll die durchschnittliche Länge
eines Satzes und die durchschnittliche Anzahl der Nebensätze eines
eingegebenen Textes bestimmen.
86
Aufgabe
Entwickeln Sie ein System, mit dem man eine Lotto-Ziehung simulieren
kann.
87
Literaturhinweise
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.
Noll, Mayr, Paulus, Selinger:
http://informatikag.bildung-rp.de/html/delphi_teil_1.html
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://www.bildung.hessen.de/abereich/inform/skii/material/delphi/index.htm
88
Literaturhinweise
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/
...
Herunterladen