Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Repeat-Until --> Endlosschleife!!
Ottchen - Mi 20.11.02 20:06
Titel: Repeat-Until --> Endlosschleife!!
Hallo Liste!
Ich habe mal wieder ein Problem mit der Austrittsbedingung der Repeat-Until-Schleife. Der größte gemeinsame Teiler zweier Zahlen soll nach dem Algorithmus von EUKLID ermittelt werden. Wenn die Restdivision Null ergibt, soll die Schleife beendet sein. Gebe ich z.B. die Zahlen 24 und 12 ein, kommt sofort das Ergebnis 3 und der Rest Null wird auch im StringGrid ausgegeben.
Hier der QT:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure TForm1.Rechne1Click(Sender: TObject); var a, b, i, Rest, quotient:integer; begin a:=StrToInt(a_Edit.Text); b:=StrToInt(b_Edit.Text);
if a<b then MessageDlg('a muss größer als b sein!',mtInformation,[mbOK],0) else begin i:=1; repeat StringGrid1.RowCount:=i+1; StringGrid1.Cells[0,i]:=IntToStr(i); StringGrid1.Cells[1,i]:=IntToStr(a); // dient nur der Ausgabe StringGrid1.Cells[2,i]:=IntToStr(b); // dient nur der Ausgabe quotient:=a DIV b; // dient nur der Ausgabe StringGrid1.Cells[3,i]:=IntToStr(quotient); // dient nur der Ausgabe Rest:=a MOD b; StringGrid1.Cells[4,i]:=IntToStr(Rest); // dient nur der Ausgabe i:=i+1; until Rest=0; end; {of begin Zeile 52} ausgabe_panel.caption:=IntToStr(b); end; |
Findet Ihr einen Fehler? :shock:
Danke!!!!
Ottchen
tommie-lie - Mi 20.11.02 20:59
Hast du schonmal was von Trace und Step und der Watch-List gehört?
Anscheinend nicht, denn:
Wenn du dir die Werte im Debugger mal anschaust, wird dir kalr, warum die Schleife endlos durchgelaufen wird, sobald Rest <> 0 ist:
Zuerst führst du die Integer-Division von a \ b durch (nicht zu verwechseln mit der Fließkommadivision a / b). Dadurch hast du den ganzzahligen Wert des Quotienten a : b. An den Werten veränderst du nichts.
Ich habe es bei mir mal mit 143 und 12 ausprobiert. Ergebnis: 11
Dann holst du dir mit mod den Rest der Integer-Division. Bei mir auch 11. Dann guckst du, ob Rest = o ist. Ist nicht, also nochmal das ganze. Wieder 143 div 12, wieder 11. Wieder 143 mod 12. Wieder Rest 11. Immer noch nicht 0, also wieder 143 mod 12, immer noch nicht 0, also wieder 143 mod 12.
Klar?
Wenn eine Zahl nicht ohne Rest teilbar ist, wird die Schleife immer ausgeführt, weil du die Werte nie änderst, er also immer wieder nicht 0 ist.
Tschüß
Thomas
Funzi - Mi 20.11.02 22:08
Titel: while-Schleife
Also... ich glaube das Problem lässt sich lösen, indem man anstatt der repeat-Schleife eine while-Schleife benutzt.
Habe es nicht ausprobiert, aber erst vor kurzem eine Arbeit darüber geschrieben. Also ich hab deinen QT mal geringfügig verändert...
Probiers mal aus!
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| ... while Rest <> 0 do begin StringGrid1.RowCount:=i+1; quotient:=a DIV b; Rest:=a MOD b; i:=i+1; end; |
Feedback erwünscht!
Wolff68 - Do 21.11.02 08:05
Und was soll sich nun dadurch ändern? Ausser, daß Du vorher nun auch noch den Rest mit einem Wert <> 0 initialisieren musst?
Hast Du über 1 Stunde geschrieben? Oder warum baust Du genau den gleichen Fehler ein, den tommie bereits erklärt hatte?
Egal ob While oder Repeat. Wichtig ist immer, daß sich der Wert der Abbruchbedingung auch Ändert !!!
Wenn a MOD b ungleich 0 ist kannst es so oft rechnen wie Du willst. Solange sich weder bei a noch b was ändert wird das Ergebnis <>0 immer das gleiche bleiben.
Delete - Do 21.11.02 11:09
Wolff68 hat folgendes geschrieben: |
Wichtig ist immer, daß sich der Wert der Abbruchbedingung auch Ändert !!! |
Oder um genauer zu sein: Sie muß irgendwann mal erfüllt sein. Eigentlich nicht genauer, sondern richtiger. Wenn sie sich ändert heißt, dass nicht, dass sie auch mal greift.
UGrohne - Do 21.11.02 11:31
Hab mal in meinem Info-Archiv gestöbert und folgendes gefunden:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| function tform1.ggt(a,b : integer):integer; var rest: integer; begin repeat rest:= a mod b; a:= b; b:= rest; until rest= 0; ggt:= a; end; |
Hoffe, das hilft weiter
Ottchen - Do 21.11.02 17:52
Titel: Ihr habt ja alle Recht :--))
Ja logisch!!
Das kann ja auch nicht funktionieren, weil ich einfach zu unkonzentriert und müde war, so dass zwei Anweisungen für den EUKLID-Algor. fehlen! Mensch!
Hier der richtige Quelltext (so wie ihn UGrohne auch beschrieb):
Quelltext
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:
| procedure TForm1.Rechne1Click(Sender: TObject); var a, b, i, Rest, quotient:integer; begin a:=StrToInt(a_Edit.Text); b:=StrToInt(b_Edit.Text);
if a<b then MessageDlg('a muss größer als b sein!',mtInformation,[mbOK],0) // oder ganz einfach den folgenden Teil nehmen und Rest:=b MOD a rechnen else begin i:=1; repeat StringGrid1.RowCount:=i+1; StringGrid1.Cells[0,i]:=IntToStr(i); StringGrid1.Cells[1,i]:=IntToStr(a); StringGrid1.Cells[2,i]:=IntToStr(b); quotient:=a DIV b; StringGrid1.Cells[3,i]:=IntToStr(quotient); Rest:=a MOD b; StringGrid1.Cells[4,i]:=IntToStr(Rest); a:=b; b:=Rest; i:=i+1; until Rest=0; end; {of begin Zeile 52} ausgabe_panel.caption:=IntToStr(a); end; |
:arrow: Danke an alle!
Und von Trace und Step und der Watch-List habe ich wirklich nichts gehört; bin aber für jeden Tipp dankbar. :wink:
Ottchen
UGrohne - Do 21.11.02 18:04
Nochn kleiner Tipp von nem Schreibfaulen: Mach statt
einfach
Macht dasselbe, aber sieht schöner aus *g*
Wolff68 - Do 21.11.02 19:17
Titel: Watchlist, Trace, Step
Also was tommie gemeint hat ist das Schrittweise Ausführen des Programmes während man die Variablen im Auge behält.
Auf Deutschen Systemen zu finden unter Start / Einzelne Anweisung ....
Die Watchlist ist das Fenster mit den Überwachten Ausdrücken.
Findet man unter Ansicht / Debugfenster / Überwachte Ausdrücke
Am besten setzt Du Dir in die Schleife oder davor einen Haltepunkt und gehst dann die Programmschritte einzeln mit F7 durch.
tommie-lie - Do 21.11.02 19:35
Jepp.
Der Unterschied zwischen Trace und Step ist nur, daß Trace auch die Zeilen einzeln bearbeitet, die in Funktionen zu finden sind, während Step einfach die Funktion ausführt. Also wenn man sein event hat, und hat jede Menge eigene Funktionen deklariert und ist sich sicher, daß diese korrekt sind, braucht man ja nur das Event. Da würde dann Step besser sein, weil mit Trace jedesmal die funktionen (die ja richtig sind) auch einzeln abgearbeitet werden.
Doof erklärt, iss aber so.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!