Seite 5 von 8

Verfasst: 14.12.2008 15:41
von AND51
Captn. Jinguji hat geschrieben:
PMV hat geschrieben:
Captn. Jinguji hat geschrieben:Öhmmm rekursives Abklappern von Filesystemen z.B. ?
Das macht man aber mit einer Prozedur und keiner Schleife.
Wer hat denn unbedingt von Schleifen gesprochen ?
Egal, ob Schleifen oder Rekursionen, ein Goto zum Verlassen des ganzen Konstrukts ist unnötig.
Bei Konstrukten wie diesem hier kann man sich das Goto ganz einfach durch setzen richtiger Abbruchbedingungen sparen (Pseudocode):

Code: Alles auswählen

Procedure scan()
   While scannen
      If noch_mehr_zu_scannen
         scan()
      Else
         Goto raus_hier
      EndIf
   Wend
EndProcedure

scan()
raus_hier:
Jinguji un DrFalo, natürlich kennt man hier seine Rekursionstiefe nicht, das stimmt. Da habe ich anfangs nicht dran gedacht. Aber es ist auch gar nicht nötig, sie zu kennen und auch einen Rekursionstiefenmesser braucht man nicht. Man kann auch 2 verschiedenen Wegen die Rekursion verlassen: Entweder, wenn es nichts mehr zu scannen gibt, oder indem man Werte wie -1 zurückgibt, die signalisieren, dass die Rekursion abgebrochen werden soll.

In Fällen wie diesem ein Goto zum verlassen einer Rekursion einzusetzen, halte ich wie andere hier auch, für "schlechten" Programmierstil. Was machst du denn, wenn diese Prozedur die Größe in Bytes eines Verzeichnisses inklusive Unterverzeichnisse zurückgeben soll? Zählst du dann die Größe in einer globalen Variable mit und springst da bei Bedarf mit Goto raus? LOL. Das macht man "anständigerweise" mit geschützen Variablen (Protected) und einem ProcedureReturn am Ende der Prozedur. Das zeigt auch, dass man die Rekursion 100%ig verstanden hat.

Verfasst: 14.12.2008 16:43
von PMV
Das Beispiel von ANDI zeigt, wie man es ausdrücklich nicht benutzen darf,
weil der Stack dannach nicht aufgeräumt wird ... das gibt nur Probleme
und ist richtig "dirty" :wink:

Wie PB mit Schleifen arbeitet wissen wir nicht, dafür müsste man sich den
ASM-Output anschauen ... aber wer macht das schon, nur um ein mal in
seinem leben sinnvoll Goto verwenden zu können? :shock:

@cxAlex ... wenn dir jemand sagt: "Spring von dir Brücke!" ... würdest du
es tun? ... deine Antwort ist vermutlich dann folgende: "Ja natürlich,
wenn er eine Waffe hat und droht mich zu erschießen" ... in diese
Situation kommen genau wie viele? :? ... Stichwort: Klugscheißen /:->
Wir haben schon verstanden, dass es in ganz bestimmten Situation, wenn
X praktisch unmögliche Ereignisse Eintreten, dann und nur dann ist Goto
mal wirklich praktisch. Muss man deswegen drauf beharren? <)
Einem Anfänger bringe ich garnicht erst Goto bei ... Und wenn er's selber
lernt, selbst schuld :mrgreen:

MFG PMV

Verfasst: 14.12.2008 17:00
von rolaf
Hai,

nachdem ihr euch nun mächtig über einen Satz meines Postings ausgequatscht habt, hier ein Statement von mir. ;)
DrFalo hat geschrieben:Sicher, nur solls danach nicht am Schleifenende weitergehen, das heißt hier müßte noch ein Umweg rein und genau da ist mir dann ein GOTO lieber.
Dieser Satz war die eigendliche Aussage und die stimmt und ist für mich der seltene Grund GOTO zu verwenden. Amen.

DrFalo hat geschrieben:Gibt auch Fälle in denen ich die Schleifenanzahl zum Zeitpunkt des Verlassens nicht kenne. usw.
Dieser Satz war unüberlegt und scheisse, vergesst ihn. :lol:

DrFalo hat geschrieben:Wie gesagt sehr selten, wenn mir alles andere zu umständlich erscheint.
Jo, das stimmt wieder, wie die Faust aufs Auge.


Hoffe alle Klarheiten sind damit beseitigt und ihr könnt wieder zum Tagesgeschäft übergehen. <)

Grüß Gott

Verfasst: 14.12.2008 17:04
von Froggerprogger
In GW-Basic durfte man GOTO nicht verwenden, um aus Schleifen herauszuspringen (also nichteinmal bei FOR-Schleifen).
In PB scheint man aus FOR- und WHILE-Schleifen herausspringen zu dürfen. Aber man darf nicht aus Select...Case-Konstrukten mit GOTO herausspringen!! Und schon gar nicht aus Prozeduren!!
Siehe Beispiel:

