|
PÜ 9: Übungen zu Nichtabweisenden Schleifen
- Repeat ... Until ... -
1. Übertragung Struktogramm in Quelltext:
Als algorithmische Kontrollstrukturen kennen wir von den
vorangegangenen Seiten Sequenzen, Alternativen
und nichtabweisende Zyklen. Diese
lassen sich in Problemlösungsalgorithmen in nahezu beliebiger
Weise und Tiefe miteinander kombinieren bzw. ineinander
schachteln. Die nachfolgenden Struktogramme sind gemäß Beispiel
a) 1:1 in pascalgerechte Notationen zu übersetzen, wobei "a"
für eine allgemeine Anweisung und "b" für
eine allgemeine Bedingung steht.
2. Schreibtischtest" von zyklischen Strukturen:
Zweck: |
- Erkennen der Variablenbelegungen für verschiedene
Eingabewerte,
- Nachweis, ob eine Abbruchbedingung bei bestimmten
Eingabewerten erreicht wird oder nicht.
|
2.1. Beispielaufgabe und Lösung:
a) |
Zu testen ist folgender
nichtabweisender Zyklus für die Eingabe edit1.text :=
‘4’ !
x :=
StrToInt(edit1.text);
n := 0; y := 1;
REPEAT
n := n+1;
y := y*2
UNTIL n = x;
edit2.text := IntToStr(y);
|
b) |
Welche mathematische Funktion wird von
der Struktur realisiert ? |
c) |
Was würde geschehen, wenn man
edit1.text mit ‘-1’ belegt ? - Schlussfolgerung ? |
Lösung + Hinweise:
zu a) |
Der Schreibtischtest erfolgt am besten
in Tabellenform. Hier werden alle im Algorithmus
relevanten Variablen eingetragen und hinsichtlich der
Änderung ihrer Werte beim (gedanklichen) Ablauf des
Programmes untersucht. Sind Schleifen im Spiel, so
muss nach jedem fiktiven Durchlauf das Erreichen der
Abbruchbedingung überprüft werden.
Variablen: |
x |
n |
y |
Vorgabe: |
4 |
0 |
1 |
Durchläufe: |
1. |
4 |
1 |
2 |
2. |
4 |
2 |
4 |
3. |
4 |
3 |
8 |
4. |
4 |
4 |
16 |
Abbruch,
da n=x |
|
zu b) |
Hierbei ist die Abhängigkeit der
Ausgabevariable(n) von der/den Eingabevariable(n) zu
untersuchen, im Beispiel also y = f(x). Erkennt man
die Abhängigkeit nicht sofort, führe man
weitere "Schreibtischtests" mit geänderten
Eingabevariablen durch!
Im Beispiel beträgt y
= 2x
|
zu c) |
Da n bereits im
ersten Schleifendurchlauf mit dem Wert 1 belegt ist
und in jedem weiteren Durchlauf um 1 erhöht wird,
entstünde bei Eingabe von -1 für x eine sog.
"Endlosschleife", weil die Abbruchbedingung n=x
theoretisch niemals erreicht wird.
In der Praxis endet das Ganze entweder mit einer
Fehlermeldung (Bereichsüberschreitung / Stacküberlauf
etc.) oder mit einem tobsüchtigen Nutzer, der im
schlimmsten Fall irgendwann die Reset-Taste betätigt
;-)
Fazit:
- Insbesondere zyklische Strukturen sollten vor
dem Programmstart gedanklich daraufhin getestet
werden, welche Eingabewerte zu Endlosschleifen o. a.
Fehlern führen könnten.
- Mit Hilfe einer zu programmierenden
Eingabesicherung "zwinge" man den Nutzer
dazu, nur "erlaubte" Werte einzugeben.
- Da 1. und 2. nie 100% Sicherheit bieten,
speichere man jedes in Entwicklung befindliche
Programm vor dem Compilieren bzw. Starten.
|
2.2. Aufgabe zum Schreibtischtest
a) |
Das nachstehende Programmstück ist per
"Schreibtischtest" für den Eingabewert
‘5’ zu untersuchen !
x :=
StrToInt(edit1.text);
f := 1;
REPEAT
f := f * x;
x := x-1
UNTIL x<1;
edit2.text := IntToStr(f);
|
b) |
Welche mathematischen Funktion wird
hierbei realisiert ? |
c) |
Welcher Wertebereich darf nicht zur
Eingabe verwendet werden und weshalb? |
3. Programmieraufgabe "Eigenwilliger Kredit":
a) |
Ein nicht gewinnsüchtiger Vater mit
nennenswerten Ersparnissen trifft mit seinem
finanzbedürftigen Sohn eine eigenwillige
"Kreditvereinbarung":
Der Sohn erhält einen Kredit in gewünschter
Höhe. Es werden keine Zinsen erhoben. Nach einem Jahr
soll der Sohn die Hälfte der Kreditsumme zurückzahlen.
Nach jedem weiteren Jahr beträgt die Rückzahlung
jeweils die Hälfte der Rückzahlung des Vorjahres bis
nach n Jahren der Kredit getilgt ist.
Man
entwerfe einen Algorithmus (Struktogramm) und schreibe
ein Programm, welches für beliebige Kreditsummen bei
Rundung auf ganze Pfennige die Anzahl der Jahre
ermittelt, die bis zur vollständigen Tilgung benötigt
werden sowie die jährlich zu zahlende Rate auflistet.
Benötigte Variablen: jahre : ganzzahlig; kredit,
rate, tilgung : reelle Zahlen.
Nebenstehende Abbildung zeigt einen Vorschlag zur
Oberflächengestaltung, wobei die Ausgabe über drei
nebeneinander stehende TListBox-Komponenten erfolgt.
Lösungshinweise:
- Synchronisation
von TListBox-Komponenten
- Ausgabe im
Währungsformat
|
b) |
Schon eher etwas für Fortgeschrittene:
Eine günstige Stunde ausnutzend, erreicht der Sohn
folgende nicht ganz unwesentliche Modifizierung des
Kreditvertrages:
Die Abzahlungen können in umgekehrter
Reihenfolge stattfinden, d. h. im ersten Jahr
erfolgt die Überweisung der kleinsten Rate. Dies
steigert sich bis zum letzten Abzahlungsjahr, in dem die
Hälfte der ursprünglichen Kreditsumme fällig wird.
Die Problemlösung von a) ist in Struktogramm- und
Programmform entsprechend zu modifizieren!
|
Lösungshinweise:
Synchronisation
von TListBox-Komponenten
Falls nebeneinander angeordnete TListBox-Komponenten zusammen
gehörende Wertereihen enthalten, erwartet der Nutzer eine gewisse
Synchronität der Anzeige. Wird im obigen Beispiel etwa in der
ListBox1 auf das Jahr Nr. 11 geklickt, so sollen auch in
ListBox2 und ListBox3 die zugehörigen Einträge markiert
erscheinen.
Die nachfolgende Prozedur passt den jeweiligen ItemIndex
(markierten Eintrag) von ListBox2 und ListBox3 an den in ListBox1
markierten Eintrag an.
procedure
TForm1.ListBox1Click(Sender: TObject);
begin
listbox2.itemindex:=listbox1.itemindex;
listbox3.itemindex:=listbox1.itemindex;
end;
Ausgabe im Währungsformat
Der Delphi-Hilfe ist unter dem Stichwort
"FloatToStrF" u. a. folgendes zu entnehmen:
Funktion FloatToStrF(Value:
Extended; Format: TFloatFormat; Precision, Digits: Integer):
String;
Beschreibung
FloatToStrF konvertiert einen durch Value
gegebenen Fließpunktwert in seine String-Darstellung.
Der Parameter Format bestimmt das Format des resultierenden
Strings.
Der Parameter Precision bestimmt die Genauigkeit des übergebenen
Wertes. Er sollte für Werte vom Typ Single auf 7 oder weniger
gesetzt sein, für Werte vom Typ Double auf 15 oder weniger und
bei Extended-Werten auf höchstens 18.
Die Bedeutung des Parameters Digits hängt vom gewählten Format
ab.
ffCurrency Währungsformat.
Der Wert wird in einen String konvertiert, der eine Währungsbetrag
angibt. Die Umwandlung wird durch die globalen Variablen
CurrencyString, CurrencyFormat, NegCurrFormat, ThousandSeparator
und DecimalSeparator gesteuert, die alle mit den Werten
initialisiert werden, die in der Windows-Systemsteuerung,
Abschnitt Ländereinstellungen angegeben wurden. Die Anzahl
Ziffern nach dem Dezimalpunkt wird durch den Parameter Digits
bestimmt und muß zwischen 0 und 18 liegen.
Im "Kreditprogramm" könnte das Währungsformat wie
folgt in die Ausgabeschleife implementiert werden: Listbox2.Items.Add (FloatToStrF (rate, ffCurrency, 8, 2));
|
|
|