GGT Berechnung scheitert in Schleife.



  • Hallo zusammen,

    ich muss für die Uni eine Aufgabe lösen in der ich eine rekursiv Funktion für den GGT für die Fakultät und für die Fibonacci-Folge erstelle welche ich natürloich variabel für die Natürlichen Zahlen selber eingeben kann.

    Mein bisheriger Programmcode:

    #include <iostream>
    using namespace std;
    
    int erste, zweite;
    int ggT(int erste, int zweite);
    
    int main()
    {
    	int sw, ergebnis;
    	cout << " Wählen Sie zwischen: " << endl;
    	cout << " 1) Größter gemeinsamer Teiler " << endl;
    	cout << " 2) Fakultät " << endl;
    	cout << " 3) Fibonacci-Folge " << endl;
    	cin >> sw;
    	switch(sw)
    	{
    		case 1: ggT(erste, zweite);
    
    		case 2:
    		case 3:
    		default: break;
    	}
    
    }
    
    int ggT(int erste, int zweite)
    {
    	int ergebnis;
    	cout << " erste Zahl: " << endl;
    	cin >> erste;
    	cout << " zweite Zahl: " << endl;
    	cin >> zweite;
    	if (zweite==0)
    	{
    		cout << erste << endl;
    	}
    	else
    	{
    		ergebnis=ggT(zweite, erste%zweite);
    		cout << ergebnis;
    	}
    }
    

    Das Problem an der Sache ist, dass er quasi in einer endlos-Schleife hineingerät, sodass ich jedes mal nach erste und zweite Zahl gefragt werde, außer natürlich ich gebe die 0 ein.

    Glaube persönlich dass es daran liegt dass er im else wieder die Funktion aufruft und dann von vorne durchgeht, mir fällt aber gerade kein Weg da herum ein, habt ihr vielleicht eine Idee?

    und vorweg ich bin C++ Einsteiger.



  • Du musst Eingabe und rekursive Berechnung auf verschiedene Funktionen aufteilen.



  • okay soweit so gut, das Problem was ich dabei aber habe ist in folgendem Quelltext:

    #include <iostream>
    using namespace std;
    
    int erste, zweite, zahl;
    int ggT(int erste, int zweite);
    int fak(int zahl);
    
    int main()
    {
    	int sw, ausgabe;
    	cout << " Wählen Sie zwischen: " << endl;
    	cout << " 1) Größter gemeinsamer Teiler " << endl;
    	cout << " 2) Fakultät " << endl;
    	cout << " 3) Fibonacci-Folge " << endl;
    	cin >> sw;
    	switch(sw)
    	{
    		case 1: ggT(erste, zweite);
    
    		case 2:	cout << " Geben Sie Ihre Fakultätszahl ein : " << endl;
    			cin >> zahl;
    			ausgabe = fak(zahl);
    			cout << " Ihr Ergebnis ist : " << ausgabe << endl;
    		case 3:
    		default: break;
    	}
    
    }
    
    int ggT(int erste, int zweite)
    {
    	int ergebnis;
    	cout << " erste Zahl: " << endl;
    	cin >> erste;
    	cout << " zweite Zahl: " << endl;
    	cin >> zweite;
    	if (zweite==0)
    	{
    		cout << erste << endl;
    	}
    	else
    	{
    		ergebnis=ggT(zweite, erste%zweite);
    		cout << ergebnis;
    	}
    }
    
    int fak(int zahl)
    {
    	int ergebnis;
    
    	if(zahl==0)
    	{
    		cout << " Ergebnis ist : " << 1 << endl;
    	}
    	else
    	{
    		zahl * fak(zahl-1);
    	}
    }
    

    er liest jetzt z.B. im Fall 2 die Zahl ein, ich gebe die 3 ein, dann müsste er doch die Variable zahl an die Funktion fak(); übergeben und mit dieser eingegebenen Variable zahl die Fakultät errechnen, anstattdessen wird mir aber ausgeworfen:

    Ergebnis ist : 1
    Ihr Ergebnis ist: 134521056

    Somit nimmt er sowohl das if als auch das else dabei mit, obwohl er ja eigentlich direkt zum else springen sollte berechnen sollte und dann die Ausgabe haben sollte. 😕



  • Du hast da zwei Probleme:

    1. Du hast für die Funktion fak einen RÜckgabetyp (int) definiert, gibst aber keinen Wert zurück.
    2. Schau dir den else-Zweig in fak nochmal genau an. Du machst da eine Berechnung, aber was passiert mit dem Ergebnis der Berechnung?


  • Wenn du bei deinem Compiler die Warnstufen hoch drehst, wird er dir sagen, dass in deinen Funktionen kein Wert zurückgegeben wird (es fehlt eben ein return).

    Die Funktion sollte selber natürlich auch nichts ausgeben.



  • huwul schrieb:

    okay soweit so gut, das Problem was ich dabei aber habe ist in folgendem Quelltext:

    Du hast das return vergessen.

    Das ist ein Thema, was grundlegend für die Arbeit mit Funktionen ist. Du arbeitest gerade mit Rekursion, was schon fortgeschritten ist. Mit anderen Worten, du schleppst ein ziemliches Defizit mit dir herum!

    Ich korrigiere deinen Code mal:

    int fak(int zahl)
    {
        //int ergebnis;  -- Brauchen wir nicht
    
        if(zahl==0)
        {
            // Ausgabe wozu?
            // cout << " Ergebnis ist : " << 1 << endl;
            return 1;
        }
        else
        {
            return zahl * fak(zahl-1);
        }
    }
    


  • Deine beiden "Berechnungsfunktionen" geben keinen Wert zurück - Stichwort: return



  • Ja das mit dem return ist mir nebenbei auch aufgefallen, woraufhin ich es auch korrigiert habe, die Variable ergebnis war von einem vorherigen Fehlversuch, die st ebenfalls raus.

    Ist alles auskorrigiert, keine Sorge ich habe kein Defizit was return angeht, ich habs nur grade total übersehen :o

    Nunja beide sowohl GGT und Fakultät funktionieren soweit, jetzt muss ich mich nur noch an den Debugger geben. 👍



  • Wie lässt sich denn der Fakultätsbereich erweitern, sodass ich auch eine Fakultät von 15 berechnen kann?

    der Wertebereich hört nämlich dabei bei 2004310016 auf.
    Und bei einem Unsigned int ist dort auch Ende.
    Double wollte ich eigentlich nicht zulassen, da ja nur natürliche Zahl verwendet werden sollten, weshalb ich auch die if's noch abändern muss.



  • Ohne eine externe Lib (z.B. BigNum) kannst du als Datentyp nur "unsigned long long" verwenden (aber auch dann geht die Fakultät nur bis ca. 21 [bei 64bit])).

    Schau auch mal in http://www.c-plusplus.net/forum/259339 rein (geht auch um Fakultät).



  • Habt ihr vielleicht noch eine Idee wie ich im Debugger für jede Rekursion den Backtrace ausgeben kann?

    ich weiß, dass backtrace im gdb ein befehl ist, allerdings zeigt er mir immer an "No Stack" und hab mir grade schon ein paar Tutorials angeschaut, die mich aber bezüglich des Backtrace nicht schlauer machen.

    Ich muss quasi bei jedem Aufruf den Stack ausgeben.



  • Wenn das Programm im Debugger läuft und an einem Breakpoint angehalten hat, solltest du auch einen Baktrace erhalten.



  • Das Problem ist, dass kein Breakpoint da ist, ich kann das Programm starten, dann läuft es halt durch und danach kann ich keinen Backtrace mehr erhalten " NO Stack"

    Und Breakpoint setzen kann ich z.b. für die Fakultätsfunktion warum auch immer nicht.



  • huwul schrieb:

    Das Problem ist, dass kein Breakpoint da ist, ich kann das Programm starten, dann läuft es halt durch und danach kann ich keinen Backtrace mehr erhalten " NO Stack"

    backtrace gibt den Stack von der aktuellen Stelle aus. Wenn du das Programm bis zum Ende durchlaufen lassen hast, ist er natürlich leer.

    Und Breakpoint setzen kann ich z.b. für die Fakultätsfunktion warum auch immer nicht.

    break fak
    Falls das nicht geht, hast du vielleicht ohne Debugsymbole gebaut? gcc -g



  • das geht b fak.

    Habe mit g++ und ohne -g gearbeitet. Allerdings ist die Aufgabenstellung dass Quasi jedesmal wo die Fakultät einen Schritt macht der Backtrace angegeben werden sollte.



  • huwul schrieb:

    das geht b fak.

    Habe mit g++ und ohne -g gearbeitet. Allerdings ist die Aufgabenstellung dass Quasi jedesmal wo die Fakultät einen Schritt macht der Backtrace angegeben werden sollte.

    Die Aufgabenstellung hat zum Ziel, dass du dich mit dem gdb vertraut machst. Das solltest du dann auch tun.


Log in to reply