Prinzipfrage: Ausstieg aus einer Rekusiven Procedure

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
CSHW89
Beiträge: 489
Registriert: 14.12.2008 12:22

Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure

Beitrag von CSHW89 »

ts-soft hat geschrieben: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?
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?
Kann sein, dass du den Code kopiert hast, bevor ich ihn editiert hab. Hab erst "Global SaveStack" vergessen. Und es ging ja darum, dass man direkt mehrere Rekursionstiefen zurückspringt, nicht bei einer Tiefe von 10000, 10000 zurückspringen muss.
NicTheQuick hat geschrieben:Nein, PB macht das nicht, wenn man einfach so mit einem Goto aus einer Procedure heraus springt.
Doch, wenn man selber den Stack repariert.
lg Kevin
Bild Bild Bild
http://www.jasik.de - Windows Hilfe Seite
padawan hat geschrieben:Ich liebe diese von hinten über die Brust ins Auge Lösungen
Benutzeravatar
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

Beitrag von NicTheQuick »

Naja, angenommen du bist schon in der 10. Rekursion. Dann springst du mit einem ProcedureReturn einfach nur zurück in die 9. Rekursion und musst so weiter machen, bis du in der 0. Rekursion bist und dann kannst du ins Hauptprogramm zurück. Bei jedem ProcedureReturn wird der Stackpointer dann wieder entsprechend zurück gesetzt. Mit einem Goto hast du den Vorteil, dass du direkt raus springen kannst ohne den umständlichen Weg zu gehen immer nur Schritt für Schritt zu gehen. Wichtig ist dann aber den Stackpointer auch wieder richtig zurück zu setzen. Im Beispiel von CSHW89 geht das mit einem kleinen ASM-Befehl anstatt 10 mal den Pointer Stück für Stück zurück zu setzen.
Benutzeravatar
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:

Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure

Beitrag von alen »

Hallo Community,

ich wusste nicht das ich mit meiner Frage so eine Welle schlage. Scheint aber wirklich ein prinzipielles Problem zu sein. Der Anwendungsfall sollte dazu dienen, rekursiv die Registry zu durchsuchen bis man aus einen definierten Wert trifft und daraufhin dann die ganze Rekursion komplett, unverzüglich und sauber verlässt. Eine Exception auslösen käme der Sache schon nahe. Nur das gibt es im PB nicht.

Anwendung auf den Punkt gebracht:
- Suche den kompletten Pfad
- Wenn Wert gefunden Suche sofort beenden
- Fund zurückliefern

Das ist doch eigentlich ein gängiger Anwendungsfall. Sollte in der Praxis öfter vorkommen.
Wie würdet Ihr sowas lösen ?

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)
Benutzeravatar
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

Beitrag von ts-soft »

NicTheQuick hat geschrieben:Naja, angenommen du bist schon in der 10. Rekursion. Dann springst du mit einem ProcedureReturn einfach nur zurück in die 9. Rekursion
Nach dem, was ich im engl. Forum von Fred gelesen habe, ist dem eben nicht so! PB bereinigt das autom.,
oder ich habe da was durcheinander gebracht, was ja auch mal vorkommen könnte :wink:
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.
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure

Beitrag von STARGÅTE »

Hier der Weg über Rekursion:

Code: Alles auswählen

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
	#DirectoryDelimiter$ = "\"
CompilerElse
	#DirectoryDelimiter$ = "/"
CompilerEndIf

Procedure.s FindFile(Path.s, FileName.s)
	Protected Result.s
	Protected Directory.i = ExamineDirectory(#PB_Any, Path.s, "*")
	If Directory
		Debug Path
		If Right(Path, 1) <> #DirectoryDelimiter$
			Path + #DirectoryDelimiter$
		EndIf
		While NextDirectoryEntry(Directory)
			Select DirectoryEntryType(Directory)
				Case #PB_DirectoryEntry_Directory
					If DirectoryEntryName(Directory) = "." Or DirectoryEntryName(Directory) = ".."
						Continue
					EndIf
					Result = FindFile(Path+DirectoryEntryName(Directory), FileName)
					If Result
						Break
					EndIf
				Case #PB_DirectoryEntry_File
					If DirectoryEntryName(Directory) = FileName
						Result = Path+DirectoryEntryName(Directory)
						Break
					EndIf
			EndSelect
		Wend
		FinishDirectory(Directory)
	EndIf
	ProcedureReturn Result
EndProcedure

Debug FindFile("C:", "Beispiel.txt")
C:\Dokumente und Einstellungen\***\Beispiel.txt
Wie schon von NicTheQuick angedeutet, kann man auch diese Rekursion in eine Iteration umwandeln.
Dazu muss müssen dann nur die Directory-Nummern in einer Liste abgespeichert werden, sodass sie ordnungsgemäß wieder freigegeben werden können.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
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

Beitrag von ts-soft »

@STARGÅTE

Wie ich NickTheQuick verstanden habe, würde Dein Code einen Stacküberlauf verzapfen, was aber nach
meinem Verständnis nicht der Fall ist.

Was ist denn nun richtig?
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.
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7039
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure

Beitrag von STARGÅTE »

Stacküberlauf gibt es nur, wenn die Rekursionstiefe zu groß wird (ca 80.000 bei einem Parameter).
Da hier die Tiefe gleich der Ordnertiefe entspricht, wird es also nie passieren.
Wie oft eine Prozedur sich selbst in einer Tiefe aufruft ist egal, da es ja immer stück für stück geht und erst die erste komplett in die Tiefe geht, wieder zurück und dann die nächste.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Re: Prinzipfrage: Ausstieg aus einer Rekusiven Procedure

Beitrag von remi_meier »

STARGÅTE hat geschrieben:Stacküberlauf gibt es nur, wenn die Rekursionstiefe zu groß wird (ca 80.000 bei einem Parameter).
Da hier die Tiefe gleich der Ordnertiefe entspricht, wird es also nie passieren.
Wie oft eine Prozedur sich selbst in einer Tiefe aufruft ist egal, da es ja immer stück für stück geht und erst die erste komplett in die Tiefe geht, wieder zurück und dann die nächste.
Hah, du bist nur noch nie auf einen rekursiven Symlink gestossen :wink:

@ts-soft:
Wenn du nur ProcedureReturn verwendest, räumt PB natürlich selbst
auf und du solltest nie einen korrupten Stack vorfinden. Das Problem
sind nur Gotos innerhalb einer Prozedur, die nach aussen springen
(gleiches Problem bei OnErrorGoto).
Wenn man Stack-Überläufe produziert, hat man meist falsch programmiert.
Benutzeravatar
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

Beitrag von ts-soft »

@remi_meier

Danke, genauso hatte ich das bisher auch immer verstanden und Goto, sowie OnErrorGoto
sind für mich genauso wichtig, wie die FTP :mrgreen:
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.
Bild
Antworten