mehr als ein Next in einer For-Next Schleife

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

 

Silvio

Betreff: mehr als ein Next in einer For-Next Schleife

BeitragMi, Jul 10, 2013 22:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Folgende Situation:
In einer For Schleife tritt der Fall, wo man direkt zum nächsten Durchgang springen will, daher setzt man ja logischerweise ein Next. Bei mehr als einem Next sagt blitz aber eben "Next without for" was ja theoretisch stimmt, da jedes For ein Next braucht. Wie kann ich nun von egal wo in der Schleife zum nächsten Durchgang springen?
 

CO2

ehemals "SirMO"

BeitragMi, Jul 10, 2013 22:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Mit Continue kannst du einen Schleifendurchlauf überspringen, mit Exit verlässt du die gesamte Schleife (Auch wenn das keine saubere Lösung ist, da es dem beliebten Goto gleicht...)
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti
 

PhillipK

BeitragMi, Jul 10, 2013 22:14
Antworten mit Zitat
Benutzer-Profile anzeigen
BB hat continue?
Hab grade die hilfe durchforstet, weil ich auch direkt dachte: "boh! continue!" aber habe leider nichts gefunden.

Exit finde ich an sich nicht schlimm. Wenn man eine schleife nunmal verlassen muss, ist es immerhin sauberer mit einem Exit statt mit einem GoTo, denn der code verrät exakt was passiert.
Bei sprungmarken muss man dann immer erst suchen Razz

Warum gleicht Exit deiner meinung nach GoTo? Weil man damit etwas "überspringen kann", indem man einfach zum ende der schleife "springT" ? Smile

Holzchopf

Meisterpacker

BeitragMi, Jul 10, 2013 22:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Da BlitzBasic Continue nicht kennt und Goto sehr sehr hässlich ist, möchte ich noch folgenden Vorschlag bringen:
Arbeite einfach mit Steuervariablen, die du zu Beginn jedes Schleifendurchgangs zurücksetzt. Die Variable kannst du dann beliebig setzen und entsprechend andere Blöcke nur je nach Wert der Variable ausführen.

MfG
Holzchopf
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm
 

Silvio

BeitragMi, Jul 10, 2013 22:21
Antworten mit Zitat
Benutzer-Profile anzeigen
habs jetzt mal mit goto gemacht. Ist das "nur" hässlich, aber sonst nicht tragisch oder gibts noch andere Gründe, das nicht zu benutzen? Habs bisher noch nie gebraucht und meide es
 

CO2

ehemals "SirMO"

BeitragMi, Jul 10, 2013 22:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh, entschuldigung, war noch bei BMax Embarassed

Goto ist eigentlich nur hässlich, aber wenn du es richtig anwendest, bekommst du auch damit brauchbare Programme hin.
Richtig benutzen heißt dabei: Sprechende Sprungmarken, jedes Goto 3 mal hervorgehoben und Goto so selten wie möglich benutzt... (Ich möchte keinesfalls raten Goto zu benutzen)
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Holzchopf

Meisterpacker

BeitragMi, Jul 10, 2013 22:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Nun... Es ist hässlich. Die Hässlichkeit skaliert allerdings mit dem Gebrauch von Goto. Bei zuviel Umhergespringe verlierst du den Überblick über den Programmablauf/-aufbau. Es ist auch nicht unbedingt im Sinne der Programmiersprache, wenn sie schon Blöcke/Funktionen anbietet, dass man dann wild von einer Zeile zu einer völlig fremden springen kann.

