Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
- alen
- Beiträge: 107
- Registriert: 09.04.2007 17:38
- Computerausstattung: Main Hardware: AMD Ryzen 5 1600 - 6 Core / Gigabyte B450 Aorus Pro / Sapphire RX580 8GB
PB 5.61 and earlier @ Manjaro Linux XFCE x64/ Fedora Linux Cinnamon x64 / Windows 10 x64 on various Hardware Platforms - Wohnort: Duisburg
- Kontaktdaten:
Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Hallo Community,
ich bin mal wieder in Sachen PB unterwegs und stosse auf ein Grundsatzproblem.
Es wird eine Procedure abgearbeitet die sich selbst wieder aufruft. Nach dem Beispiel als wenn man durch Verzeichnissse oder in der Registry den kompletten Pfad durchsucht. So weit, so gut. Klappt auch.
Was ich brauche ist aus dieser Rekursiven Procedure beim Vorkommen einer Bedingung frühzeitig ausszuteigen mit einem Rückggabewert bsp. der String der dort gefunden wurde. Sprich sobald die Bedingung eintrifft, mit dem Rückgabewert im Gepäck aus der Procedure raus.
Welches ist die beste Praxis für sowas ? Komme auf keine praktikable Lösung.
Grüße
Alen
ich bin mal wieder in Sachen PB unterwegs und stosse auf ein Grundsatzproblem.
Es wird eine Procedure abgearbeitet die sich selbst wieder aufruft. Nach dem Beispiel als wenn man durch Verzeichnissse oder in der Registry den kompletten Pfad durchsucht. So weit, so gut. Klappt auch.
Was ich brauche ist aus dieser Rekursiven Procedure beim Vorkommen einer Bedingung frühzeitig ausszuteigen mit einem Rückggabewert bsp. der String der dort gefunden wurde. Sprich sobald die Bedingung eintrifft, mit dem Rückgabewert im Gepäck aus der Procedure raus.
Welches ist die beste Praxis für sowas ? Komme auf keine praktikable Lösung.
Grüße
Alen
---
Main Hardware: AMD Ryzen 5 1600 - 6 Core / Asus B350M-A / Nvidia GTX650
PB 5.61 and earlier @ Manjaro Linux XFCE x64/ Fedora Linux Cinnamon x64 / Windows 10 x64
on various Hardware Platforms (Notebook and Desktop)
Main Hardware: AMD Ryzen 5 1600 - 6 Core / Asus B350M-A / Nvidia GTX650
PB 5.61 and earlier @ Manjaro Linux XFCE x64/ Fedora Linux Cinnamon x64 / Windows 10 x64
on various Hardware Platforms (Notebook and Desktop)
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Suchst du vielleicht ProcedureReturn?
Oder bei Schleifen Break?
Oder bei Schleifen Break?
- NicTheQuick
- Ein Admin
- Beiträge: 8838
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Ich würde das so in der Art machen:
Ich hoffe der Code ist selbsterklärend.
Code: Alles auswählen
Procedure recursiveFunction(parameter1, parameter2, *cancelRecursion.Integer = 0)
Protected cancel.i = #False
If (*cancelRecursion = 0)
*cancelRecursion = @cancel
EndIf
;mach was
result = recursiveFunction(wert1, wert2, *cancelRecursion)
If (*cancelRecursion\i)
;brich die Rekursion ab
ProcedureReturn
EndIf
;mach was
result = recursiveFunction(wert1, wert2, *cancelRecursion)
If (*cancelRecursion\i)
;brich die Rekursion ab
ProcedureReturn
EndIf
;mach was
;usw.
If irgendwas_schlimmes_ist_passiert
*cancelRecursion\i = #True
ProcedureReturn
EndIf
;alles ok, gib Ergebnis aus
ProcedureReturn ergebnis
EndProcedure
Debug recursiveFunction(123, 456)Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Das heißt aber das bei einer Rekursionstiefe von beispielsweise 10.000 dannRSBasic hat geschrieben:Suchst du vielleicht ProcedureReturn?
Oder bei Schleifen Break?
auch 10.000 male zurückgesprungen wird.
Ich vermute mal das alen mit aussteigen meinte, die ganze Rekursion komplett
und unverzüglich zu verlassen und nicht tausende male zurück zu springen.
Für PB ist mir dafür aber auch kein sauberer Weg bekannt. Mit Goto rausspringen
räumt den Stack nicht auf. Exceptions gibt es nicht.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Code: Alles auswählen
EnableExplicit
Global newvalue
Procedure Zaehle(value)
value + 1
If value < 1000
Zaehle(value)
Else
newvalue = value
ProcedureReturn
EndIf
EndProcedure
Zaehle(1)
Debug newvaluePureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

