Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
C++Builder Senior JLI'ler
Anmeldedatum: 04.10.2003 Beiträge: 235
Medaillen: Keine
|
Verfasst am: 25.09.2004, 22:22 Titel: Rekursionsgrenze |
|
|
hi,
ich hab mal diese Progrämmschen geschrieben und mich gewundert das es nur bis zu einer gewissen Rekursionstiefe funktioniert:
Code: |
#include <iostream>
using namespace std;
int bla(int i)
{
if(i==0)
return 0;
return i+bla(i-1);
}
int main(void)
{
cout << "blabla" << endl;
cout << (int)bla(10000) << endl;
cout << "blabla" << endl;
return 0;
} |
bis 10000 funktioniert es bei 100.000 nicht mehr da wird dann nur noch das erste blabla angezeigt und dann das Programm beendet.
Warum??
Es gibt übrigens 128 zurück, falls das hilft.
Ich benutze MingW32 weiß nicht ob es bei VC++ funktioniert.
Danke, schonmal! |
|
Nach oben |
|
|
Sören JLI Master Trainee
Anmeldedatum: 26.07.2002 Beiträge: 647 Wohnort: Bonn Medaillen: Keine
|
Verfasst am: 25.09.2004, 22:35 Titel: |
|
|
Ich denke mal 100.000 sind einfach zuviel für einen int.
Denn: Bei 100.000 solltest du am Ende einen Wert von 5000050000 rausbekommen. Ein int kann aber nur maximal ca. +2147000000 enthalten. Von daher sollte ein Wert von 65.000 noch funktionieren, 66.000 dagegen nicht mehr. Stimmts? ;D
Allerdings wundert es mich dass sich das Programm dann beendet. Bei TurboPascal wars immer so, dass die zahl bei überschreitung des Wertebereiches nochmal vom minimalbereich begann. |
|
Nach oben |
|
|
C++Builder Senior JLI'ler
Anmeldedatum: 04.10.2003 Beiträge: 235
Medaillen: Keine
|
Verfasst am: 25.09.2004, 22:51 Titel: |
|
|
das meine ich.
eigentlich müsste das Programm endlos laufen. Kannst u es vielleicht mal bei dir compilieren und ausprobieren? |
|
Nach oben |
|
|
Sören JLI Master Trainee
Anmeldedatum: 26.07.2002 Beiträge: 647 Wohnort: Bonn Medaillen: Keine
|
Verfasst am: 25.09.2004, 23:01 Titel: |
|
|
Mhh, ich krieg ab 5000 schon nen StackOverflow vom Compiler, frag mich aber nicht warum^^
Ich benutz MS VC7.0, falls es dich interessiert, vielleicht sind da ja irgendwelche speziellen Einstellungen drinne, werd mich morgen nochmal ransetzen! |
|
Nach oben |
|
|
C++Builder Senior JLI'ler
Anmeldedatum: 04.10.2003 Beiträge: 235
Medaillen: Keine
|
Verfasst am: 25.09.2004, 23:16 Titel: |
|
|
Danke!
MingW scheint ohne ne Exception zu werfen zu beenden. |
|
Nach oben |
|
|
AFE-GmdG JLI MVP
Alter: 45 Anmeldedatum: 19.07.2002 Beiträge: 1374 Wohnort: Irgendwo im Universum... Medaillen: Keine
|
Verfasst am: 25.09.2004, 23:16 Titel: |
|
|
Für jede Funktion, die aufgerufen wird, müssen Daten zwischengespeichert werden, wie z.B. der Rücksprungpunkt und alle lokalen Funktionsvariablen. Das kostet nicht wenig Stackspeicher - und der ist ja bekanntlich begrenzt. Man kann per Compilerschalter den Stack vergrößern (weiss nich genau welcher schalter das is) aber tief-recursive Funktionen sind dann immer irgendwann ein Problem.
Deshalb sollte man recursive Funktionen nur begrenzt einsetzen - und nur dann, wenn man weiss, was genau man tut. Für jedes recursive Problem gibt es immer auch eine iterative Lösung, die unter Umständen zu bevorzugen ist - nicht nur wegen der (dann) kürzeren Programmlaufzeit und dem geringeren Speicherverbrauch.
Dein Code lässt sich in einer simplen For-Schleife lösen: Code: |
int i=0;
for(int j=0; j<MaxWert; j++)
i+=j;
|
_________________
CPP: | float o=0.075,h=1.5,T,r,O,l,I;int _,L=80,s=3200;main(){for(;s%L||
(h-=o,T= -2),s;4 -(r=O*O)<(l=I*I)|++ _==L&&write(1,(--s%L?_<(L)?--_
%6:6:7)+\"World! \\n\",1)&&(O=I=l=_=r=0,T+=o /2))O=I*2*O+h,I=l+T-r;} |
|
|
Nach oben |
|
|
C++Builder Senior JLI'ler
Anmeldedatum: 04.10.2003 Beiträge: 235
Medaillen: Keine
|
Verfasst am: 26.09.2004, 07:19 Titel: |
|
|
ja das ist schon klar.
Das war jetzt nur ein Bsp um zu zeigen das die Rekursionstiefe begrenzt ist. Eigentlich benutze ich diese Rekursion in einem Komplexeren Programm und habe mich gewundert das es sich plötztlich beendet. Da hab ich dann immer teilweise auskommentiert und festgestellt das es an der Rekursion liegt.
Code: |
#include <iostream>
using namespace std;
int i=0;
int bla(void)
{
i++;
cout << ( int)i << endl;
if(i==1000000)
return i;
return bla();
}
int main(void)
{
cout << "blabla" << endl;
cout << (int)bla() << endl;
cout << "blabla" << endl;
return 0;
} |
Wenn ich das ausführe komme ich gerade mal bis 130119.
Das mit dem Stack muss ich mir noch mal angucken. |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 26.09.2004, 07:50 Titel: |
|
|
Aber ich wäre mir da nicht so sicher, ob man jedes Rekussive Lösung auch mit einer Schleife machen kann.
Als Beispiel musste ich mal so ne bescheuerte Schildkröte die zeichenne konnte in irgend so einen Kusr programmieren. Da haben wir auch Rekursionen gemacht.
Also, man sollte einen hübschen Baum machen, der sich immer weiter verzweigt.Im Prinzip einmal schräg nach links, zurück, und wieder einmal schräg nach rechts.Und an jedes Ende eine weitere, kleinere Verzweigung. Also musste sich die FUnktion insgesamt zweimal selbst aufrufen. Wie soll man das dann in einer Schleife Lösen.
Die Rekussion:
Code: |
Draw(Größe)
{
if(Größe>0)
{
ZeichneRechts(Größe)
Draw(Größe-1)
Geh zurück()
ZeichneLinks(Größe)
DrawGröße(-1)
GehZurück
}
}
| [/code] _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
Sören JLI Master Trainee
Anmeldedatum: 26.07.2002 Beiträge: 647 Wohnort: Bonn Medaillen: Keine
|
Verfasst am: 26.09.2004, 08:39 Titel: |
|
|
Es gibt immer eine iterative Lösung(wie AFE auch schon gesagt hat). Aus deinen Code werde ich nicht sonderlich schlau(was soll zB "DrawGröße(-1)", kannste dir doch schenken!?), weil ich nicht genau weiß was da jetzt gemacht werden soll. Aber so wie es mir aussieht könnte man es zB mit einer for-schleife lösen die "Größe" runterzählt, oder man beginnt nicht "außen"(sieht zumindest so aus bei dir), sondern "innen"(hochzählen also). Kann auch sein dass man mehrere Schleifen anwenden muss und dass es ein wenig komplizierter wird, aber es muss immer einen weg geben. |
|
Nach oben |
|
|
Kronos Senior JLI'ler
Anmeldedatum: 19.03.2004 Beiträge: 290
Medaillen: Keine
|
Verfasst am: 26.09.2004, 09:07 Titel: |
|
|
MiracleBoy hat Folgendes geschrieben: | Ich denke mal 100.000 sind einfach zuviel für einen int.
Denn: Bei 100.000 solltest du am Ende einen Wert von 5000050000 rausbekommen. Ein int kann aber nur maximal ca. +2147000000 enthalten. Von daher sollte ein Wert von 65.000 noch funktionieren, 66.000 dagegen nicht mehr. Stimmts? ;D
Allerdings wundert es mich dass sich das Programm dann beendet. Bei TurboPascal wars immer so, dass die zahl bei überschreitung des Wertebereiches nochmal vom minimalbereich begann. |
das ist nicht ganz korrekt. auf einem 286er kann ein int kaum 0-2147000000 fassen ^_^ |
|
Nach oben |
|
|
AFE-GmdG JLI MVP
Alter: 45 Anmeldedatum: 19.07.2002 Beiträge: 1374 Wohnort: Irgendwo im Universum... Medaillen: Keine
|
Verfasst am: 26.09.2004, 10:28 Titel: |
|
|
Kronos hat Folgendes geschrieben: | das ist nicht ganz korrekt. auf einem 286er kann ein int kaum 0-2147000000 fassen ^_^ | Das ist wiederum nicht korrekt. Es ist Kompilerabhängig, wie breit ein int ist. Wenn man einen 64-Bit-Emulierten-Kompiler auf einer 286-Kiste zum laufen kriegt, können ints auch 64 Bit breit sein. Ob das sinnvoll ist, sei dahingestellt, meisstens hat ein 286-er nichmal genug Speicher für den Compiler eingebaut - und du willst auf ein Programm, dass nur ne For-Schleife ist auch nicht 5 Tage beim kompilieren warten... _________________
CPP: | float o=0.075,h=1.5,T,r,O,l,I;int _,L=80,s=3200;main(){for(;s%L||
(h-=o,T= -2),s;4 -(r=O*O)<(l=I*I)|++ _==L&&write(1,(--s%L?_<(L)?--_
%6:6:7)+\"World! \\n\",1)&&(O=I=l=_=r=0,T+=o /2))O=I*2*O+h,I=l+T-r;} |
|
|
Nach oben |
|
|
Fallen JLI MVP
Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 26.09.2004, 18:36 Titel: |
|
|
Sowei ich weiss kann durch einen zu grossen int Wert nichts schlimes passieren das einzige was geschieht ist das man wenn man MAX_INT überschreitet MIN_INT+Überzug bekommt. _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
|
C++Builder Senior JLI'ler
Anmeldedatum: 04.10.2003 Beiträge: 235
Medaillen: Keine
|
Verfasst am: 26.09.2004, 19:10 Titel: |
|
|
weiß vielleicht jemand wie ich den Stack vergrößern kann? |
|
Nach oben |
|
|
|