|
|
Linia 88: |
Linia 88: |
| print(a[0], a[1], b); | | print(a[0], a[1], b); |
| }'' | | }'' |
|
| |
| ==Test==
| |
|
| |
| <quiz type="exclusive">
| |
| Który język nie pozwala na użycie parametrów z wartością domyślną?
| |
| <wrongoption reply="Źle">Ada</wrongoption>
| |
| <rightoption reply="Dobrze">C</rightoption>
| |
| <wrongoption reply="Źle">C++</wrongoption>
| |
| <wrongoption reply="Źle">PHP</wrongoption>
| |
| </quiz>
| |
|
| |
| <quiz type="exclusive">
| |
| Przekazanie funkcji jako parametru można w C\# osiągnąć za pomocą mechanizmu:
| |
| <wrongoption reply="Źle">bezpośrednio, bez dodatkowych mechanizmów</wrongoption>
| |
| <rightoption reply="Dobrze">delegatów</rightoption>
| |
| <wrongoption reply="Źle">tablic wielowymiarowych</wrongoption>
| |
| <wrongoption reply="Źle">wskaźników do funkcji</wrongoption>
| |
| </quiz>
| |
|
| |
| <quiz type="exclusive">
| |
| Który język nie sprawdza zgodności typów parametrów?
| |
| <wrongoption reply="Źle">Ada</wrongoption>
| |
| <wrongoption reply="Źle">C#</wrongoption>
| |
| <wrongoption reply="Źle">Java</wrongoption>
| |
| <rightoption reply="Dobrze">PHP</rightoption>
| |
| </quiz>
| |
|
| |
| <quiz type="exclusive">
| |
| Przy której deklaracji procedury f wywołanie f(2*x + 3) jest poprawne?
| |
| <wrongoption reply="Źle">procedure f(n: in out Integer) w Adzie</wrongoption>
| |
| <wrongoption reply="Źle">procedure f(n: out Integer) w Adzie</wrongoption>
| |
| <rightoption reply="Dobrze">void f(int n) w języku C</rightoption>
| |
| <wrongoption reply="Źle">void f(int *n) w języku C</wrongoption>
| |
| </quiz>
| |
|
| |
| <quiz type="exclusive">
| |
| Chcąc w języku C przekazać do funkcji tablicę przez wartość, trzeba:
| |
| <rightoption reply="Dobrze">,,obudować'' ją strukturą i przekazać tę strukturę</rightoption>
| |
| <wrongoption reply="Źle">użyć nawiasów kwadratowych po nazwie tablicy w wywołaniu funkcji</wrongoption>
| |
| <wrongoption reply="Źle">użyć nawiasów kwadratowych po nazwie parametru w nagłówku funkcji</wrongoption>
| |
| <wrongoption reply="Źle">nie trzeba robić niczego szczególnego</wrongoption>
| |
| </quiz>
| |
|
| |
| <quiz type="exclusive">
| |
| Jaką dodatkową cechę mają parametry stałe deklarowane w C++
| |
| z użyciem const w stosunku do parametrów w trybie wejściowym w ogóle?
| |
| <rightoption reply="Dobrze">nie mogą być zmieniane nawet w obrębie podprogramu</rightoption>
| |
| <wrongoption reply="Źle">są zawsze alokowane statycznie</wrongoption>
| |
| <wrongoption reply="Źle">wymuszają statyczne sprawdzenie zgodności typu</wrongoption>
| |
| <wrongoption reply="Źle">nie mają żadnej dodatkowej cechy</wrongoption>
| |
| </quiz>
| |
|
| |
|
| |
| <quiz type="exclusive">
| |
| Załóżmy, że x jest parametrem w trybie out w procedurze w Adzie.
| |
| Która instrukcja ma szansę być poprawna?
| |
| <wrongoption reply="Źle">x \:\= x + 1</wrongoption>
| |
| <rightoption reply="Dobrze">x \:\= y + 1</rightoption>
| |
| <wrongoption reply="Źle">y \:\= x + 1</wrongoption>
| |
| <wrongoption reply="Źle">y \:\= T(x)</wrongoption>
| |
| </quiz>
| |
|
| |
| <quiz type="exclusive">
| |
| Jawne przekazywanie przez referencję jest w C\# możliwe, jeśli
| |
| umieścimy słowo kluczowe ref:
| |
| <wrongoption reply="Źle">przy parametrze aktualnym</wrongoption>
| |
| <wrongoption reply="Źle">przy parametrze formalnym</wrongoption>
| |
| <rightoption reply="Dobrze">i przy parametrze formalnym, i przy aktualnym</rightoption>
| |
| <wrongoption reply="Źle">to w ogóle nie jest możliwe</wrongoption>
| |
| </quiz>
| |
|
| |
| <quiz type="exclusive">
| |
| W językach z zakresem widoczności zmiennych wiązanym statycznie
| |
| jako środowiska wykonywania przekazanego przez parametr podprogramu najczęściej używa się:
| |
| <wrongoption reply="Źle">środowiska instrukcji (w podprogramie), wywołującej przekazany podprogram</wrongoption>
| |
| <rightoption reply="Dobrze">środowiska definicji przekazanego podprogramu</rightoption>
| |
| <wrongoption reply="Źle">środowiska instrukcji, która przekazała podprogram jako parametr</wrongoption>
| |
| <wrongoption reply="Źle">żadnego z wymienioinych środowisk</wrongoption>
| |
| </quiz>
| |
|
| |
| <quiz type="exclusive">
| |
| W implementacji podprogramów bez zagnieżdżeń, ale z rekurencją
| |
| i z dynamicznymi zmiennymi lokalnymi na stosie potrzebne jest przechowywanie w rekordzie aktywacyjnym:
| |
| <rightoption reply="Dobrze">tylko łącza dynamicznego</rightoption>
| |
| <wrongoption reply="Źle">tylko łącza statycznego</wrongoption>
| |
| <wrongoption reply="Źle">łącza dynamicznego i statycznego</wrongoption>
| |
| <wrongoption reply="Źle">żadnego z nich</wrongoption>
| |
|
| |
| </quiz>
| |
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?
Wskazówka: Typowy generator liczb pseudolosowych działa tak: Pierwszy wyraz ciągu, powiedzmy , 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 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.
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ć.
Wskazówka: Trzeba sprawdzić, czy wartość zmiennej zachowuje się pomiędzy wywołaniami funkcji.
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ę.
Wskazówka: Pamiętaj, że w C i językach pochodnych nie da się przekazać tablicy przez wartość bez użycia pewnej „sztuczki”. Pamiętaj też, że przekazywanie tablicy po elemencie (podobnie jak wielokrotne przekazywanie jednej zmiennej np. całkowitej) da zupełnie inny rezultat.
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.
Wskazówka: Rozważ przekazanie parametru będącego odwołaniem do elementu tablicy.
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);
}