Fakultät rekursiv


HarryXVI

Erfahrenes Mitglied
#1
Ich habe mir für eine rekursive Fakultäts-Rechnung folgendes überlegt.

Code:
x, result: Real;
...
function TRechenoperationen.Fakultaet(x: Real): Real;
var n: Real;
begin
if x >= 2 the begin
   n := x-1;
   result := Fakultaet(n) * x;
  end
else result := 1;
end;
Nur hat result am Ende keinen Wert. Wie kann ich das ändern?
 
#2
Du hast ganz oben in deinem Code "result" deklariert. Das ist aber unnötig (und verursacht wohl auch den Fehler), weil "result" der Rückgabewert deiner Funktion ist. Du brauchst es nicht extra deklarieren. Ansonsten seh ich jetzt keinen Fehler, hab den Code allerdings nur im Kopf getestet ;)
 

Navy

Freiwillige Serverwehr
#3
Es ist im übrigen ungünstig den Rückgabewert in einer Funktion mehr als einmal zu definieren, auch wenn bei einer Anweisungsüberdeckung dieses nur einmal passiert. Sauberer und schöner ist es, wenn man eine (lokale!) Variable definiert und dann ganz zum Schluss den Rückgabewert setzt.

Code:
function TRechenoperationen.Fakultaet(x: integer): integer;
var TempResult: integer;
begin
  if x >= 2 then 
  begin
    TempResult := Fakultaet(x-1) * x;
  end
  else
    TempResult := 1;
  result := TempResult;
end;
Die globalen Variablen brauchst Du nicht. Darüber hinaus ist die Fakultät < 0 nicht möglich.
 
Zuletzt bearbeitet:

Navy

Freiwillige Serverwehr
#6
Das Ergebnis 0 kann bei meiner Lösung nicht entstehen. Das Fehler liegt also bei Dir. Hast Du Dich vielleicht irgendwo verschrieben?
 

squeaker

Erfahrenes Mitglied
#7
Es ist im übrigen ungünstig den Rückgabewert in einer Funktion mehr als einmal zu definieren, auch wenn bei einer Anweisungsüberdeckung dieses nur einmal passiert. Sauberer und schöner ist es, wenn man eine (lokale!) Variable definiert und dann ganz zum Schluss den Rückgabewert setzt.
Frage - warum ist das ungünstig? Schliesslich legt Delphi ja gerade eine spezielle lokale Variable an um das Resultat dann zu übergeben (die immer den Namen Result hat).

Beispiel:

Code:
function doSomething : Integer;
begin
   Result:=ERROR_CODE; //mit Fehlerhaft initialisieren
   //defensives Programmieren, Preconditions pruefen
   if cond1 = true then Exit;
   if cond2 = true then Exit;
   //Preconditions erfuellt
   ...
   Result:=...  //Erfolgreich berechnet
end;
wichtig ist doch blos, dass Result einen definierten Wert hat, bevor die Funktion verlassen wird (wie auch immer sie verlassen wird).
 

HarryXVI

Erfahrenes Mitglied
#9
Code:
function TRechenoperationen.Fakultaet(x: Integer): Integer;
var i: Integer;
    TempResult: Integer;
begin
if x <= 0 then TempResult := 0 else TempResult := 1;
for i := 2 to x do begin
  TempResult := TempResult * i;   //eröhhen + und mit vorherigem multiplizieren
  result := TempResult;
  end;
end;
Diese Lösung habe ich in meinem Schulbuch gefunden^^