Eine schöne Struktur ist nach allgemeiner Auffassung dann erreicht, wenn man das Programm (die Problemstellung, die Summe aller Teilproblemchen plus der Leim dazwischen, weil das ganze ja bekanntlich mehr als die Summe aller Teile ist) in kleine eigenständige Routinen und Unterroutinen aufteilen kann, die Sequenziell und halt logisch gesteuert aufgerufen werden, ihre Arbeit erledigen und dann abgeschlossen sind.
Springt man mit Goto nun irgendwo aus einem Block von Anweisungen raus in oder vor einen anderen Block komplett unabhängiger Anweisungen, sprengt man diese Struktur. Der Code wird einfach von dort aus weiter ausgeführt, ohne, dass der Programmzähler wieder zurück zur Aufruf-Stelle springen würde. Unter Umständen muss man die Struktur sogar als Programmierer selbst sprengen, weil Goto nur innerhalb eines Scopes springen kann (Beispiel: alles in globalen Variablen ablegen und einzelne Goto-"Bereiche" benutzen, die unterschiedliche Dinge tun und die dann durch komplizierte Goto-Anhäufungen abrackern).

Zu viel Goto führt dann übrigens zu Spaghetticode.

MfG
Holzchopf
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm
 

bjh

BeitragMi, Jul 10, 2013 23:18
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzBasic: [AUSKLAPPEN]
For x=0 To 9
Print x
If Rand(0,1) x=x+1
Next

WaitKey
End

so kann man einen durchlauf beenden.

DAK

BeitragDo, Jul 11, 2013 8:25
Antworten mit Zitat
Benutzer-Profile anzeigen
@bhj:
Nein, kann man so nicht. So kann man einen Durchlauf überspringen, aber beenden geht so nicht.

Wie Holzchopf gesagt hat, sowas wäre richtig:

BlitzBasic: [AUSKLAPPEN]

For i=0 To 10
;Code
If (Not ueberspringe) Then
;Code
EndIf
Next


Um zu überspringen muss man die Variable ueberspringe auf True setzen.


Goto sorgt recht schnell für unkontrolliertes Chaos. Es gilt als sehr unsauber, wenn Programme nicht dem normalen Kontrollfluss folgen, also quasi allem, was du mit While, For, Repeat, If und Funktionen hinbekommst. Das macht auch Exit oder Continue teilproblematisch, weil mit denen auch der Kontrollfluss gebogen wird. Einer meiner Profs an der Uni hat sogar gemeint, dass ein Return hinter einem If in der Mitte einer Funktion eigentlich schon problematisch wäre, wenn es nicht die Funktion komplett beenden würde.
Gewinner der 6. und der 68. BlitzCodeCompo

Thunder

BeitragDo, Jul 11, 2013 11:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Okay, ich will jetzt gar nicht zu viel Aufruhr machen, aber ich finde, das ist eher ein Glaubenskrieg (wie iOS<->Android, Apple<->Nicht-Apple, Linux<->alles-andere) und hier wirst du fast immer hören, dass Goto sehr problematisch ist und es ist auch nicht sinnvoll, wenn man als Anfänger alles mit Goto beigebracht bekommt, weil man in den meisten Fällen es ersetzen kann (Schleife, Funktion, Continue, Exit/Break).

Aber als jemand, der sich viele Gedanken macht über Syntax und Maschinencodegenerierung (weil ich ja einen Compiler schreiben wollte, was mir bisher nicht gelang), muss ich sagen, dass mir die Goto-Variante logischer vorkommt.
BlitzBasic: [AUSKLAPPEN]
Const MAX = $2FFFFFF

time = MilliSecs()

; Variante mit GOTO

For i = 1 To MAX

x = x + 1

If x Mod 2 Then Goto loop_continue

y = x ^ 2 + y

.loop_continue
Next
time = MilliSecs()-time
Print time

x = 0
y = 0

time = MilliSecs()

; Variante ohne GOTO

For i = 1 To MAX
ueberspringe = 0

x = x + 1

If x Mod 2 Then ueberspringe = 1

If Not ueberspringe Then
y = x ^ 2 + y
EndIf

Next
time = MilliSecs()-time
Print time


WaitKey


Mit geeigneter Namensgebung erreicht man ebenso Übersichtlichkeit (Goto loop_continue heißt Continue). (Wobei mir ehrlich gesagt die untere Version, wenn ich sie mir etwas umfangreicher vorstelle, viel abschreckender vorkommt) Portiert man den Code in eine Sprache, die Continue kennt, kann man Goto loop_continue direkt durch Continue ersetzen ohne, dass weitere Modifikationen notwendig wären (eventuell Label entfernen).

Ich finde, in erster Linie müssen zusätzliche Variablen (machen Funktionen unübersichtlich) und Redundanzen (Wartbarkeit nimmt ab) vermieden werden, dann erst Goto. In Programmiersprachen die Schleifen, Funktionen, Exit/Break und Continue unterstützen, wird es natürlich immer weniger sinnvoll - es geht um den sinnvollen Einsatz von Goto - aber manchmal wünsche ich mir auch Goto für BlitzMax (im Strict Mode).

Nur, dass du von der anderen Seite auch Mal gehört hast. Wenn du es bisher noch nicht gebraucht hast, es meidest und fürs Erste es nur für Continue benutzt, ist das in meinen Augen ok.

Edit zu Kruemelators Vorschlag: Funktioniert nicht bei mehreren lokalen Variablen. Meine Schleife von oben lässt sich mit einer Funktion so nicht umsetzen:
BlitzBasic: [AUSKLAPPEN]
For i = 1 To MAX
f
Next

Function f()
x = x + 1 ; verwendet die falschen lokalen Variablen

If x Mod 2 Then Return

y = x ^ 2 + y

; sie ließen sich als Parameter übergeben, können aber nicht
; beide zurückgegeben werden.
End Function

Ist natürlich nur ein einfaches Beispiel, wo man noch tricksen kann, aber es geht um Lösungen, die immer eingesetzt werden können und das sind hauptsächlich die mit der Steuervariable und die mit Goto.

Edit: und hör nicht auf Jan_ Very Happy
  • Zuletzt bearbeitet von Thunder am Do, Jul 11, 2013 13:18, insgesamt 4-mal bearbeitet
 

Kruemelator

BeitragDo, Jul 11, 2013 12:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Geht alles viel einfacher:
BlitzBasic: [AUSKLAPPEN]
For i=0 To 10
blabalbla()
Next

Function blablabla()
Return; hier wird rausgesprungen
End Function

Jan_

Ehemaliger Admin

BeitragDo, Jul 11, 2013 12:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Man sollte nur Goto verwenden, anstatt for - next konstrukten!
between angels and insects

Holzchopf

Meisterpacker

BeitragDo, Jul 11, 2013 18:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Jan_ ich bitte dich, wir sind hier im Beginners-Bereich, hier glauben dir die Leute vielleicht noch was Rolling Eyes
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm

FireballFlame

BeitragFr, Jul 12, 2013 14:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich verstehe den Diskussionsgrund hier nicht wirklich.

Was Silvio braucht ist ein Continue, welches in BlitzBasic aber fehlt. Ein Goto wie in Thunders Beispiel übernimmt genau diese Aufgabe.
Nun kann man über Goto (im Allgemeinen) sagen was man will, aber die Continue-Anweisung kommt mir nicht sonderlich umstritten vor. Es gibt sie in BlitzMax, in VB.NET, in C♯, in Java und was weiß ich wo sonst noch. Und das Goto, um das es geht, täte exakt dasselbe. Es wäre auch überschaubarer, als den gesamten Rest der Schleife in einen If-Block einzuklammern oder ähnliche alternative Lösungen; zumal z.B. ein "If ... Then Continue" innerhalb eines zweiten Then/Else-Blocks dann gleich mehrere neue Ifs nach sich ziehen müsste etc. etc.

Wo ist also das Problem? Was rechfertigt, hier sarkastische Kommentare zu schreiben?
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

DAK

BeitragFr, Jul 12, 2013 14:32
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Problem ist nicht das eine Goto. Das Problem ist, dass man schnell anfängt, sich an Goto zu gewöhnen.

Du hast recht, das Continue kann durch ein Goto nachgeahmt werden. Das Gleiche kann man aber auch für While, For, Funktionsaufrufe und quasi alle anderen Flusskontrollelemente sagen. Und hier wird's dann haarig. Stell dir vor, da gibts jetzt nicht nur ein Goto als Continue, sondern auch noch eins für die Hauptschleife und jede andere Schleife und jede Funktion wird durch Gosubs ersetzt. Dann steig noch mal durch den Code.

Erfahrene Programmierer können unterscheiden, wo ein Goto angebracht ist, und wo nicht, und selbst die schreiben nicht nur schönen Code.
Anfänger können das oft nicht unterscheiden. Gibt man ihnen dann sowas wie Goto, und sie stoßen wieder auf ein Problem, dann suchen sie nicht weiter nach einer schöneren Lösung und klatschen einfach ein Goto rein, selbst wenn es eine passende Lösung dafür geben würde. Das ist das Problem.
Deswegen sagt man Anfängern (und auch etwas fortgeschritteren Programmierern), "Wenn du willst, dass ich dir mit deinem Code helfe, dann verwende kein Goto."

Überspitzter Vergleich: eine Schusswaffe kann ein sehr nützliches Werkzeug sein. Trotzdem wird der Zugriff auf selbige stark beschränkt, weil man damit auch sehr viel Unheil anrichten kann.
Gewinner der 6. und der 68. BlitzCodeCompo

BladeRunner

Moderator

BeitragFr, Jul 12, 2013 16:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Für den hier beschriebenen Einsatz ist goto das sinnigste Werkzeug. Spaghetticode ist nur zu befürchten wenn goto generell für das Hin und Herspringen im Programm genutzt wird. Hier geht es um eine Klar definierte Bedingung.

Die Angst vor Goto stammt im Wesentlichen aus der Zeit als man eigentlich keine anderen Strukturen hatte.
Die ersten Basicdialekte hatten schwer damit zu kämpfen. Hier sehe ich es unkritisch.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

FireballFlame

BeitragFr, Jul 12, 2013 23:43
Antworten mit Zitat
Benutzer-Profile anzeigen
DAK hat Folgendes geschrieben:
Du hast recht, das Continue kann durch ein Goto nachgeahmt werden. Das Gleiche kann man aber auch für While, For, Funktionsaufrufe und quasi alle anderen Flusskontrollelemente sagen. Und hier wird's dann haarig.
[...]
Erfahrene Programmierer können unterscheiden, wo ein Goto angebracht ist, und wo nicht, und selbst die schreiben nicht nur schönen Code.

Ja schon, aber While, For, und Funktionen stehen in BlitzBasic ja schon zur Verfügung. Es ging ja hier nur darum, das fehlende Element (Continue) nachzubilden, nicht die vorhandenen zu ersetzen.
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit
 

CO2

ehemals "SirMO"

BeitragSa, Jul 13, 2013 0:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Schönste Lösung ohne Continue ist denke ich - wie DAK schon schrieb - folgende:

BlitzBasic: [AUSKLAPPEN]
For x = 0 To 10
If(x Mod 2 = 0) ; Als Bedingung bietet sich eine Statusvariable o.ä. an, ist sie bspw. 1, so wird der Teil im If-Block übersprungen (entspricht ungefähr Continue), sonst wird er ausgeführt.
; Hier Kommt der Code hin, der ausgeführt werden soll
EndIf
Next


Ganz ohne GoTo, verwirrende Sprungmarken und Sprünge, unübersichtligkeit, ...
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Xeres

Moderator

BeitragSa, Jul 13, 2013 0:37
Antworten mit Zitat
Benutzer-Profile anzeigen
In realem Code mit ein paar mehr Bedingungen kann ein Sprung die einfachere und übersichtlichere Variante sein.
Oder man benutzt gleich eine Sprache, die kein GoTo beherrscht aber dafür die richtigen Kontrollstrukturen bietet.
Wie immer muss man wissen was man tut und warum - Abergläubigkeit an Anfänger weiter zu geben ist unnötig. Die Probleme von GoTo wurden ja - mal wieder - ausreichend beleuchtet.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group