W C++ każda zmienna ma z góry ustalony typ, a od typu zależy nie tylko zakres liczb, ale i wynik działania. Najsłynniejsza pułapka to dzielenie: 7 / 2 daje 3, a nie 3,5. Na lekcji uczniowie sprawdzają zachowanie int, double i char, mierzą rozmiary typów i uczą się świadomego rzutowania.
Scenariusz jest przeznaczony na 45 minut dla klasy po lekcji o wczytywaniu danych przez cin. Rozmiary typów (sizeof) zależą od kompilatora; wyniki w lekcji pochodzą z kompilatora g++ 15.2 na komputerze 64-bitowym.
Przygotowanie stanowisk
Potrzebny jest kompilator C++ (na przykład g++ z MinGW-w64, Code::Blocks lub Dev-C++) i edytor tekstu. Rozpakuj pakiet z sekcji materiałów do osobnego folderu. W folderze projektu skompiluj program poleceniem g++ -std=c++17 -Wall start.cpp -o program, a potem uruchom go: ./program (Linux, macOS) albo program.exe (Windows). W środowisku z przyciskiem Build and Run (Code::Blocks) wystarczy otworzyć plik .cpp i je użyć. Rozwiązanie jest w pliku rozwiazanie.cpp, zadanie dla chętnych — w rozszerzenie.cpp.
Cele i plan lekcji
Po zajęciach uczeń potrafi:
- dobrać typ
int,double,char,booldo danych; - przewidzieć wynik dzielenia i reszty z dzielenia dla liczb dodatnich i ujemnych;
- zastosować
static_cast<double>tak, aby dzielenie było dokładne; - odczytać rozmiar typu operatorem
sizeofi zakresintzINT_MAX; - wyjaśnić, że typ bez znaku „zawija się” po przekroczeniu zakresu.
| Czas | Praca na lekcji |
|---|---|
| 0–5 min | Problem: dlaczego 7 / 2 to 3? |
| 5–15 min | Typy podstawowe, dzielenie, rzutowanie |
| 15–22 min | sizeof, zakresy, char jako liczba |
| 22–37 min | Trzy zadania samodzielne |
| 37–42 min | Omówienie wyników |
| 42–45 min | Pytania kontrolne |
Typy podstawowe
int przechowuje liczby całkowite, long long — większe całkowite, double — liczby rzeczywiste, char — pojedynczy znak (w pamięci jest to mała liczba), bool — wartość true albo false. Wybór typu wpływa na wynik: operacja na dwóch liczbach całkowitych daje liczbę całkowitą.
Dzielenie
Dla int operator / odrzuca część ułamkową (7 / 2 to 3), a % zwraca resztę (7 % 2 to 1). Dla liczb ujemnych C++ obcina wynik w stronę zera: -7 / 2 to -3, a -7 % 2 to -1. Aby dostać wynik dokładny, przynajmniej jeden argument musi być typu double (7 / 2.0) albo trzeba go rzutować: static_cast<double>(7) / 2.
Konwersje i zakresy
Przypisanie liczby rzeczywistej do int obcina część ułamkową (int a = 3.99; daje 3). Zapis double b = 7 / 2; najpierw wykonuje dzielenie całkowite, więc b ma wartość 3. Typ bez znaku (unsigned char, zakres 0–255) po przekroczeniu zakresu zaczyna od zera. Liczby rzeczywiste są zapisywane binarnie, więc 0.1 + 0.2 nie jest dokładnie 0,3 — widać to dopiero po zwiększeniu precyzji wypisywania.
Zadania
Zadanie 1. Dzielenie i reszta. Wypisz 7 / 2, 7 % 2, 7 / 2.0 oraz -7 / 2 i -7 % 2.
Zadanie 2. Konwersje. Sprawdź, co zostanie zapisane w int a = 3.99;, double b = 7 / 2; i double c = static_cast<double>(7) / 2;. Oblicz średnią całkowitą i dokładną z 17 punktów na 5 osób.
Zadanie 3. Rozmiary i zakresy. Wypisz sizeof typów char, int, long long, double, wartość INT_MAX, wynik zwiększenia unsigned char o 1 po wartości 255 oraz sumę 0.1 + 0.2 z domyślną precyzją i z setprecision(17). Dodaj 1 do znaku wielkiej litery A (znak char w apostrofach) i wypisz wynik jako liczbę oraz po rzutowaniu na char.
Dla chętnych: przelicz 36,6 °C na °F oraz 135 minut na godziny i minuty (plik rozszerzenie.cpp).
Rozwiązanie i wyniki
#include <iostream>
#include <climits>
#include <iomanip>
using namespace std;
int main() {
// Zadanie 1
cout << 7 / 2 << " " << 7 % 2 << " " << 7 / 2.0 << endl;
cout << -7 / 2 << " " << -7 % 2 << endl;
// Zadanie 2
int a = 3.99;
double b = 7 / 2;
double c = static_cast<double>(7) / 2;
cout << a << " " << b << " " << c << endl;
int ile = 17;
int osob = 5;
cout << "srednia calkowita: " << ile / osob << endl;
cout << "srednia dokladna: " << static_cast<double>(ile) / osob << endl;
// Zadanie 3
cout << sizeof(char) << " " << sizeof(int) << " " << sizeof(long long) << " " << sizeof(double) << endl;
cout << INT_MAX << endl;
unsigned char znak = 255;
znak = znak + 1;
cout << static_cast<int>(znak) << endl;
cout << 0.1 + 0.2 << " " << setprecision(17) << 0.1 + 0.2 << endl;
cout << 'A' + 1 << " " << static_cast<char>('A' + 1) << endl;
return 0;
}
Program wypisze:
3 1 3.5
-3 -1
3 3 3.5
srednia calkowita: 3
srednia dokladna: 3.4
1 4 8 8
2147483647
0
0.3 0.30000000000000004
66 B
Zadanie dla chętnych (rozszerzenie.cpp):
#include <iostream>
using namespace std;
int main() {
double celsjusz = 36.6;
double fahrenheit = celsjusz * 9 / 5 + 32;
cout << celsjusz << " C = " << fahrenheit << " F" << endl;
int minuty = 135;
cout << minuty / 60 << " h " << minuty % 60 << " min" << endl;
return 0;
}
Wynik:
36.6 C = 97.88 F
2 h 15 min
Programy kompilowano kompilatorem g++ 15.2 z opcjami -std=c++17 -Wall -Wextra, bez ostrzeżeń.
Typowe błędy
| Objaw | Co sprawdzić |
|---|---|
7 / 2 daje 3 | Oba argumenty są całkowite; użyj 7 / 2.0 lub static_cast<double>. |
double b = 7 / 2; daje 3, a nie 3,5 | Dzielenie wykonuje się przed przypisaniem, więc jest całkowite. |
Ostrzeżenie o konwersji przy int a = 3.99; | Przypisanie liczby rzeczywistej do int obcina ułamek; zrób to świadomie przez static_cast<int>. |
Zmiana znaku wyniku % dla liczb ujemnych | Reszta ma znak dzielnej (-7 % 2 to -1). |
0.1 + 0.2 pokazuje 0.3, ale == 0.3 nie działa | Porównuj liczby rzeczywiste z tolerancją, nie przez ==. |
Zakres int przekroczony | Dla typów ze znakiem wynik jest nieokreślony; użyj większego typu, np. long long. |
Pytania kontrolne i punktacja
- Ile wynosi
7 / 2, a ile7 / 2.0? - Co zrobi
int a = 3.99;? - Dlaczego
0.1 + 0.2nie jest dokładnie 0,3?
Odpowiedzi: Odpowiednio 3 i 3,5. Zapisze liczbę 3 (obcina część ułamkową). Bo liczby rzeczywiste zapisujemy binarnie, a ułamek 0,1 nie ma w systemie dwójkowym skończonego rozwinięcia.
Proponowana punktacja (razem 10 punktów): zadanie 1 — pięć wartości 2 pkt, wyjaśnienie ujemnych 1 pkt; zadanie 2 — trzy konwersje 2 pkt, dwie średnie 1 pkt; zadanie 3 — sizeof i INT_MAX 1 pkt, zawijanie 1 pkt, precyzja 1 pkt; pytania kontrolne 1 pkt. Zadanie dla chętnych nie jest wymagane do pełnej oceny.
Materiały do pobrania
Rozpakuj ZIP przed otwarciem plików. Materiały są dostępne bez logowania; publiczne rozwiązanie służy nauce i samodzielnemu sprawdzeniu, a nie poufnemu sprawdzianowi.
Co dalej?
Następny krok to instrukcje warunkowe. Ten materiał rozwija dział o podstawach programowania w kursie C++ w TablicaPro, gdzie znajdziesz prezentacje, ćwiczenia i testy do prowadzenia lekcji.
Źródła techniczne: cplusplus.com: Data types oraz static_cast w cppreference.com. Zobacz też pierwszą lekcję C++.
Poprowadź kolejne lekcje C++
Pełny kurs: prezentacje, ćwiczenia i testy do pracy z klasą.
Kup dostęp do kursu C++ →