Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autor: Piotr Szawdyński
Kurs C++

Operacje matematyczne

[lekcja] Rozdział 10. Podstawowe operatory matematyczne, inkrementacja i dekrementacja oraz sposoby zapisywania działań matematycznych.
Zanim przejdziemy do właściwej części rozdziału zastanówmy się przez chwilę czym jest komputer. Komputer w dzisiejszych czasach stał się nieodłączną częścią życia każdego z nas. Z praktycznego punktu widzenia hasło to samo w sobie jest dla nas czymś w rodzaju słowa kluczowego, pod którym kryje się system operacyjny, programy i gry. W rzeczywistości komputer jest jednak maszyną służącą do obliczeń. Wszystkie aplikacje, które uruchamiamy na komputerze wykonują obliczenia. Nawet podczas pisania tekstu w notatniku wykonywane są stale obliczenia, a skoro tak to C++ również powinien umożliwić nam liczenie i tak właśnie jest.

Operatory matematyczne

Operatorami matematycznymi nazywamy te znaki, które wykonują jakieś działanie matematyczne. W C++ są to: +, -, *, / i %. Wszystkie operatory powinieneś znać ze szkoły oprócz ostatniego, tj. % dzięki któremu otrzymujemy resztę z dzielenia liczb całkowitych.

Kolejność wykonywania działań

Kolejność wykonywania działań jest taka sama jak uczyłeś się w szkole podstawowej na matematyce. Najpierw mnożymy i dzielimy, a następnie dodajemy i odejmujemy. Jeśli chcemy zmienić kolejność wykonywania operacji, musimy wykorzystać nawiasy zaokrąglone. Oto przykład wykorzystujący powyższy fakt:
C/C++
#include <iostream>
int main()
{
    std::cout << "Obliczam: 3+2*4=" << 3 + 2 * 4 << std::endl;
    std::cout << "Obliczam: (3+2)*4=" <<( 3 + 2 ) * 4 << std::endl;
    return 0;
}
Wynik działania programu będzie wyglądał tak:
Obliczam: 3+2*4=11
Obliczam: (3+2)*4=20

Obliczenia z wykorzystaniem zmiennych

Jeśli mamy potrzebę wykonać obliczenia na wartościach znajdujących się w zmiennych, możemy również to robić. Wykonuje się to w taki sam sposób, jakby to była liczba. Tłumaczenie tutaj na niewiele się zda, więc przejdźmy do przykładu:
C/C++
#include <iostream>
int main()
{
    std::cout << "Podaj liczbe: ";
    int zmienna;
    std::cin >> zmienna;
    std::cout << "Obliczam: 3+zmienna*4=" << 3 + zmienna * 4 << std::endl;
    std::cout << "Obliczam: (3+zmienna)*4=" <<( 3 + zmienna ) * 4 << std::endl;
    return 0;
}
Wynik działania programu:
Podaj liczbe: 10
Obliczam: 3+zmienna*4=43
Obliczam: (3+zmienna)*4=52

Zapisywanie obliczeń do zmiennych

Obliczenia, które wykonujemy można zapisywać również do zmiennych. Wykorzystuje się do tego celu operator przypisania, który poznałeś już w jednym ze wcześniejszych rozdziałów. Przytoczmy jednak przykład demonstrujący jego użycie:
C/C++
#include <iostream>
int main()
{
    std::cout << "Podaj liczbe: ";
    int zmienna;
    std::cin >> zmienna;
    int wynik1 = 3 + zmienna * 4;
    int wynik2 =( 3 + zmienna ) * 4;
    std::cout << "Wynik pierwszy: " << wynik1 << std::endl;
    std::cout << "Wynik drugi: " << wynik2 << std::endl;
    return 0;
}
Wynik działania powyższego programu:
Podaj liczbe: 7
Wynik pierwszy: 31
Wynik drugi: 40

Pamiętajmy o konsekwencjach dzielenia

