KWALIFIKACJA INF2 + INF3 - STYCZEŃ 2013

PYTANIE NR 25.
Wskaż wyrażenie w języku C++ które generuje liczbę naturalną z zakresu [0;a].
A.
B.
C.
D.
Wyjaśnienie poprawnej odpowiedzi:
Wyrażenie rand() % (a + 1) zwraca resztę z dzielenia przez (a+1), więc możliwe wyniki to wszystkie liczby od 0 do a włącznie. Dodanie "a + …" przesuwa zakres do [a, 2a] lub [a, 2a−1], a użycie "% a" daje tylko [0, a−1], czyli bez wartości a.

Pełne wyjaśnienie:

Funkcja rand() w C++ zwraca pseudolosową liczbę całkowitą z przedziału [0, RAND_MAX]. Aby "ściąć" ten duży zakres do żądanego, często stosuje się operator % (modulo), który zwraca resztę z dzielenia.

Dla dzielnika (a+1) możliwe reszty to zawsze wartości od 0 do a włącznie. Dlatego wyrażenie rand() % (a + 1) generuje liczbę naturalną dokładnie z zakresu [0, a] (przedział domknięty, zawiera oba końce).

Pozostałe odpowiedzi są błędne z powodu nieprawidłowego zakresu:

  • a + rand() % (a + 1) – część z modulo daje 0..a, ale dodanie a przesuwa wyniki na [a, 2a], więc nie ma wartości mniejszych niż a.
  • a + rand() % a – modulo a daje 0..a−1 (dla a>0), a po dodaniu a otrzymujemy [a, 2a−1], nadal bez 0..a−1.
  • rand() % a – daje [0, a−1], czyli brakuje wartości a, wymaganej przez zapis [0,a].

Wskazówka egzaminacyjna: jeśli w treści jest zakres "do a włącznie", w wyrażeniu z modulo zwykle pojawia się (a+1). Dodatkowo w praktyce dla zmiennych sekwencji losowej często inicjalizuje się generator (np. przez srand), a w nowoczesnym C++ preferuje się bibliotekę <random>, ale to nie zmienia poprawności samego mapowania przez modulo.

Dodatkowe pytania

Dodatkowe pytania (FAQ):
Zwraca ono resztę z dzielenia wyniku rand() przez (a+1). Ponieważ reszta może mieć tylko wartości od 0 do a, otrzymujesz liczbę z przedziału [0, a] (włącznie z 0 i a).
Bo zapis [0, a] zawiera także wartość a. Gdy użyjesz % a, możliwe wyniki to tylko 0..a−1, więc a nigdy nie wystąpi. Dopiero dzielnik (a+1) daje reszty 0..a.
Nie. Dla a>0 wyrażenie rand() % a zwraca wartości 0..a−1, czyli zakres półotwarty. Jeśli w zadaniu wymagany jest zakres domknięty [0, a], to ta wersja jest za wąska.
Dodanie a przesuwa wszystkie wyniki w górę o a. Jeśli część losowa daje 0..a, to po dodaniu a otrzymasz a..2a. To nie jest już zakres zaczynający się od 0, więc nie spełnia warunku [0, a].
Gdy (a+1) nie dzieli równo liczby możliwych wartości generatora (zależnej od RAND_MAX). Wtedy niektóre reszty mogą pojawiać się minimalnie częściej. Na egzaminie zwykle liczy się poprawny zakres, a nie idealna równomierność.
Zwykle inicjalizuje się generator przez wywołanie srand z innym ziarnem, np. zależnym od czasu. Bez tego wiele implementacji startuje od tego samego ziarna, więc sekwencja "losowa" powtarza się między uruchomieniami.
Najprościej przesunąć wynik o 1: 1 + rand() % a (dla a>0). Wtedy możliwe wartości to 1..a. To inne wymaganie niż [0,a], więc w zadaniach trzeba uważnie czytać, czy 0 ma być dopuszczalne.
W praktyce częściej używa się biblioteki <random>, np. silników typu mt19937 oraz rozkładów (np. uniform_int_distribution). Daje to lepszą jakość losowania i wygodniejsze ustawianie zakresu bez problemów z modulo.
Najczęstsze pomyłki to: użycie % a (brak wartości a), dodanie a + (przesunięcie zakresu), oraz mylenie zapisu [0,a] z [0,a). Warto zawsze wypisać skrajne możliwe wyniki.
Tak. Gdy a=0, dzielnik wynosi (0+1)=1, więc wynik to zawsze 0, co nadal spełnia zakres [0,0]. Problem dzielenia przez 0 pojawiłby się przy rand() % a dla a=0.
info

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

Według specjalistów z branży: "Wyrażenie rand() % (a + 1) zwraca resztę z dzielenia przez (a+1), więc możliwe wyniki to wszystkie liczby od 0 do a włącznie."

Źródła:

  • cppreference.com: "rand" (C++), https://en.cppreference.com/w/cpp/numeric/random/rand - accessed 2026-02-27
  • cppreference.com: "Operator%" / "Arithmetic operators" (C++), https://en.cppreference.com/w/cpp/language/operator_arithmetic - accessed 2026-02-27
  • cplusplus.com: "rand" (reference), https://cplusplus.com/reference/cstdlib/rand/ - accessed 2026-02-27

Materiały:

  • Dokumentacja C++ (rand, srand) w serwisie cppreference
  • Materiały o operatorach w C++ (w tym %)
  • Wprowadzenie do nowoczesnych generatorów z biblioteki <random>

Aktualizacja pytania: 31.03.2026



Aktualizacja pytania: 31.03.2026
📡 Brak połączenia internetowego