Bilder Kapitel 9.doc

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)