<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Rekursionsfrage]]></title><description><![CDATA[<p>Hallo zusamme</p>
<p>ich habe eine grundsätzliche Frage zur Rekursion. Angenommen ich berechne das Produkt zweier Zahlen rekursiv, dann würde das etwa so aussehen (ungetestet):</p>
<pre><code class="language-cpp">int mult(int a, int b)
{
  if(b == 0)
	return b;
  return a+mult(a,b-1);
}
</code></pre>
<p>Ich mache nun folgenden Aufruf: mult(3,4). Dann müsste es intern so aussehen:</p>
<p>3+mult(3,3)<br />
3+3+mult(3,2)<br />
3+3+3+mult(3,1)<br />
3+3+3+3+mult(3,0)<br />
3+3+3+3+0</p>
<p>Nun berechne ich mal den ggT nach Euklid rekursiv. Das sieht so aus:</p>
<pre><code class="language-cpp">int ggT(int a, int b)
{
  int tmp = a % b;
  a = b;
  if(tmp = 0) 
     return b;
  return ggT(a,tmp);
}
</code></pre>
<p>In einem letzten Thread habe ich das return vor dem rekursiven Aufruf vergessen. Dass dieses dahingehört ist mir am oberen Beispiel klar, aber warum muss ich beim ggT vor dem Selbstaufruf ein return schreiben? Mir geht es doch eigentlich um das &quot;b&quot; ganz am Schluss und nichts das ich vom Stack noch draufaddieren müsste wie bin der Multiplizierung. Warum ist das so?</p>
<p>Vielen Dank<br />
lg, freakC++</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/286868/rekursionsfrage</link><generator>RSS for Node</generator><lastBuildDate>Thu, 20 Aug 2026 15:31:23 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/286868.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 17 May 2011 19:06:08 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Rekursionsfrage on Tue, 17 May 2011 19:06:08 GMT]]></title><description><![CDATA[<p>Hallo zusamme</p>
<p>ich habe eine grundsätzliche Frage zur Rekursion. Angenommen ich berechne das Produkt zweier Zahlen rekursiv, dann würde das etwa so aussehen (ungetestet):</p>
<pre><code class="language-cpp">int mult(int a, int b)
{
  if(b == 0)
	return b;
  return a+mult(a,b-1);
}
</code></pre>
<p>Ich mache nun folgenden Aufruf: mult(3,4). Dann müsste es intern so aussehen:</p>
<p>3+mult(3,3)<br />
3+3+mult(3,2)<br />
3+3+3+mult(3,1)<br />
3+3+3+3+mult(3,0)<br />
3+3+3+3+0</p>
<p>Nun berechne ich mal den ggT nach Euklid rekursiv. Das sieht so aus:</p>
<pre><code class="language-cpp">int ggT(int a, int b)
{
  int tmp = a % b;
  a = b;
  if(tmp = 0) 
     return b;
  return ggT(a,tmp);
}
</code></pre>
<p>In einem letzten Thread habe ich das return vor dem rekursiven Aufruf vergessen. Dass dieses dahingehört ist mir am oberen Beispiel klar, aber warum muss ich beim ggT vor dem Selbstaufruf ein return schreiben? Mir geht es doch eigentlich um das &quot;b&quot; ganz am Schluss und nichts das ich vom Stack noch draufaddieren müsste wie bin der Multiplizierung. Warum ist das so?</p>
<p>Vielen Dank<br />
lg, freakC++</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2064877</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2064877</guid><dc:creator><![CDATA[freakC++]]></dc:creator><pubDate>Tue, 17 May 2011 19:06:08 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Tue, 17 May 2011 19:20:19 GMT]]></title><description><![CDATA[<p>Ich fürchte ich habe deine Frage nicht ganz verstanden. Ich versuchs jetzt trotzdem mal:</p>
<p>Der ggT ist gemäss dem Algorithmus von Euklid das b im letzen Rekursionsaufruf (du brauchst das return vor dem Selbstaufruf, damit die Rekursion abbricht). Und dieses wird schlussendlich auch zurückgegeben.</p>
<p>Ich denke hier ist etwas falsch:<br />
3+mult(3,3)<br />
3+3+mult(3,2)<br />
3+3+3+mult(3,1) // Hier bricht der Algorithmus bereits ab, weil 3 % 1 == 0, also wird 1 zurückgegeben.<br />
3+3+3+3+mult(3,0) // Wird gar nicht mehr ausgeführt<br />
3+3+3+3+0</p>
<p>Es müsste dann übrigens heissen if(tmp == 0) <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2064885</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2064885</guid><dc:creator><![CDATA[icarus2]]></dc:creator><pubDate>Tue, 17 May 2011 19:20:19 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Tue, 17 May 2011 19:26:29 GMT]]></title><description><![CDATA[<p>freakC++ schrieb:</p>
<blockquote>
<p>In einem letzten Thread habe ich das return vor dem rekursiven Aufruf vergessen. Dass dieses dahingehört ist mir am oberen Beispiel klar, aber warum muss ich beim ggT vor dem Selbstaufruf ein return schreiben?</p>
</blockquote>
<p>Aus demselben Grund. Ohne return keine Rückgabe.</p>
<blockquote>
<p>Mir geht es doch eigentlich um das &quot;b&quot; ganz am Schluss und nichts das ich vom Stack noch draufaddieren müsste wie bin der Multiplizierung. Warum ist das so?</p>
</blockquote>
<p>Die ganzen ineinandergeschachtelten Funktionsaufrufe müssen wieder abgewickelt werden. Jeweils der Rückgabewert der einen Instanz wird weiter zurückgegeben, ohne in diesem Fall noch etwas damit zu machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2064889</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2064889</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Tue, 17 May 2011 19:26:29 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Tue, 17 May 2011 20:09:08 GMT]]></title><description><![CDATA[<p>icarus2 schrieb:</p>
<blockquote>
<p>Ich fürchte ich habe deine Frage nicht ganz verstanden. Ich versuchs jetzt trotzdem mal:</p>
<p>Der ggT ist gemäss dem Algorithmus von Euklid das b im letzen Rekursionsaufruf (du brauchst das return vor dem Selbstaufruf, damit die Rekursion abbricht). Und dieses wird schlussendlich auch zurückgegeben.</p>
<p>Ich denke hier ist etwas falsch:<br />
3+mult(3,3)<br />
3+3+mult(3,2)<br />
3+3+3+mult(3,1) // Hier bricht der Algorithmus bereits ab, weil 3 % 1 == 0, also wird 1 zurückgegeben.<br />
3+3+3+3+mult(3,0) // Wird gar nicht mehr ausgeführt<br />
3+3+3+3+0 <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
</blockquote>
<p>Ja, hast Du. Das Beispiel gehört zur Berechnung des Produkts. Damit wollte ich zeigen, dass ich hier verstanden habe, warum das return dahin gehört.</p>
<p>icarus2 schrieb:</p>
<blockquote>
<p>Es müsste dann übrigens heissen if(tmp == 0)</p>
</blockquote>
<p>peinlich, peinlich! Ich hab es aus Delphi übersetzt und da passiert das schonmal leicht.</p>
<p>Bashar schrieb:</p>
<blockquote>
<p>Die ganzen ineinandergeschachtelten Funktionsaufrufe müssen wieder abgewickelt werden. Jeweils der Rückgabewert der einen Instanz wird weiter zurückgegeben, ohne in diesem Fall noch etwas damit zu machen.</p>
</blockquote>
<p>Aber es gibt doch hier nur einen Rückgabewert, nämlich das letzte &quot;b&quot;.</p>
<p>Danke<br />
lg, freakC++</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2064916</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2064916</guid><dc:creator><![CDATA[freakC++]]></dc:creator><pubDate>Tue, 17 May 2011 20:09:08 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Tue, 17 May 2011 20:17:41 GMT]]></title><description><![CDATA[<p>Es sieht aber intern nicht so aus wie du beschrieben hast.</p>
<p>Ja, es gibt nur den letzen Rückgabewert b. Aber dieser muss durch alle Rekursionsstufen zurückgegeben (hochgereicht) werden.<br />
return ggT(a,tmp); hat immer den Wert b.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2064922</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2064922</guid><dc:creator><![CDATA[icarus2]]></dc:creator><pubDate>Tue, 17 May 2011 20:17:41 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Tue, 17 May 2011 20:45:40 GMT]]></title><description><![CDATA[<p>freakC++ schrieb:</p>
<blockquote>
<p>Aber es gibt doch hier nur einen Rückgabewert, nämlich das letzte &quot;b&quot;.</p>
</blockquote>
<p>Ja, aber dieses ist etwas ganz anderes als das b, was vom Hauptprogramm reingekommen ist - bei jedem Aufruf der Funktion ggT() wird ein weiteres Stück vom Stack reserviert und dort eine eigene Version von a, b und tmp untergebracht (zusammen mit einigen Verwaltungs-Informationen, um beim Funktionsende alles wieder aufräumen zu können) - womöglich auf für eine temporäre Variable, die den Rückgabewert des rekursiven Aufrufs aufnehmen kann. Beim return wird der dort genannte Wert in den Speicherbereich des Aufrufers geschrieben und kann anschließend weiterverarbeitet werden (daß sich diese Weiterverarbeitung hier auf eine Rückgabe beschränkt, hat darauf keinen Einfluß).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2064931</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2064931</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 17 May 2011 20:45:40 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Tue, 17 May 2011 20:51:09 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18082">@freakC</a>++: Bitte schreibe am Ende, wenn das Problem gelöst würde, wer von den Helfern daran den größten Einfluß hatte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2064933</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2064933</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Tue, 17 May 2011 20:51:09 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Tue, 17 May 2011 21:12:53 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18082">@freakC</a>++: Bitte schreibe am Ende, wenn das Problem gelöst würde, wer von den Helfern daran den größten Einfluß hatte.</p>
</blockquote>
<p>Bin ja schon ruhig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2064945</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2064945</guid><dc:creator><![CDATA[icarus2]]></dc:creator><pubDate>Tue, 17 May 2011 21:12:53 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Wed, 18 May 2011 05:51:17 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18082">@freakC</a>++: Bitte schreibe am Ende, wenn das Problem gelöst würde, wer von den Helfern daran den größten Einfluß hatte.</p>
</blockquote>
<p>Ich, da ich als einziger im letzen Thread schon erkannt habe, wo sein Denkfehler ist und ein rekursiver Funktionsaufruf nichts besonderes ist.<br />
Stattdessen wurde sich aber lieber über Kompileroptimierungsmöglichkeiten von Rekursionen unterhalten.<br />
:p</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2064993</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2064993</guid><dc:creator><![CDATA[Jockelx]]></dc:creator><pubDate>Wed, 18 May 2011 05:51:17 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Wed, 18 May 2011 09:39:59 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>Ja, aber dieses ist etwas ganz anderes als das b, was vom Hauptprogramm reingekommen ist - bei jedem Aufruf der Funktion ggT() wird ein weiteres Stück vom Stack reserviert und dort eine eigene Version von a, b und tmp untergebracht (zusammen mit einigen Verwaltungs-Informationen, um beim Funktionsende alles wieder aufräumen zu können) - womöglich auf für eine temporäre Variable, die den Rückgabewert des rekursiven Aufrufs aufnehmen kann. Beim return wird der dort genannte Wert in den Speicherbereich des Aufrufers geschrieben und kann anschließend weiterverarbeitet werden (daß sich diese Weiterverarbeitung hier auf eine Rückgabe beschränkt, hat darauf keinen Einfluß).</p>
</blockquote>
<p>Ahh..danke! Es geht als vor allem um das Aufräumen des Stacks, das ohne das return vor dem Selbstaufruf nicht funktionieren würde. Habe ich das richtig verstanden?</p>
<p>volkard schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18082">@freakC</a>++: Bitte schreibe am Ende, wenn das Problem gelöst würde, wer von den Helfern daran den größten Einfluß hatte.</p>
</blockquote>
<p>Das verstehe ich wiederum nicht. Habe ich was falsch gemacht? Was meinst Du?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2065118</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2065118</guid><dc:creator><![CDATA[freakC++]]></dc:creator><pubDate>Wed, 18 May 2011 09:39:59 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Wed, 18 May 2011 10:24:29 GMT]]></title><description><![CDATA[<p>freakC++ schrieb:</p>
<blockquote>
<p>Ahh..danke! Es geht als vor allem um das Aufräumen des Stacks, das ohne das return vor dem Selbstaufruf nicht funktionieren würde. Habe ich das richtig verstanden?</p>
</blockquote>
<p>Nein, der Stack räumt sich auch ohne return auf. Es geht um das zurückgeben des Wertes.</p>
<p>Stell dir vor, wir implementieren mult nicht-rekursiv, eher pseudo-rekursiv:</p>
<pre><code class="language-cpp">int mult2(int a, int b)
{
  if(b == 0)
    return b;
  throw &quot;maximum recursion depth exceeded&quot;;
} 

int mult1(int a, int b)
{
  if(b == 0)
    return b;
  return a+mult2(a,b-1);
} 

int mult(int a, int b)
{
  if(b == 0)
    return b;
  return a+mult1(a,b-1);
}
</code></pre>
<p>Das funktioniert genauso wie das rekursive mult, nur greift mult auf eine Funktion mult1 zurück, die wiederum auf mult2 zurückgreift. An der Stelle hab ich dann mal abgebrochen, man kann halt nur maximal mit 2 multiplizieren.</p>
<p>Jetzt frag ich dich: Macht es ohne return Sinn?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2065160</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2065160</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Wed, 18 May 2011 10:24:29 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Wed, 18 May 2011 22:32:52 GMT]]></title><description><![CDATA[<p>freakC++ schrieb:</p>
<blockquote>
<p>CStoll schrieb:</p>
<blockquote>
<p>Ja, aber dieses ist etwas ganz anderes als das b, was vom Hauptprogramm reingekommen ist - bei jedem Aufruf der Funktion ggT() wird ein weiteres Stück vom Stack reserviert und dort eine eigene Version von a, b und tmp untergebracht (zusammen mit einigen Verwaltungs-Informationen, um beim Funktionsende alles wieder aufräumen zu können) - womöglich auf für eine temporäre Variable, die den Rückgabewert des rekursiven Aufrufs aufnehmen kann. Beim return wird der dort genannte Wert in den Speicherbereich des Aufrufers geschrieben und kann anschließend weiterverarbeitet werden (daß sich diese Weiterverarbeitung hier auf eine Rückgabe beschränkt, hat darauf keinen Einfluß).</p>
</blockquote>
<p>Ahh..danke! Es geht als vor allem um das Aufräumen des Stacks, das ohne das return vor dem Selbstaufruf nicht funktionieren würde. Habe ich das richtig verstanden?</p>
</blockquote>
<p>Nein, der Compiler wird am Ende der Funktion versuchen, eine eigene return-Anweisung zu ergänzen, um den Programmfluß wieder um Aufrufer zurückzuleiten (die Alternative wäre schmlimmer). Allerdings ist afaik nicht definiert, welche Wert er dann an den Aufrufer zurückgeben wird - dadurch bekommst du dann höchstwahrscheinlich Müll im Hauptprogramm geliefert.<br />
Allerdings sollte dein Compiler dich auch warnen, wenn er zu diesem Schritt gezwungen ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2065579</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2065579</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Wed, 18 May 2011 22:32:52 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Thu, 19 May 2011 12:57:06 GMT]]></title><description><![CDATA[<p>Ich versuchs auch mal zu erklären...</p>
<pre><code class="language-cpp">int Endlos(int a) {
return Endlos(a)
}
</code></pre>
<p>Ich hoffe es ist klar, dass das eine Endlosschleife bildet (die irgendwann absürzt).<br />
Um rauszufinden was er da genau returnen soll, muss er &quot;int Endlos(int a)&quot; auswerten, um das auszuwerten muss er &quot;int Endlos(int a)&quot; auswerten, um das ...</p>
<p>Man braucht also für eine Rekursion immer eine Abbruchbedingung, etwas was sagt &quot;Ich bin hier fertig&quot;, etwas was eben nicht erneut die Funktion aufruft und die Rekursion fortsetzt. Deswegen braucht eine rekursive Funktion prinzipiell immer 2-mal return. Einmal zum weitermachen, und einmal zum aufhören.<br />
Man hört normalerweise auf wenn man sein Ergebnis hat, und das ist in beiden deiner Beispiele &quot;b&quot; - das Ergebnis, das zurückgegeben wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2065811</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2065811</guid><dc:creator><![CDATA[kleiner Troll]]></dc:creator><pubDate>Thu, 19 May 2011 12:57:06 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Thu, 19 May 2011 16:45:28 GMT]]></title><description><![CDATA[<p>kleiner Troll schrieb:</p>
<blockquote>
<p>Ich versuchs auch mal zu erklären...</p>
</blockquote>
<p>Netter Vortrag, aber ein wenig am Thema vorbei. Außerdem ist es weder notwendig noch ausreichend, in einer rekursiven Funktion genau zwei <code>return</code> zu haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2065957</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2065957</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Thu, 19 May 2011 16:45:28 GMT</pubDate></item><item><title><![CDATA[Reply to Rekursionsfrage on Thu, 19 May 2011 19:52:05 GMT]]></title><description><![CDATA[<p>Danke für die Antworten. Ich denke, ich habe es verstanden. Wenn ich das return nicht schreiben würde, dann gäbe es für meisten Aufrufe keinen Rückgabetyp und das wäre gegen den Sinn einer Funktion.</p>
<p>lg, freakC++</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2066055</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2066055</guid><dc:creator><![CDATA[freakC++]]></dc:creator><pubDate>Thu, 19 May 2011 19:52:05 GMT</pubDate></item></channel></rss>