HSG |
|
Im Mathematik-Lehrbuch der 6.Klasse (Lambacher-Schweizer 6, Klett-Verlag, 73102) findet man folgende Beschreibung:
Alle übrig gebliebenen Zahlen sind die Primzahlen. Bei den Zahlen bis 100 kann man schon nach dem Streichen aller Vielfachen von 7 aufhören.
Schreibe ein Delphi-Programm, das nach obigem Algorithmus Primzahlen sucht.
// es werden die Vielfachen von a getrichen v := 2; // v gibt die 'Vielfachheit' an while v*a <= 100 do begin zahl[v*a] := 0; v := v+1; end;
i := p+1; while zahl[i] = 0 do i := i + 1;
Was ist aber, wenn schon alle Zahlen gestrichen sind? Dann läuft der Zeiger über die vereinbarte Feldgrenze hinweg.
i := p+1; while (i<=100) and (zahl[i] = 0) do i := i + 1;Obige Lösung führt zu einem Abbruch, wenn i > 100 geworden ist. Dann sollte man aber nicht zahl[i] auswerten, da diese Stelle nicht mehr im Array, im Feld ist. In Delphi werden je nach Einstellung logische Ausdrücke von links nach rechts ausgewertet und die Auswertung abgebrochen, wenn das Ergebnis schon feststeht (Kurzschlussverfahren).
for i := 2 to 100 do zahl[i] := i; p := 2; while p <= 100 do begin // es werden die Vielfachen von p getrichen v := 2; // v gibt die 'Vielfachheit' an while v*p <= 100 do begin zahl[v*p] := 0; v := v+1; end; // es wird die nächste nicht gestrichene Zahl gesucht i := p+1; while (i<=100) and (zahl[i] = 0) do i := i + 1; // die gefundene Zahl ist eine Primzahl oder zu groß p := i; end;
Es ist typisch, dass man bei der ersten Lösung in Teillösungen gedacht hat und nicht mehr einen klaren Blick für das Ganze hat. Hier sollte man kritisch über die Lösung sehen. Sind die Variablen sinnvoll benannt? Sind die Datentypen sinnvoll gewählt? Braucht man überhaupt alle Variablen oder sind Reste früherer Versuche im Programm-Code enthalten? Wurden Programmiersprachen-abhängige Besonderheiten benutzt?
Folgende Version ist an einigen Stellen verändert. Was bewirken die Änderungen? Ist das Programm 'besser'?
procedure TForm1.bRechneClick(Sender: TObject); const n = 200; var zahl : array[2..n] of boolean; p,i,v : integer; weiter : boolean; begin // Eingabe // Verarbeitung for i := 2 to n do zahl[i] := true; p := 2; while p <= n do begin // es werden die Vielfachen von p getrichen v := 2*p; // v ist das 'Vielfache' while v <= n do begin zahl[v] := false; v := v+p; end; // es wird die nächste nicht gestrichene Zahl gesucht p := p+1; if p <= n then weiter := true; // 'weiter' ist ein logischer Schalter while weiter do if (p<=n) and (zahl[p] = false) then p := p+1 else weiter := false; end;
Es folgt eine dritte Version:
for i := 2 to n do zahl[i] := true; for i := 2 to n do if zahl[i] = true then begin // es werden die Vielfachen von zahl[i] getrichen v := 2*i; while v <= n do begin zahl[v] := false; v := v+i; end; end;
Diese Version entspricht nicht mehr 1:1 der Beschreibung aus dem Mathematikbuch. Wie müsste hier die Beschreibung lauten?