Wykonując różne operacje matematyczne, najgroźniejszą operacją dla naszego programu jest dzielenie. Może ona bowiem spowodować zamknięcie krytyczne aplikacji. Pamiętajmy jednak, że samo z siebie nic nie przestanie działać. W matematyce nie można jednak dzielić przez zero i właśnie ta wartość w mianowniku jest niepożądana. Na chwilę obecną miej świadomość, że taki problem istnieje. W jednym z późniejszych rozdziałów dowiesz się jak temu się zapobiega.

Warto też tutaj wspomnieć, że to samo dotyczy obliczania reszty z dzielenia i program również odmówi nam posłuszeństwa w przypadku, gdy wartość po znaku % będzie równa 0.

Reszta z dzielenia, a liczby rzeczywiste

Załóżmy, że napiszemy program, który będzie miał pokazywać resztę z dzielenia dwóch liczb. Program ten będzie wyglądał następująco:
C/C++
#include <iostream>

int main( void )
{
    double a;
    std::cout << "Podaj a: ";
    std::cin >> a;
   
    double b;
    std::cout << "Podaj b: ";
    std::cin >> b;
   
    std::cout << "a % b = " << a % b << std::endl;
    return 0;
}
Próba kompilacji tego programu się nie powiedzie i otrzymamy następujący błąd:
error: invalid operands of types 'double' and 'double' to binary 'operator%'
Błąd ten wynika z faktu, że operację modulo możemy wykonywać tylko i wyłącznie na liczbach całkowitych. Naprawienie tego programu wymaga albo zmiany typów zmiennych z liczb rzeczywistych na całkowite albo wykonania rzutowania typów, którego jeszcze nie znasz. Poprawnie napisany program będzie więc wyglądał następująco:
C/C++
#include <iostream>

int main( void )
{
    int a;
    std::cout << "Podaj a: ";
    std::cin >> a;
   
    int b;
    std::cout << "Podaj b: ";
    std::cin >> b;
   
    std::cout << "a % b = " << a % b << std::endl;
    return 0;
}

Jak poprawić czytelność kodu

Ponieważ operacje arytmetyczne są działaniami, które najczęściej są używane w programie, na przestrzeni wielu lat powstało kilka ułatwień do wykonywania operacji matematycznych. Pierwszym z nich jest wykonywanie działań już na obecnej wartości zmiennej. Załóżmy, że mamy zmienną x, której wartość początkowa wynosi 5. Następnie chcemy, aby w tej samej zmiennej znalazła się nowa wartość, np. 2 razy większa. Mając wiedzę obecną mogli byśmy zrobić to np. tak:
C/C++
int x = 5;
int tmp = x * 2; //x*2 = 10
x = tmp; //tmp = 10, więc x = 10
Oczywiście to samo, można zapisać bez tworzenia dodatkowej zmiennej, czyli:
C/C++
int x = 5;
x = x * 2; //x*2 = 10, następnie przypisz obliczoną wartość, czyli x = 10
To co zostało wyżej napisane powinieneś już wiedzieć i potrafić zrobić samodzielnie. Nowy, krótszy zapis zamieszczam poniżej:
C/C++
int x = 5;
x *= 2; //pomnożenie obecnej wartości zmiennej razy 2.
Operatory skróconych operacji istnieją również do pozostałych działań arytmetycznych. Ich zestawienie zamieszczam w poniższej tabeli.
OperacjaZapis tradycyjnyZapis skrócony
dodawaniex = x + y;x += y;
odejmowaniex = x - y;x -= y;
mnożeniex = x * y;x *= y;
dzieleniex = x / y;x /= y;
reszta z dzieleniax = x % y;x %= y;

Inkrementacja i dekrementacja

