Bild 9-1 Ein Block ist eine Sequenz von Anweisungen { .... { .... } .... Innerer Block Äußerer Block } Bild 9-2 Schachtelung von Blöcken a) b) x #include <stdio.h> #include <stdio.h> int main (void) { int main (void) { } int x; } int x; alpha void sub1 (void) { int alpha = 4; x alpha x void sub1 (void) { int x; .... x .... } } void sub2 (void) { ... } Bild 9-3 x x void sub2 (void) { ... } x Sichtbarkeit und Lebensdauer (grauer Balken: Lebensdauer, weißer Balken: Sichtbarkeit) Rekursion 3 2 * 1 wird zurückgegeben Rekursion 2 1 wird zurückgegeben Rekursion 1 3 * 2 wird zurückgegeben Fakultät von 3 rekursiv berechnen: main () { .... z = faku (3); printf ("....", z); .... } long faku (n) { .... if (n > 1) { return n * faku (n-1); } return 1; } long faku (n) { .... if (n > 1) { return n * faku (n-1); } return 1; } long faku (n) { .... if (n > 1) { return n * faku (n-1); } return 1; } Bild 9-4 Verfolgung der rekursiven Aufrufe für faku(3) Aufruf von faku mit Parameter 3 n hat den Wert 3 wahr Aufruf von faku mit Parameter 2 n hat den Wert 2 wahr Aufruf von faku mit Parameter 1 n hat den Wert 1 falsch main() Stack Variable n = 3 Variable z Aufruf faku(3) von main() Stack Variable n Variable z Rücksprungadresse in main() und weitere Verwaltungsinformationen... Parameter n = 3 Aufbau des Stacks für faku (3): Bei jedem Aufruf von faku() werden die Rücksprungadresse und weitere Verwaltungsinformationen auf einem Stack abgelegt, der durch das Laufzeitsystem verwaltet wird. Auch die übergebenen Parameter (hier nur einer) werden auf diesem Stack abgelegt. Dabei wächst der Stack mit der Rekursionstiefe der Funktion. Der letzte Aufruf von faku() mit dem Parameter n = 1 bewirkt keine weitere Rekursion, da ja die Abbruchbedingung erfüllt ist. Der Abbau des Stacks geschieht in umgekehrter Reihenfolge, wie aus dem folgenden Bild ersichtlich wird. Aufruf faku(2) von faku(3) Stack Variable n Variable z Rücksprungadresse in main() und ..... Parameter n = 3 Rücksprungadresse in faku(3) und ...... Parameter n = 2 Aufruf faku(1) von faku(2) Stack Variable n Variable z Rücksprungadresse in main() und ..... Parameter n = 3 Rücksprungadresse in faku(3) und ...... Parameter n = 2 Rücksprungadresse in faku(2) und ...... Parameter n = 1 Bild Error! No text of specified style in document.-1 Aufbau des Stacks für faku (3) faku(1) beendet sich mit return 1 Stack Variable n Variable z Rücksprungadresse in main() und ..... Parameter n = 3 Rücksprungadresse in faku(3) und ...... Parameter n = 2 Rücksprungadresse in faku(2) und ...... Parameter n = 1 Abbau des Stacks für faku (3): Beim Beenden der aufgerufenen Funktion werden auf dem Stack die lokalen Variablen (übergebene Parameter) freigegeben und die Rücksprungadresse und sonstigen Verwaltungsinformationen abgeholt. Der Rückgabewert wird in diesem Beispiel über ein Register an die aufrufenden Funktionen zurückgegeben. Der Rückgabewert kann auf verschiedene Weise an die aufrufende Funktion zurückgegeben werden, beispielsweise auch über den Stack. Dies ist vom Compiler abhängig. Übergabe des Rückgabewertes über Register faku(2) beendet sich mit return 2 Stack Variable n Variable z Rücksprungadresse in main() und ..... Parameter n = 3 Rücksprungadresse in faku(3) und ...... Parameter n = 2 Übergabe des Rückgabewertes über Register faku(3) beendet sich mit return 6 Stack Variable n Variable z Rücksprungadresse in main() und weitere Verwaltungsinformationen... Parameter n = 3 Übergabe des Rückgabewertes über Register main() Stack Variable n = 3 Variable z = 6 Bild Error! No text of specified style in document.-2 Abbau des Stacks für faku (3)
© Copyright 2025 Paperzz