Rekursives Programmieren

Hallo!

Wir haben im Informatik-Unterricht (Stufe 12)gerade rekursives Programmieren - in der Schule mit Delphi 6 hat’s geklappt aber die Hausaufgabe mit Delphi 3 funktioniert nicht - gibt es da irgendwelche nennenswerten Unterschiede?
Was wir amchen sollen, sit im Prinzip ganz simpel: je ein Programm, dass Fibonacci-Zahlen und Fakultät einer eingegebenen Zahl (Edit-Fenster) ausrechnet (bzw. die x. Fibonacci-Zahl) und über ein Label ausgibt.
Mein Fakultät-Programm sieht so aus, aber es gibt immer die Fehlermeldung Stack-Überlauf, oder als Ergebnis kommt die eingegebene Zahl raus. Kann mir vielleicht irgendjemand weiterhelfen?

procedure TForm1.Button2Click(Sender: TObject);
begin
close;
end;

procedure TForm1.Button1Click(Sender: TObject);
function rechne (x:Integer):Integer;
begin
if x=1 then result := 1
else result := rechne (x*(x-1));

end;
begin
x := strtoint (Edit1.Text);
rechne(x);
Label1.Caption := 'Die Fakultät der eingegebenen Zahl ist '+ inttostr(x);
end;
end.

Danke!!!

Hallo!

Wir haben im Informatik-Unterricht (Stufe 12)gerade rekursives
Programmieren - in der Schule mit Delphi 6 hat’s geklappt aber
die Hausaufgabe mit Delphi 3 funktioniert nicht - gibt es da
irgendwelche nennenswerten Unterschiede?

Nein.

Mein Fakultät-Programm sieht so aus, aber es gibt immer die
Fehlermeldung Stack-Überlauf, oder als Ergebnis kommt die
eingegebene Zahl raus. Kann mir vielleicht irgendjemand
weiterhelfen?

Ja.

Du ruft eine Funktion (rechne) auf, diese gibt als Ergebnis die Fakultät des Arguments (x) zurück. Soweit ok.

function rechne (x:Integer):Integer;
begin
 if x=1 then 
 result := 1
 else 
 result := rechne (x\*(x-1));
end;

Der Fehler liegt im Rest des Programms:
Du ermittelst das Argument (x) und rufst damit die Funktion „rechne“ auf. Allerdings verwirfst du das Ergebnis dieser Funktion, d.h. weder speicherst du es in einer Variable noch gibst du es aus. Anschließend gibst du das Argument (x) aus.
Deine Prozedur müßte also so aussehen:

var
 y: Integer;
begin
 x := StrToInt(Edit1.Text);
 y := Rechne(x);
 Label1.Caption := 
 'Die Fakultät der eingegebenen Zahl ist '
 + IntToStr(x);
end;

oder kürzer:

begin
 Label1.Caption := 
 'Die Fakultät der eingegebenen Zahl ist '
 + IntToStr(StrToInt(Edit1.Text));
end;

Noch ein paar Tipps zum Schluß:

Gib deinen Funktionen/Prozeduren immer möglichst genaue, sinnvolle Namen. Für die Funktion „rechne“ wäre ein Name wie „Fakultaet“ besser gewesen.

Kommentiere deinen Quellcode. Schreibe in Kommentaren dazu, was welche Prozedur/Funktion macht und wie (z.B. „berechnet die Fakutät n! rekursiv nach der Formel (i=1…n) f[i+1]=i*f[i]“ oder so ähnlich). Das ist in diesem konkreten Fall zwar lächerlich, aber es dient ja der Ausbildung („aus didaktischen Gründen“, wie einer meiner Lehrer zu sagen pflegte).

Verwende Groß/Kleinschreibung. „StrToInt“ ließt sich besser als strtoint.

Beste Grüße,
Jochen

PS: Der Stack-Overflow wird verursacht, wenn du ein zu großes x eingibst.

Fehler in der Rekursion
Hallo,

zusätzlich zum Fehler, der im anderen Posting erwähnt ist, ist die Funktion „rechne“ auch falsch:

function rechne (x:Integer):Integer;
begin
 if x=1 then result := 1
 else result := **rechne (x\*(x-1))**;
end;

Probier’ mal aus, was beim Aufruf rechne(3) passiert:

rechne (3)
ruft auf:
rechne (3\*(3-1)) [also rechne(6)]
ruft auf:
rechne (6\*(6-1)) [das ist rechne(30)]
etc ...
**\*puff\***

Schau Dir die rekursive Definition der Fakultät nochmal an:
Du hast n! := (n*(n-1))! implementiert, es heißt aber n! := n * (n-1)!

Gruß, Ralf

hab ich doch übersehen!

Das erklärt auch den Überlauf bei niedrigen Zahlen…

Viele Grüße,
Jochen

Danke für eure Hilfe! Ich hab’s heute im Unterricht dann auch rausgefunden, nachdem mein Lehrer sicher 10 Minuten draufgestarrt hat und auch nicht auf den Fehler kam. *gg*

iterative Funtkionen
Schon wieder ein neues Problem. „Macht mal“, sprach der Lehrer, weg war er, und das Netzwerk stürzte ab. *gg* Und Schüler dürfen nciht an die Server.
Diesmal: eine iterative Funktion für die Hofstadter-Zahl. Eignetlich soll das Programm auch noch einen Grapf zeichnen, aber ich kriege es nicht mal soweit, dass es das richtige Ergebnis ausspuckt…

function hof(n:Integer):Integer;
var i:integer;
begin
feld[1] := 1;
feld[2] := 1;
if n>2 then
for i:=1 to n do
begin
feld[n]:= feld[n-feld[n-1]]+feld[n-feld[n-2]];
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
x := StrToInt(Edit1.Text);
feld[x] := hof(x);
Label1.Caption := 'Das Ergebnis ist ’ + IntToStr(feld[x]);
end;

end.