Frage zu rekursive Funktionen



  • Hallo,

    ich übe mich gerade im Umgang mit rekursiven Funktionen und habe eine Frage zum folgenden Beispiel:

    void recursive(int n)
    {
           if (n > 0)
           {
                 cout << n << endl;  // 1. Ausgabe von 5 4 3 2 1
                 recursive(n - 1);   // recursive case
                 cout << n << endl;  // 2. Ausgabe von 1 2 3 4 5
           }
    }
    
    int main() 
    {
           recursive(5);
    
           return 0;
    }
    
    

    Die erste Ausgabe ist mir klar.
    Da nach der ersten Ausgabe die Bedingung if(n > 0) nicht mehr erfüllt ist, verstehe ich es nicht warum die 2. Ausgabe überhaupt durchgeführt wird? Hier sollte doch die Funktion verlassen werden.



  • @ledi001 sagte in Frage zu rekursive Funktionen:

    Hier sollte doch die Funktion verlassen werden.

    Warum sollte nach einem Funktionsaufruf (hier ein rekursiver Aufruf - so what) eine Funktion verlassen werden?



  • @ledi001 sagte in Frage zu rekursive Funktionen:

    Da nach der ersten Ausgabe die Bedingung if(n > 0)

    5-1 ist nicht > 0?

    Was hat das mit MFC zu tun?



  • @Jockelx Da nach dem 5. rekursiven Funktionsaufruf n = 0 und damit if(n>0) false ist, müsste nach meinem Verständnis die Funktion verlassen werden. Offenbar ist dem nicht so, aber meine Frage ist warum ist das so?



  • Benutze einen Debugger. Schau dir den Stack an. Dann verstehst du, was rekursiv bedeutet.



  • @manni66 OK, habe ich gemacht und wenn ich das jetzt richtig interpretiere, dann wir die Funktion welche am Stack landet rückwärts wieder abgearbeitet (also rückwärts aufgerufen) bis der Stack wieder sauber ist.



  • Denk' oder nimm dir 6 kleine Zettelchen und beschrifte die von 0-5. Anschließend sortierst du sie absteigend.
    5 -> Ausgabe 5, Zettel zur Seite
    4 -> Ausgabe 4, Zettel auf 5
    3 -> Ausgabe 3, Zettel auf 5 und 4
    ...
    0 -> Abbruch -> ganz weglegen

    Und nun wird der Stapel wieder von oben nach unten abgearbeitet. Oben liegt die 1:
    1 -> Ausgabe 1, Zettel weg
    ...
    5 -> Ausgabe 5, Zettel weg und verlassen (in diesem Fall zu main() zurückkehren)



  • Vielleicht verwirren dich deine Kommentare?

                 cout << n << endl;  // 1. Ausgabe von 5 4 3 2 1
                 recursive(n - 1);   // recursive case
                 cout << n << endl;  // 2. Ausgabe von 1 2 3 4 5
    

    Ich würde eher kommentieren:

                 cout << n << endl;  // 1. Ausgabe von n
                 recursive(n - 1);   // recursive case, führe recursive(n-1) aus (gibt n-1, ..., 1, 1, ..., n-1 aus)
                 cout << n << endl;  // 2. Ausgabe von n
    


  • @ledi001 sagte in Frage zu rekursive Funktionen:

    also rückwärts aufgerufen

    Möglicherweise meinst du das Richtige. Die Funktion wird aber nicht aufgerufen, denn sie läuft ja immer noch, und das mehrfach. Wenn ein (rekursiver) Funktionsaufruf beendet ist, wird die Aneisung in der "nächsten Zeile" ausgeführt.



  • Vlt. hilft es ja mal die Funktion auszuschreiben ...

    int main() {
      int a = 5;
      if(a > 0) {
        std::cout << a << '\n'; //a == 5;
        int b = a - 1;
        if(b > 0) {
          std::cout << b << '\n'; //b == 4;
          int c = b - 1;
          if(c > 0) {
            std::cout << c << '\n'; //c == 3;
            int d = c - 1;
            if(d > 0) {
              //usw. bis die Bedingungen > 0 irgendwann nicht mehr erfüllt ist
            }
            std::cout << c << '\n'; //c == 3;
          }
          std::cout << b << '\n'; //b == 4;
        }
        std::cout << a << '\n'; //a == 5;
      }
    }