- NicTheQuick
- Ein Admin
- Beiträge: 8838
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Weiterhin sei noch gesagt, dass man jede Rekursion auch in eine Iteration verwandeln kann. Dazu baut man sich einfach seinen eigenen Stack, falls man ihn überhaupt braucht. Das kommt eben immer auf das zu Grunde liegend Problem an. Aber funktionieren tut es alle mal und man bekommt außerdem keinen Stack-Overflow, der bei tiefen Rekursionen mal schnell erreicht sein kann. Interessanterweise stürzt bei PB einfach das Programm samt Debugger ab, wenn man einen Stack-Overflow provoziert. Ich denke das sollte der Debugger eigentlich auch abfangen.
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Etwas unsauber, aber mit Speicherung des Stacks, und Goto gehts so:
Mit einem etwas modifiziertem Code aus dem CodeArchiv benutze ich das immer für Try/Catch-Blöcke, und funktioniert wunderbar.
lg Kevin
Code: Alles auswählen
Global __SaveStack
Macro SaveStack()
CompilerIf #PB_Compiler_Processor =#PB_Processor_x86
!MOV dword[v___SaveStack],ESP
CompilerElse
CompilerIf #PB_Compiler_Processor =#PB_Processor_x64
!MOV qword[v___SaveStack],RSP
CompilerElse
CompilerError "Processor not supported by try/catch handler"
CompilerEndIf
CompilerEndIf
EndMacro
Macro GotoBack()
CompilerIf #PB_Compiler_Processor =#PB_Processor_x86
!MOV ESP,dword[v___SaveStack]
CompilerElse
CompilerIf #PB_Compiler_Processor =#PB_Processor_x64
!MOV RSP,qword[v___SaveStack]
CompilerElse
CompilerError "Processor not supported by try/catch handler"
CompilerEndIf
CompilerEndIf
Goto back
EndMacro
Procedure Rec(n)
Debug "Start "+Str(n)
If (n = 0)
GotoBack()
EndIf
Rec(n-1)
Debug "Hier kommste niemals hin"
EndProcedure
Procedure test()
Protected str.s
str = "Fertig!"
SaveStack()
Rec(5)
back:
Debug str
EndProcedure
test()
lg Kevin

http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Abgesehen davon, das dieser Code bei mir einen ASM error wirft, warum wollt Ihr immer den Stack
bereinigen, das macht PB doch bei einem ProcedureReturn automatisch, sollte also vollkommen
unnötig sein?
bereinigen, das macht PB doch bei einem ProcedureReturn automatisch, sollte also vollkommen
unnötig sein?
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

- NicTheQuick
- Ein Admin
- Beiträge: 8838
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Nein, PB macht das nicht, wenn man einfach so mit einem Goto aus einer Procedure heraus springt.
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure
Naja, aber warum sollte man mit einem Goto aus der Procedure springen, das ist es ja was ich nicht verstehe,NicTheQuick hat geschrieben:Nein, PB macht das nicht, wenn man einfach so mit einem Goto aus einer Procedure heraus springt.
ist doch vollkommen unnötig oder übersehe ich hier etwas?
IMHO kann man rekursive Funktionen problemlos mit einem ProcedureReturn verlassen, so habe ich das gelesen.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.