Jeśli nie miałeś nigdy wcześniej styczności z programowaniem to prawdopodobnie hasła inkrementacja jak i dekrementacja nic Ci nie mówią. Opis pojęć przedstawiam w poniższej tabeli:
PojęcieOpisPrzykład
inkrementacjazwiększenie wartości zmiennej o jedenzmienna += 1;
dekrementacjazmniejszenie wartości zmiennej o jedenzmienna -= 1;
Pomimo, iż skrócony zapis jest wygodnym rozwiązaniem na zwiększenie, bądź zmniejszenie wartości o jeden, to do wykonania tych operacji istnieją dodatkowe zapisy i są to:
PojęciePrzykładOdpowiednik
preinkrementacja++zmienna;zmienna += 1;
postinkrementacjazmienna++;zmienna += 1;
predekrementacja--zmienna;zmienna -= 1;
postdekrementacjazmienna--;zmienna -= 1;
Rozpatrzmy teraz jakie mamy możliwości inkrementacji:
C/C++
++zmienna;
zmienna++;
zmienna += 1;
Na dzień dzisiejszy możesz przyjąć, że powyższe zapisy są równoważne, tj. wykonają dokładnie to samo, czyli zwiększą wartość zmiennej o 1. W rzeczywistości istnieją jednak różnice w działaniu między poszczególnymi zapisami. Na chwilę obecną uważam jednak, że wiedza tak szczegółowa nie jest Ci potrzebna i nie powinieneś dostawać informacji ponad niezbędne minimum. Priorytetem jest bowiem zrozumienie podstaw programowania, a nie znajomość wszystkich detali języka, których można się douczyć w każdej chwili.

Podsumowanie rozdziału

Podsumujmy teraz przedstawioną wiedzę w rozdziale w postaci następującego kodu źródłowego:
C/C++
#include <iostream>
int main()
{
    double liczba = 123.3;
    std::cout << "liczba = " << liczba << std::endl;
   
    liczba = liczba + 6.7;
    std::cout << "liczba = " << liczba << std::endl;
   
    liczba -= 30;
    std::cout << "liczba = " << liczba << std::endl;
   
    liczba /= 11;
    std::cout << "liczba = " << liczba << std::endl;
   
    liczba *= 3;
    std::cout << "liczba = " << liczba << std::endl;
   
    int nowa = liczba;
    std::cout << "nowa = " << nowa << std::endl;
   
    nowa %= 8;
    std::cout << "nowa = " << nowa << std::endl;
   
    nowa++;
    std::cout << "nowa = " << nowa << std::endl;
   
    ++nowa;
    std::cout << "nowa = " << nowa << std::endl;
   
    nowa *= 10;
    std::cout << "nowa = " << nowa << std::endl;
   
    --nowa;
    std::cout << "nowa = " << nowa << std::endl;
   
    nowa--;
    std::cout << "nowa = " << nowa << std::endl;
    return 0;
}
Po uruchomieniu powyższego programu w konsoli ujrzymy następującą treść:
liczba = 123.3
liczba = 130
liczba = 100
liczba = 9.09091
liczba = 27.2727
nowa = 27
nowa = 3
nowa = 4
nowa = 5
nowa = 50
nowa = 49
nowa = 48

Zadanie domowe

Liczby całkowite

Napisz program, który wczyta dwie liczby całkowite a i b, a następnie wykona na nich obliczenia. Efekt działania programu powinien być następujący:
Podaj a: 5
Podaj b: 4
a + b = 9
a - b = 1
a * b = 20
a / b = 1
a % b = 1

Liczby rzeczywiste

Napisz program, który wczyta dwie liczby rzeczywiste i wykona na nich obliczenia. Efekt programu powinien być analogiczny jak w pierwszym zadaniu czyli:
Podaj a: 5
Podaj b: 4
a + b = 9
a - b = 1
a * b = 20
a / b = 1.25

Eksperymenty

Sprawdź jak zachowają się oba programy gdy:
  • a lub b jest ujemne
  • b = 0
W przypadku pierwszym zwróć szczególną uwagę na resztę z dzielenia.
Poprzedni dokument Następny dokument
Obsługa strumienia wejściowego Operacje porównania