Code: Alles auswählen

Procedure.l GetESP()
  !MOV EAX, ESP
  ProcedureReturn
EndProcedure

Debug "Sprung aus for-Schleife"
Debug "Stackpointer vorher: " + Str(GetESP())
For inner1 = 0 To 100
  For inner2 = 0 To 100
    If inner1 + inner2 = 1000
      Goto weiter1
    EndIf
  Next
Next
weiter1:
Debug "Stackpointer nachher: " + Str(GetESP())
Debug "=> OK"

Debug "Sprung aus while-Schleife"
Debug "Stackpointer vorher: " + Str(GetESP())
i=0
While i<100
  If i=5
    Goto weiter2:
  EndIf
  i+1
Wend
weiter2:
Debug "Stackpointer nachher: " + Str(GetESP())
Debug "=> OK"

Debug "Sprung aus Select..Case"
Debug "Stackpointer vorher: " + Str(GetESP())
a = 2
Select a
  Case 1 : Debug "Error"
  Case 2 : Goto weiter3
  Case 3 : Debug "Error"
  Default : Debug "Error"
EndSelect
weiter3:
Debug "Stackpointer nachher: " + Str(GetESP())
Debug "=> NICHT OK!!"


Debug "Sprung aus Procedure"
Procedure Bla(a.l, b.l, c.l)
  Goto weiter4
EndProcedure
Debug "Stackpointer vorher: " + Str(GetESP())
Debug Bla(1, 2, 3)
weiter4:
Debug "Stackpointer nachher: " + Str(GetESP())
Debug "=> NICHT OK!!"
Bei jedem Goto-Aufruf wird der Stackpointer nicht mehr richtig zurückgesetzt, so dass es bei häufigem Aufruf das Programm mit einem Stackoverflow abstürzen wird.

Verfasst: 14.12.2008 17:12
von PMV
Und wenn sich das in PB5.0 ändert geht das Geschrei los :lol: /:->
... hab schon vorfreude :mrgreen: ... ganz besonders bei *DrFalo 8)

* nicht böse gemeint, nur bischen fieß :D

MFG PMV

Verfasst: 14.12.2008 17:12
von rolaf
Na also, ich springe in diesen Ausnahmefällen nur aus for-Schleifen und dies innerhalb der jeweiligen Prozedur - somit alles im grünen Bereich. :allright:
PMV hat geschrieben:Und wenn sich das in PB5.0 ändert geht das Geschrei los :lol: /:->
... hab schon vorfreude :mrgreen: ... ganz besonders bei *DrFalo 8)

* nicht böse gemeint, nur bischen fieß :D

MFG PMV
Da bin ich vermutlich schon unter der Erde und knabbere die Mohrüben von unten ab. :lol:

Verfasst: 14.12.2008 17:14
von Kaeru Gaman
Froggerprogger hat geschrieben:Bei jedem Goto-Aufruf wird der Stackpointer nicht mehr richtig zurückgesetzt, so dass es bei häufigem Aufruf das Programm mit einem Stackoverflow abstürzen wird.
das ist das kleinere problem.
schon bei einer einzigen solchen fehlerhaften Verwendung wird die nächste Benutzung des Stacks falsche werte zurückliefern.
das ist dann die Situation, wo ein einfaches ProcedureReturn oder EndProcedure einen IMA rückmeldet.

Verfasst: 14.12.2008 17:21
von milan1612
Also ich hatte erst letztens einen Fall in dem ich ohne ein klug gesetzes Goto
den Code so umstrukurieren hätte müssen dass er wesentlich unleserlicher
geworden wäre. Goto also pauschal zu verteufeln halte ich für absoluten Quatsch,
nur darf man es halt nicht unüberlegt einsetzen...

Verfasst: 14.12.2008 17:22
von AND51
PMV hat geschrieben:Das Beispiel von ANDI zeigt, wie man es ausdrücklich nicht benutzen darf,
weil der Stack dannach nicht aufgeräumt wird ... das gibt nur Probleme
und ist richtig "dirty"
Richtig. Und selbst die PB-Hilfe rät von Goto ab. Scheinbar hat aber niemand bisher die Hilfe dazu aufgeschlagen?
Goto hat geschrieben:Dieser Befehl wird benutzt, um die Programmausführung direkt zu einer Sprungmarke zu verlegen. Seien Sie vorsichtig mit dieser Funktion, da falsche Benutzung zu einem Programmabsturz führen kann...

Hinweis: Um eine Schleife sicher zu verlassen, sollten Sie immer Break anstelle von Goto verwenden.

Verfasst: 14.12.2008 17:29
von Franky
Ach jungs, Goto is doch Pillekack, der Profi optimiert seinen Quelltext mit JMP 8)


Und an die Klugscheißer: Das war ein Gag