Paradygmaty programowania/Ćwiczenia 4: Podprogramy: Różnice pomiędzy wersjami
(Nie pokazano 7 wersji utworzonych przez 5 użytkowników) | |||
Linia 5: | Linia 5: | ||
Zaimplementuj jeden generator liczb pseudolosowych w „czystym” C, a drugi w C# lub Javie. Jak można wykorzystać charakterystyczne cechy tych języków? | Zaimplementuj jeden generator liczb pseudolosowych w „czystym” C, a drugi w C# lub Javie. Jak można wykorzystać charakterystyczne cechy tych języków? | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed">'''Wskazówka:''' <div class="mw-collapsible-content" style="display:none"> Typowy generator liczb pseudolosowych działa tak: Pierwszy wyraz ciągu, powiedzmy <math>x_{0}</math>, to konkretna stała lub liczba wzięta „z zewnątrz”, np. końcowe, szybkozmieniające się bity zegara systemowego. Każdy następny wyraz ciągu generowany jest na podstawie poprzedniego według zależności <math>x_{i+1} = (ax_{i} + b)</math> | <div class="mw-collapsible mw-made=collapsible mw-collapsed">'''Wskazówka:''' <div class="mw-collapsible-content" style="display:none"> Typowy generator liczb pseudolosowych działa tak: Pierwszy wyraz ciągu, powiedzmy ''<math>x_{0}</math>'', to konkretna stała lub liczba wzięta „z zewnątrz”, np. końcowe, szybkozmieniające się bity zegara systemowego. Każdy następny wyraz ciągu generowany jest na podstawie poprzedniego według zależności ''<math>x_{i+1} = (ax_{i} + b)</math> mod c'', gdzie ''a, b i c'' to odpowiednio dobrane stałe. Generowane są oczywiście liczby całkowite z zakresu od ''0'' do ''c – 1''. | ||
</div> | </div> | ||
</div> | </div> | ||
===Zadanie 3=== | ===Zadanie 3=== | ||
Załóżmy, że mamy kompilator pewnego języka o składni takiej jak C, o którym nie wiemy, czy zmienne lokalne są statyczne czy dynamiczne na stosie. Napisz program, który pozwoli to sprawdzić. | Załóżmy, że mamy kompilator pewnego języka o składni takiej jak C, o którym nie wiemy, czy zmienne lokalne są statyczne, czy dynamiczne na stosie. Napisz program, który pozwoli to sprawdzić. | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed">'''Wskazówka:''' <div class="mw-collapsible-content" style="display:none"> Trzeba sprawdzić, czy wartość zmiennej zachowuje się pomiędzy wywołaniami funkcji. | <div class="mw-collapsible mw-made=collapsible mw-collapsed">'''Wskazówka:''' <div class="mw-collapsible-content" style="display:none"> Trzeba sprawdzić, czy wartość zmiennej zachowuje się pomiędzy wywołaniami funkcji. | ||
</div> | </div> | ||
</div> | </div> | ||
===Zadanie 4=== | ===Zadanie 4=== | ||
Napisz program w dowolnym języku, który pozwoli zaobserwować różnicę w szybkości przekazywania parametrów przez wartość i przez referencję. By zminimalizować wpływ obsługi wywołań na pomiar, przekazuj w obydwu przypadkach możliwie dużą tablicę. | Napisz program w dowolnym języku, który pozwoli zaobserwować różnicę w szybkości przekazywania parametrów przez wartość i przez referencję. By zminimalizować wpływ obsługi wywołań na pomiar, przekazuj w obydwu przypadkach możliwie dużą tablicę. | ||
Linia 30: | Linia 31: | ||
Rozważmy następujący program w Adzie: | Rozważmy następujący program w Adzie: | ||
function f(n: Integer) return Integer is | |||
function g(n: Integer) return Integer is | function g(n: Integer) return Integer is | ||
begin | |||
if n <= 1 then | if n <= 1 then return 1; | ||
else | else return n * f(n - 1); | ||
end if; | |||
end g; | |||
begin | |||
if n <= 1 then | if n <= 1 then return 1; | ||
else | else return n * g(n - 1); | ||
end if; | |||
end f; | |||
Jaka będzie największa długość łańcucha dynamicznego i statycznego, jeśli w wyrażeniu wywołano f(5)? Przedstaw schematycznie zawartość stosu w chwili, gdy zostanie wywołane f(1). | Jaka będzie największa długość łańcucha dynamicznego i statycznego, jeśli w wyrażeniu wywołano f(5)? Przedstaw schematycznie zawartość stosu w chwili, gdy zostanie wywołane f(1). | ||
Linia 50: | Linia 51: | ||
Jak należy zaimplementować instrukcję goto w języku, który pozwala na zagnieżdżanie podprogramów? Chodzi o sytuację, gdy goto powodowałoby „wyskoczenie” z podprogramu np. tak jak na rysunku poniżej (skok w obrębie podprogramu jest bezproblemowy, natomiast skok do wnętrza podprogramu stwarzałby niejasność co do wartości jego zmiennych lokalnych — więc go nie rozważamy). | Jak należy zaimplementować instrukcję goto w języku, który pozwala na zagnieżdżanie podprogramów? Chodzi o sytuację, gdy goto powodowałoby „wyskoczenie” z podprogramu np. tak jak na rysunku poniżej (skok w obrębie podprogramu jest bezproblemowy, natomiast skok do wnętrza podprogramu stwarzałby niejasność co do wartości jego zmiennych lokalnych — więc go nie rozważamy). | ||
procedure P1 | |||
procedure P2 | procedure P2 | ||
begin | |||
... | ... | ||
goto A; | |||
... | ... | ||
end P2; | |||
begin | |||
... | ... | ||
P2; | P2; | ||
Linia 65: | Linia 66: | ||
A: ... | A: ... | ||
... | ... | ||
end P1; | |||
===Zadanie 8=== | ===Zadanie 8=== | ||
Linia 73: | Linia 74: | ||
Co wypisuje poniższy program przy założeniu, że parametry przekazywane są przez wartość? Co, jeśli przez referencję? Co, jeśli przez wartość i wynik? Czy jest tu sytuacja, w której nie da się odpowiedzieć jednoznacznie bez ustalenia szczegółów implementacji? | Co wypisuje poniższy program przy założeniu, że parametry przekazywane są przez wartość? Co, jeśli przez referencję? Co, jeśli przez wartość i wynik? Czy jest tu sytuacja, w której nie da się odpowiedzieć jednoznacznie bez ustalenia szczegółów implementacji? | ||
int a[] = {10, 20}; | |||
int b = 0; | int b = 0; | ||
void f(int x, int y, int z) { | void f(int x, int y, int z) { | ||
b = b+1; | b = b+1; | ||
Linia 83: | Linia 84: | ||
print(a[0], a[1], b, x, y, z); | print(a[0], a[1], b, x, y, z); | ||
} | } | ||
void main() { | void main() { | ||
f(a[b], b, b); | f(a[b], b, b); | ||
print(a[0], a[1], b); | print(a[0], a[1], b); | ||
} | } |
Aktualna wersja na dzień 19:58, 22 wrz 2006
Zadanie 1
Napisz program w dowolnym języku (niekoniecznie prawdziwym), który pokazywałby różnicę między (a) przekazywaniem parametrów przez wartość i wynik a (b) przekazywaniem przez referencję. Chodzi o to, by program wypisywał inny komunikat, jeśli zostanie uruchomiony przy założeniu (a), a inny przy (b).
Zadanie 2
Zaimplementuj jeden generator liczb pseudolosowych w „czystym” C, a drugi w C# lub Javie. Jak można wykorzystać charakterystyczne cechy tych języków?
Zadanie 3
Załóżmy, że mamy kompilator pewnego języka o składni takiej jak C, o którym nie wiemy, czy zmienne lokalne są statyczne, czy dynamiczne na stosie. Napisz program, który pozwoli to sprawdzić.
Zadanie 4
Napisz program w dowolnym języku, który pozwoli zaobserwować różnicę w szybkości przekazywania parametrów przez wartość i przez referencję. By zminimalizować wpływ obsługi wywołań na pomiar, przekazuj w obydwu przypadkach możliwie dużą tablicę.
Zadanie 5
Napisz program w języku, w którym można stosować parametry w „czystym” trybie wyjściowym, tzn. out, a nie in-out. Program ma wykazać, w którym momencie ów parametr jest wiązany z konkretną komórką pamięci — czy w chwili wywołania podprogramu, czy w chwili jego zakończenia, czy może jeszcze kiedy indziej.
Zadanie 6
Rozważmy następujący program w Adzie:
function f(n: Integer) return Integer is function g(n: Integer) return Integer is begin if n <= 1 then return 1; else return n * f(n - 1); end if; end g; begin if n <= 1 then return 1; else return n * g(n - 1); end if; end f;
Jaka będzie największa długość łańcucha dynamicznego i statycznego, jeśli w wyrażeniu wywołano f(5)? Przedstaw schematycznie zawartość stosu w chwili, gdy zostanie wywołane f(1).
Zadanie 7
Jak należy zaimplementować instrukcję goto w języku, który pozwala na zagnieżdżanie podprogramów? Chodzi o sytuację, gdy goto powodowałoby „wyskoczenie” z podprogramu np. tak jak na rysunku poniżej (skok w obrębie podprogramu jest bezproblemowy, natomiast skok do wnętrza podprogramu stwarzałby niejasność co do wartości jego zmiennych lokalnych — więc go nie rozważamy).
procedure P1 procedure P2 begin ... goto A; ... end P2; begin ... P2; ... A: ... ... end P1;
Zadanie 8
Podaj przykłady programów i sekwencji wywołań podprogramów, przy których długość łańcucha dynamicznego będzie mniejsza, równa i większa od długości łańcucha statycznego.
Zadanie 9
Co wypisuje poniższy program przy założeniu, że parametry przekazywane są przez wartość? Co, jeśli przez referencję? Co, jeśli przez wartość i wynik? Czy jest tu sytuacja, w której nie da się odpowiedzieć jednoznacznie bez ustalenia szczegółów implementacji?
int a[] = {10, 20}; int b = 0; void f(int x, int y, int z) { b = b+1; x = x+2; y = y+3; z = z+4; print(a[0], a[1], b, x, y, z); } void main() { f(a[b], b, b); print(a[0], a[1], b); }