KWALIFIKACJA INF2 + INF3 - CZERWIEC 2006

PYTANIE NR 26.
Co zostanie wypisane na ekranie po wykonaniu poniższej procedury w języku Pascal?
procedure drukuj(n:integer);
begin
if n > 0 then
begin
writeln(n);
drukuj(n-1);
end;
end;
drukuj(3);
A.
B.
C.
D.
Wyjaśnienie poprawnej odpowiedzi:
Rekurencja działa tak, że dla n>0 najpierw wykonywane jest writeln(n), a dopiero potem wywołanie drukuj(n-1). Startując od 3, program wypisze 3, następnie 2 i 1. Dla n=0 warunek jest fałszywy, więc rekurencja się kończy bez wypisania.

Pełne wyjaśnienie:

Procedura drukuj(n) jest przykładem rekurencji liniowej: wywołuje samą siebie z argumentem n-1. Kluczowe są dwa elementy: warunek stopu oraz kolejność instrukcji w bloku.

Najpierw sprawdzany jest warunek n>0. Jeśli jest spełniony, wykonywany jest blok begin...end. W tym bloku kolejno dzieją się dwie rzeczy:

  • writeln(n) – wypisuje bieżącą wartość i przechodzi do nowej linii,
  • drukuj(n-1) – wywołuje procedurę ponownie z mniejszym argumentem.

Dla wywołania drukuj(3) przebieg jest deterministyczny: wypisuje 3, potem wywołuje drukuj(2), które wypisuje 2 i wywołuje drukuj(1), które wypisuje 1 i wywołuje drukuj(0). Gdy n=0, warunek n>0 jest fałszywy, więc nie wykonuje się ani writeln, ani kolejne wywołanie – to kończy rekurencję.

Dlatego poprawny wynik to 3, 2, 1, każda liczba w osobnej linii. Odpowiedź z kolejnością rosnącą (1, 2, 3) byłaby prawdziwa, gdyby writeln znajdowało się po wywołaniu rekurencyjnym (czyli wypisywanie następowałoby podczas "powrotu" ze stosu). Odpowiedzi "tylko 3" oraz "tylko 0" pomijają fakt, że rekurencja schodzi przez 2 i 1, a dla 0 blok nie wykona się w ogóle.

Dodatkowe pytania

Dodatkowe pytania (FAQ):
Rekurencja to technika, w której procedura lub funkcja wywołuje samą siebie z innym argumentem. Używa się jej m.in. do przetwarzania struktur drzewiastych, algorytmów dziel i zwyciężaj oraz zadań, które naturalnie dzielą się na mniejsze podproblemy. Kluczowy jest warunek stopu.
Bo writeln(n) jest wykonane przed wywołaniem drukuj(n-1). Program wypisuje bieżące n, a dopiero potem "schodzi" głębiej w rekurencję. Gdyby wypisanie było po wywołaniu, liczby pojawiłyby się przy "powrocie" ze stosu, czyli rosnąco.
Warunek stopu to sprawdzenie, które przerywa dalsze wywołania, aby uniknąć nieskończonej rekurencji. Tutaj jest to n>0. Gdy n osiągnie 0, blok nie zostanie wykonany, więc nie będzie kolejnego wywołania i rekurencja zakończy się poprawnie.
Nie. Dla n=0 warunek n>0 jest fałszywy, więc instrukcja writeln(n) nie zostanie wykonana. To typowy wzorzec: przypadek bazowy (tu: n nie większe od 0) kończy rekurencję bez wykonywania operacji w środku bloku.
Kolejne wywołania tworzą łańcuch: drukuj(3) → drukuj(2) → drukuj(1) → drukuj(0). W każdym kroku (dla n>0) najpierw następuje wypisanie, potem zejście głębiej. Gdy osiągnie się 0, dalszych ramek stosu już nie przybywa i następuje powrót.
writeln wypisuje wartość i dopisuje znak nowej linii, więc każda liczba pojawi się w osobnym wierszu. write wypisuje bez przejścia do nowej linii, więc liczby mogłyby pojawić się w jednym wierszu (np. bez odstępów lub z odstępami zależnie od kodu).
To zależy od miejsca operacji względem wywołania rekurencyjnego. Jeśli wypisanie jest przed rekurencją, wynik zwykle idzie "w dół" (malejąco). Jeśli wypisanie jest po rekurencji, wartości pojawiają się przy "powrocie" (rosnąco). To analogia do pre-order i post-order.
Tak, jeśli argument początkowy jest bardzo duży lub jeśli brakuje poprawnego warunku stopu. Każde wywołanie rekurencyjne zajmuje miejsce na stosie. W tym przykładzie warunek stopu istnieje, ale dla ekstremalnie dużych n liczba ramek może przekroczyć limit środowiska uruchomieniowego.
Najprościej rozpisać kilka pierwszych wywołań jako łańcuch (np. n=3,2,1,0) i zaznaczyć, co dzieje się przed i po wywołaniu rekurencyjnym. Pomaga reguła: operacje przed rekurencją wykonują się przy "schodzeniu", a po rekurencji – przy "powrocie".
Trzeba przenieść wypisanie writeln(n) za wywołanie rekurencyjne, czyli najpierw zrobić drukuj(n-1), a dopiero potem wypisać n. Wtedy wartości pojawią się podczas "odwijania" rekurencji. Warunek stopu n>0 może pozostać bez zmian.
info

Statystycznie 58% uczniów zna prawidłową odpowiedź. średnie

Według specjalistów z branży: "Rekurencja działa tak, że dla n>0 najpierw wykonywane jest writeln(n), a dopiero potem wywołanie drukuj(n-1)."

Źródła:

  • Free Pascal Reference Guide: Procedures and functions (procedures), https://www.freepascal.org/docs-html/ref/refsu4.html (dostęp: 2026-03-05)
  • Free Pascal Reference Guide: if statement, https://www.freepascal.org/docs-html/ref/refsu57.html (dostęp: 2026-03-05)
  • Free Pascal Reference Guide: Write/Writeln procedures, https://www.freepascal.org/docs-html/rtl/system/write.html (dostęp: 2026-03-05)

Materiały:

  • Dokumentacja Free Pascal: rozdziały o procedurach, instrukcji if i rekursji
  • Podręczniki do nauki Pascala: podstawy rekurencji i stosu wywołań
  • Ćwiczenia: przepisanie przykładu z writeln przed i po wywołaniu rekurencyjnym i porównanie wyników

Aktualizacja pytania: 31.03.2026



Aktualizacja pytania: 31.03.2026
📡 Brak połączenia internetowego