![]() |
Funktion deklarieren oder nicht?
Hallo.
Es geht um eine Variable, die für eine Grafik wichtig ist und durch eine Funktion deklariert wird. Es scheint, als ob die Funktion nicht ausgeführt werden würde. In der Grafik erscheint dann nur eine vollfarbige Fläche, obwohl man mindestens eine Struktur erkennen müsste
Code:
function zaehler(za:integer; x,y,x2,a,b:real):integer;
begin x2:=x*x-y*y+a; y:=2*x*y+b; x:=x2; If (za<100) and (sqrt(x*x+y*y)<2) then za:=zaehler(za+1,x,y,x2,a,b) else za:=1; end; . . . za:=0; //Initialisierung zaehler(za,x,y,x2,a,b); //Aufruf if za>=100 then paintbox1.canvas.Pixels[s+50,z+50]:=clBlack; case za of 0..9:paintbox1.canvas.Pixels[s+50,z+50]:=clRed; 10..19:paintbox1.canvas.Pixels[s+50,z+50]:=clGreen; . . . |
AW: Funktion deklarieren oder nicht?
Wenn Du einen Parameter innerhalb der Funktion/Prozedur/Methode veränderst, musst Du ihn mit 'var' deklarieren, also
Delphi-Quellcode:
function zaehler(var za:integer; var x,y,x2,a,b:real):integer;
begin x2:=x*x-y*y+a; y:=2*x*y+b; x:=x2; If (za<100) and (sqrt(x*x+y*y)<2) then za:=zaehler(za+1,x,y,x2,a,b) else za:=1; end; |
AW: Funktion deklarieren oder nicht?
Delphi-Quellcode:
So besser?
function zaehler(var za:integer; var x,y,x2,a,b:real):integer;
[edit] Einen Tick zu langsam. Möglichweise kann man die Fließkommaparameter aber auch by Value übergeben (also ohne das "var"), so genau hab ich das jetzt nicht durchdrungen. [/edit] |
AW: Funktion deklarieren oder nicht?
Man könnte za auch im Result der Function übergeben.
Ansonsten wäre eine Procedure sinnvoller. Nachtrag: Ohne Result := za geht der rekursive Aufruf sowieso nicht. |
AW: Funktion deklarieren oder nicht?
Stimmt, ist mir gar nicht aufgefallen :oops:
|
AW: Funktion deklarieren oder nicht?
Eine Rekursion mit
Delphi-Quellcode:
ginge schon, aber dann müsste man die Logik anpassen, damit Diese dann "eigentlich" als Iteration arbeitet, womit man den rekursiven Aufruf dann aber auch gleich entsorgen könnte.
procedure zaehler(var za:integer; x,y,x2,a,b:real);
|
AW: Funktion deklarieren oder nicht?
Hallo nochmal.
Mit der Variante bekomme ich die Fehlermeldungen: [Fehler] Unit1.pas(36): ';', ')' oder '=' erwartet, aber 'VAR' gefunden [Fehler] Unit1.pas(42): Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen
Code:
Was ist mit
function zaehler(var za:integer var x,y,x2,a,b:real):integer; //36
begin x2:=x*x-y*y+a; y:=2*x*y+b; x:=x2; If (za<100) and (sqrt(x*x+y*y)<2) then za:=zaehler(za+1,x,y,x2,a,b) //42 else za:=1; end; result:=za; gemeint? Die Variablen ändern sich doch durch die Funktion, oder nicht? Der rek. Aufruf ist schon Absicht. MfG Ergosquare |
AW: Funktion deklarieren oder nicht?
Delphi-Quellcode:
Gruß
function zaehler(var za:integer; var x,y,x2,a,b:real):integer; //36
K-H |
AW: Funktion deklarieren oder nicht?
Da fehlt ein Semikolon im Funktionskopf vor dem zweien "var". Und eine Funktion hat einen Rückgabewert, der wird in Deinem Code aber nirgends gesetzt, der Compiler müsste auch eine diesbezügliche Warnung ausgeben.
|
AW: Funktion deklarieren oder nicht?
Zitat:
Gruß K-H |
AW: Funktion deklarieren oder nicht?
Und wo soll das sein?
|
AW: Funktion deklarieren oder nicht?
Sorry, mein Fehler, das mit dem Semikolon hätte ich sehen können.
Das zweite Problem besteht weiterhin. Eine Warnung bekomme ich nicht. MfG Ergosquare |
AW: Funktion deklarieren oder nicht?
2 Möglichkeiten:
Delphi-Quellcode:
oder auch
function SomeFunction: integer;
begin Result := 42; (* Result *) end;
Delphi-Quellcode:
Auch nach 20-maligem Drübergucken habe ich in Deinem Code keine der beiden Möglichkeiten entdecken können. Du musst also vor dem rekursiven Aufruf der Funktion einen Wert zuweisen, sonst steht da irgendetwas drin, aber nichts Definiertes. Steppe doch einmal durch und schau Dir den Wert von za nach dem Aufruf an. Nach meinem Dafürhalten müsste da ziemlicher Nonsens drinstehen.
function SomeFunction: integer;
begin SomeFunction := 42; (* Funktionsname *) end; |
AW: Funktion deklarieren oder nicht?
Zitat:
Gruß K-H |
AW: Funktion deklarieren oder nicht?
Achso, Missverständnis meinerseits, ich dachte, Du hättest meine Tomaten gemeint :lol:
|
AW: Funktion deklarieren oder nicht?
So, die Funktion hat jetzt eine Rückgabewert.
za scheint trotzdem durch die Funktion nicht verändert zu werden. MfG Ergosquare |
AW: Funktion deklarieren oder nicht?
Um mal zusammenzufassen:
- Rekursion ist in der Regel langsamer als Iteration - Parameter, lokale Variablen und Rückgabewerte nicht durcheinander werfen So stelle ich mir das vor:
Delphi-Quellcode:
Pixels ist so ziemlich die langsamste Möglichkeit eine Grafik auszugeben.
function zaehler(x, y, a, b: Real): Integer;
var x2: Real; begin Result := 0; while (Result <= 100) and (sqrt((x * x) + (y * y)) < 2) do begin x2 := (x * x) - (y * y) + a; y := (2 * x * y) + b; x := x2; Inc(Result); end; end; var c: TColor; za := zaehler(x, y, a, b); case za of 0..9: c := clRed; 10..19: c := clGreen; {...} else c := clBlack; end; paintbox1.canvas.Pixels[s + 50, z + 50] := c; Besser du verwendest eine Bitmap und greifst mit Scanline darauf zu. Die Bitmap dann komplett oder nach jeder Zeile zeichnen. Alternativ gleich mit einer TImage-Komponente arbeiten (Image1.Picture.Bitmap). |
AW: Funktion deklarieren oder nicht?
Ich hatte noch einen entscheidenden Fehler:
Code:
Sonst wird za nach der Funktion nicht verändert.
If (za<100) and (sqrt(x*x+y*y)<2)
then za:=zaehler(za+1,x,y,x2,a,b)+1 //+1 hat gefehlt else za:=1; Dennoch bleibt es leider bei der Einfarbigkeit. PS: Ich würde trotzdem gerne bei Rekursion bleiben. MfG Ergosquare |
AW: Funktion deklarieren oder nicht?
Zitat:
- Nein. Hm. Also eigentlich irgendwie doch aber nicht so einfach. ;-) Eine sehr schöne Erklärung ist ![]() |
AW: Funktion deklarieren oder nicht?
Den Ausdruck
Delphi-Quellcode:
kann man übrigens zu
(sqrt((x * x) + (y * y)) < 2)
Delphi-Quellcode:
vereinfachen.
((x * x) + (y * y) < 4)
Man kommt darauf wenn man den Ausdruck auf beiden Seiten des Kleinerzeichens quadriert. Die Quadratwurzel
Delphi-Quellcode:
wird dann aufgehoben und das spart recht viel Zeit.
sqrt()
|
AW: Funktion deklarieren oder nicht?
@Rekursion: In diesem Fall hier (Mandelbrot Fraktal) ist Geschwindigkeit nicht ganz unwichtig, da der gesamte Prozess sonst echt lahm werden kann. Und die Iteration eines Punktes geht - wie der Name der Operation schon so freundlich suggeriert - völlig klaglos und performat iterativ. Es drängt sich in meinem Hirn sogar geradezu als der "natürliche" Weg auf. (Und ja, TCanvas.Pixels[] bremst hier mindestens genau so heftig, wenn nicht sogar noch signifikanter.) (Davon ab ist 100 als Grenz-Iterationstiefe schon ziemlich fein. Bei den meisten Zooms, die das Fraktal als ganzes noch zeigen, sind Tiefen um 30-50 bei voller HD Auflösung noch sehr gut. Je näher man ran geht, desto feiner muss man allerdings werden um alle theoretisch noch sichtbaren Details zu bekommen. Ich würde die Iterationstiefe daher entweder frei wählbar (favorit), oder vom Zoom abhängig machen.)
|
AW: Funktion deklarieren oder nicht?
Um es kurz zu machen: Bloß weil etwas rekursiv definiert ist, muss es ja nicht rekursiv umgesetzt werden.
|
AW: Funktion deklarieren oder nicht?
Hier wegen der Vollständigkeit eine funktionierende rekursive Variante:
Delphi-Quellcode:
procedure zaehler(var za: Integer; x, y, a, b: Real);
var x2, y2: Real; begin if za = 100 then Exit; x2 := x * x; y2 := y * y; if (x2 + y2) >= 4 then Exit; Inc(za); zaehler(za, x2 - y2 + a, (2 * x * y) + b, a, b); end; |
AW: Funktion deklarieren oder nicht?
Und hier eine iterative:
Delphi-Quellcode:
function zaehler(x, y, a, b: Real): Integer;
begin result := 0; repeat x := x*x + y*y + a; y := 2*x*y + b; Inc(result); until (result>100) or ((x*x+y*y)>=4); end; |
AW: Funktion deklarieren oder nicht?
@Medium
Deine Berechnung ist aber Falsch: - für die Berechnung des neuen x' muss (y * y) subtrahiert werden - für die Berechnung des neuen y' muss das alte x in der Berechnung benutzt werden
Delphi-Quellcode:
function zaehler(x, y, a, b: Real): Integer;
var x2, y2: Real; begin Result := 0; repeat x2 := x * x; y2 := y * y; if (x2 + y2) >= 4 then Break; y := (2 * x * y) + b; x := x2 - y2 + a; Inc(Result); until (result > 100); end; |
AW: Funktion deklarieren oder nicht?
Ups, stimmt. Ich hatte nur den vorhandenen Code im Editor zusamengeschnippelt und nicht viel geprüft/getestet. Mir ging es eher darum zu zeigen, dass man einiges an Ballast gegenüber der Rekursion los werden kann, und sich auch die Lesbarkeit erhöht (ich finde Rekursion immer sehr aufwändig nachzuvollziehen im Kopf).
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz