VB 2008 - Endlosschleife

Ich bekomme folgende Fehlermeldung:
„StackOverflowException wurde nicht behandelt.“

Ich wollte Programmieren das zwei zahlen zufällig generiert werden und die erste durch die zweite geteilt wird.
Der User sollte dann das Ergebnis sagen und anschliessend gibt das Programm die Rückmeldung ob es richtig ist.

Das Programm gibt dann z.B. dann diese Frage aus:

„Wieviel ist 20/10?“

Das Problem hierbei ist allerdings das auch diese Fragen hier auftauchen:

„Wieviel ist 19/22?“
oder
„Wieviel ist 63/55)“

Bei beiden habe ich das Problem das eine Kommastelle herraus kommt.
Wenn es jetzt sowas wie 4,5 währe dann währ das ja noch ok aber bei 6,123892348910 bezweifle ich das jemand das im Kopf wusste.

Das 1. Problem konnte ich beheben, so das jetzt immer die erste Zahl die größere ist.
Das 2. Problem wollte ich lösen in dem ich dem Programm sage das wenn keine ganze Zahl herraus kommt soll er neue zwei zahlen generieren.

Bei meinen rechnungen kommen nur Ergebnisse von 1 bis 100 raus von daher hab ich es mit etwas mühe so versucht zu lösen:

Select Case lösung
Case 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100
Case Else
teilendurchhundert()
End Select

Bei der gelegenheit wüsste ich ganz gerne wie ich in solchen Fällen mir die Arbeit mit den ganzen Zahlen ersparen könnte. Beim generator geht das ja mit (1, 101) aber hier ging das nicht.

An sich schien das Problem gelöst, da dem Programm nurnoch die Möglichkeiten blieben zwei zahlen zu generieren die am ende ein „gerades“ ergebnis ohne kommastellen raus kommt.

Wenn das Programm jetzt aber zuviele Versuche braucht um zwei passende Zahlen zu finden sagt er etwas das soviel bedeutet wie:
„Bist du sicher das keine Endlosschleife aufgetreten ist?“

Bitte um hilfe.
Danke

Hallo!

Das mit der 100-teiligen Select-Anweisung ist nicht Dein Ernst, oder?
Was gefällt Dir denn an den ganz normalen mathematischen Operatoren wie > und

Hallo!

Das mit der 100-teiligen Select-Anweisung ist nicht Dein
Ernst, oder?

Wie bereits erwähnt hätte ich gerne einen Lösungsvorschlag wie man soetwas umgehen kann!!

Was gefällt Dir denn an den ganz normalen mathematischen
Operatoren wie > und 1 dann kommen ergebnisse wie 3,42398 immernoch raus.

Zudem machst Du es uns praktisch unmöglich, Dir zu helfen,
wenn Du keinen Code postest.

An sich hatte ich meines erachtens nach den code gepostet aber hier ist mal der komplette sub:

Sub teilendurchhundert()
Dim generator As New Random
Dim erstezahl As Integer = generator.Next(1, 101)
Dim zweitezahl As Integer = generator.Next(1, 101)
If erstezahl

Selbes Problem tratt übrigens eben auch bei einem ähnlichem Code auf, nachdem ich 11 mal das richtige Ergebnis eingegeben hab.

Sub addierenbishundert()
Dim generator As New Random
Dim erstezahl As Integer = generator.Next(1, 101)
Dim zweitezahl As Integer = generator.Next(1, 101)
If (erstezahl + zweitezahl > 100) Then
addierenbishundert()
End If
Console.WriteLine(„Wieviel ist " + erstezahl.ToString + (“ + „) + zweitezahl.ToString + (“?"))
Dim versuch = Console.ReadLine()
Dim lösung = (erstezahl + zweitezahl)
If versuch = lösung Then
Console.WriteLine(„Sehr gut.“)
Console.WriteLine(„Hier kommt die nächste Aufgabe.“)
addierenbishundert()
ElseIf versuch = 1234 Then
auswaehlen()
Else
Console.WriteLine(„Nein, es währe " + lösung.ToString + (“ gewessen."))
Console.WriteLine(„Hier kommt die nächste Aufgabe.“)
addierenbishundert()
End If

Ich denke es ist das selbe Problem weil er ja einen Befehl häufig wiederholt.

Hallo nochmal!

Selbes Problem tratt übrigens eben auch bei einem ähnlichem
Code auf, nachdem ich 11 mal das richtige Ergebnis eingegeben
hab.

Nachdem man jetzt den ganzen Code sieht, wird auch sofort klar, wo die StackOverflowException herkommt:

Sub addierenbishundert()
Dim generator As New Random
Dim erstezahl As Integer = generator.Next(1, 101)
Dim zweitezahl As Integer = generator.Next(1, 101)
If (erstezahl + zweitezahl > 100) Then
addierenbishundert()

Das, was Du hier machst, nennt man Rekursion und das ist an dieser Stelle leider total unangebracht. Du lässt die Funktion sich selbst aufrufen, ohne irgendein Abbruchkriterium - kein Wunder, dass irgendwann der Stack überläuft.
Grundsätzlich ist Rekursion eine feine Sache - damit lassen sich manche Probleme sehr elegant lösen, aber es ist auch eine etwas fortschrittlichere Technik, der Du Dich erst widmen solltest, wenn Du die Grundlagen gelernt hast.

End If
Console.WriteLine("Wieviel ist " + erstezahl.ToString

  • (" + „) + zweitezahl.ToString + (“?"))
    Dim versuch = Console.ReadLine()
    Dim lösung = (erstezahl + zweitezahl)
    If versuch = lösung Then
    Console.WriteLine(„Sehr gut.“)
    Console.WriteLine(„Hier kommt die nächste
    Aufgabe.“)
    addierenbishundert()

Auch wieder unsinnige Rekursion…

ElseIf versuch = 1234 Then
auswaehlen()
Else
Console.WriteLine(„Nein, es währe " +
lösung.ToString + (“ gewessen."))

2 Schreibfehler in einer Ausgabezeile, nicht schlecht… :smile:

Console.WriteLine(„Hier kommt die nächste
Aufgabe.“)
addierenbishundert()

Und nochmal Rekursion.

End If

Ich denke es ist das selbe Problem weil er ja einen Befehl
häufig wiederholt.

Schau’ Dir mal die Befehle für Schleifen an (While/Wend oder Do/While), das brauchst Du nämlich hier statt der Rekursion.

Beim Bestimmen der 2. Zahl wäre es übrigens geschickter, das zu schreiben:

Dim zweitezahl As Integer = generator.Next(1, 101-erstezahl)

dann kannst Du Dir die Überprüfung sparen, ob die Summe

ElseIf versuch = 1234 Then
auswaehlen()
Else
Console.WriteLine(„Nein, es währe " +
lösung.ToString + (“ gewessen."))

2 Schreibfehler in einer Ausgabezeile, nicht schlecht… :smile:

welche meinst du?

Das mit den ungeraden zahlen habe ich gelöst bekommen.
Ich habe zahl a und zahl b generieren lassen und habe dann die lösung daraus genommen um sie durch zahl a zu teilen.
als formel sieht das ungefähr so aus
a:b=c ausgegeben wird aber c:a=b b ist somit automatisch eine gerade zahl. das läuft wunderbar.

ich habe allerdings leider das mit dem flowexception noch nicht verstanden. ich hatte es eben schon nach 3 richtigen ergebnissen das er sagt es sei eine endlosschleife entstanden.
es ist bewusst so aufgebaut gewessen das ich nur über das X rechts oben aus dem programm komme.
kann ich in meine formel nicht etwas eingeben das ich sage dies ist keine endlosschleife, das ist so gewollt.?

Hi!

Console.WriteLine(„Nein, es währe " +
lösung.ToString + (“ gewessen."))

2 Schreibfehler in einer Ausgabezeile, nicht schlecht… :smile:

welche meinst du?

„wäre“ schreibt man ohne ‚h‘ und „gewesen“ mit einem ‚s‘

Das mit den ungeraden zahlen habe ich gelöst bekommen.
Ich habe zahl a und zahl b generieren lassen und habe dann die
lösung daraus genommen um sie durch zahl a zu teilen.
als formel sieht das ungefähr so aus
a:b=c ausgegeben wird aber c:a=b b ist somit automatisch eine
gerade zahl. das läuft wunderbar.

ich habe allerdings leider das mit dem flowexception noch
nicht verstanden. ich hatte es eben schon nach 3 richtigen
ergebnissen das er sagt es sei eine endlosschleife entstanden.
es ist bewusst so aufgebaut gewessen das ich nur über das X
rechts oben aus dem programm komme.
kann ich in meine formel nicht etwas eingeben das ich sage
dies ist keine endlosschleife, das ist so gewollt.?

Anscheinend fehlt Dir noch das grundsätzliche Verständnis dafür, was eigentlich passiert, wenn ein Programm ausgeführt wird.
Die Laufzeitumgebung beginnt irgendwo mit der Abarbeitung des Programms. Dabei muss sie sowohl Variablen verwalten, die das Programm anlegt und verwendet als auch wissen, an welcher Stelle die Ausführung gerade ist. Hierfür gibt es einen sog. Stack (und in der Regel einen Heap, tut aber jetzt nichts zur Sache) und einen Programmausführungszeiger, der auf die Stelle zeigt, an der das Programm gerade ist.
Wenn im Programm eine Funktion aufgerufen wird, werden die Argumente für diese Funktion und eine Rücksprungadresse auf den Stack gelegt (der nicht beliebig groß ist!) und der Programmausführungszeiger auf den Anfang der Funktion fortgesetzt.
Die Funktion entfernt ggf. die Parameter vom Stack.
Sobald die Funktion durchgelaufen ist, wird das Resultat auch wieder auf den Stack gelegt und die Ausführung springt „eine Ebene nach oben“ (an die Rücksprungadresse auf dem Stack).
Wenn die Funktion nun aber ihrerseits wieder andere Funktionen aufruft, werden wiederum Parameter auf den Stack gelegt, der Stack wächst mit jeder Verschachtelungstiefe an.
In Deinem Fall ruft sich die Funktion immer wieder selber auf und packt munter Daten auf den Stack, ohne mal wieder zurückzukommen.
Wenn der Stack dann irgendwann mal überläuft (eben weil er nicht beliebig groß ist), bekommst Du genau die StackOverflowException.

Jetzt etwas klarer?

Gruß,
Martin

Ja, so hatte ich mir das auch in etwa vorgestellt.
Mir ist allerdings noch nicht klar wie ich das abstellen kann. :wink:

Kann ich ihm nicht sagen das er die alten gespeicherten Sachen wieder löschen darf wenn er die nächste Funktion aufruft?

Hallo!

Du kannst „ihm sagen, dass er die alten Sachen löschen kann“. Das Zauberwort heisst „return“. In Deinem Programm sind aber die Kontrollstrukturen falsch gewählt bzw. nicht vorhanden.
Konkret, wie früher schon geschrieben, brauchst Du while oder do…while Schleifen statt der rekursiven Aufrufe.
Bevor ich aber jetzt anfange, hier die elementaren Kontrollstrukturen zu erklären, würde ich Dir wirklich dringend empfehlen, ein Einsteigerbuch zum Thema Programmierung durchzuarbeiten - Links gibt es zur Genüge in den FAQ.

Gruß,
Martin