Rozdział 5. Kalkulator w języku C++

04 lipca 2012
1 gwiadka2 gwiazdki3 gwiazdki4 gwiazdki5 gwiazdek

W poprzednim rozdziale opis zmiennych w języku C++ rozpocząłem od przywołania przykładu pamięci w kalkulatorze. Jest to dobre porównanie, ponieważ komputer to tak naprawdę superpotężny kalkulator, który potrafimy zmusić do wykonywania obliczeń i przechowywania danych. Mam nadzieję, że trochę interesujesz się matematyką, ponieważ w tym rozdziale dowiesz się, jak napisać kalkulator w języku C++.

Zaczniemy od rzeczy, które są podstawą każdego kalkulatora, czyli liczb. W pierwszej części tego rozdziału nauczysz się zatem pobierać dane od użytkownika i zapisywać je w pamięci komputera. Do tego celu będą oczywiście potrzebne zmienne!

Później pokażę Ci, jak wykonuje się obliczenia, a na koniec, gdy już będziesz wiedział, jak wyświetlić wyniki, będziesz mógł wykorzystać zdobytą wiedzę w małym ćwiczeniu.

5.1. Pobieranie danych od użytkownika

Jak zapewne zauważyłeś, w języku C++ używanych jest wiele skrótów angielskich słów i wyrażeń. Dotyczy to między innymi instrukcji cout, która jest skrótem od angielskich słów see out — pokaż na wyjściu (i tak też należy ją czytać). Dzięki temu każdy kto zna przynajmniej podstawy angielskiego bez trudu domyśli się nazwy strumienia wejściowego. Skoro cout oznacza wyprowadzanie danych na zewnątrz programu, to wprowadzanie danych do programu musi być oznaczane słowem cin (czyt. jak ang. see in) i tak jest w rzeczywistości.

To nie wszystko! Z instrukcją cout związane są nawiasy <<. Podobnie jest z instrukcją cin, której również towarzyszy para nawiasów, ale zwróconych w przeciwną stronę>>.

Zobaczmy, jak używa się tych instrukcji w praktyce:

#include <iostream>
using namespace std;

int main()
{
    cout << "Ile masz lat?" << endl;

    int wiekUzytkownika(0);      // Przygotowujemy komórkę pamięci na liczbę całkowitą.

    cin >> wiekUzytkownika; // W komórce tej chcemy zapisać liczbę.

    cout << "Masz " << wiekUzytkownika << " lat!" <<  endl;
    // I wyświetlamy wynik na ekranie.

    return 0;
}

Przetestuj, jak działa ten program. Oto, co wyświetlił, gdy wpisałem swój wiek:

Ile masz lat?
22
Masz 22 lat!

Przenalizujemy ten kod szczegółowo. Najpierw program wyświetla tekst Ile masz lat?. Jak na razie nie ma tu nic niezwykłego. Następnie w znany nam już sposób rezerwujemy sobie w pamięci miejsce na liczbę typu int i nadajemy mu nazwę wiekUzytkownika.

Teraz zaczyna się najciekawsza część. W wierszu poleceń zostaje wyświetlona migająca pionowa kreska oznaczająca, że komputer oczekuje, aż użytkownik coś wpisze. Gdy użytkownik zrobi, co do niego należy i naciśnie klawisz Enter, program pobierze wpisaną wartość i zapisze ją w komórce pamięci wiekUzytkownika, zastępując znajdujące się w niej obecnie zero.

Na koniec robimy coś, co już dobrze znamy, tzn. wyświetlamy tekst i zawartość zmiennej na ekranie.

5.1.1. Sztuczka z ostrymi nawiasami

Programiści często gubią się w jakim kierunku powinny wskazywać ostre nawiasy po instrukcjach cout i cin. Możliwe że już nie wiesz, czy należy napisać cout >> czy cout <<.

Aby pomóc Ci to zapamiętać, poniżej przedstawiam przydatny rysunek.

Schemat pomagający zapamiętać kierunek nawiasów w instrukcjach cout i cin

Rysunek 5.1. Schemat pomagający zapamiętać kierunek nawiasów w instrukcjach cout i cin

Gdy wyświetlamy wartość zmiennej, dane wychodzą z programu, a więc strzałka wskazuje kierunek od zmiennej do strumienia cout. Kiedy natomiast pobieramy dane od użytkownika, podróżują one w przeciwnym kierunku, tzn. od strumienia cin do zmiennej.

Teraz już się nie pomylisz!

5.1.2. Inne typy zmiennych

Powyższy opis dotyczy w takim samym stopniu także innych typów zmiennych. Spójrzmy na krótki przykład.

#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout << "Jak masz na imię?" << endl;
    string imieUzytkownika("Brak imienia");      // Rezerwujemy miejsce na łańcuch znaków
    cin >> imieUzytkownika;                      // Zapisujemy w utworzonej zmiennej tekst wpisany przez użytkownika
    cout << "Ile wynosi liczba pi?" << endl;
    double piUzytkownika(-1.);                  // Rezerwujemy miejsce w pamięci na liczbę rzeczywistą
    cin >> piUzytkownika;                        // Zapisujemy w tej zmiennej to, co wpisze użytkownik
    cout << "Nazywasz się " << imieUzytkownika << " i Twoim zdaniem liczba pi wynosi " << piUzytkownika << "" << endl;
    return 0;
}

Wydaje mi się, że powyższy kod nie wymaga objaśnień. Warto jednak go skompilować i uruchomić, aby dokładnie prześledzić jego działanie.

5.1.3. Problem ze spacjami

Sprawdziłeś co się stanie, gdy powyższemu programowi przekażesz swoje imię i nazwisko? Zobacz, co wówczas wyświetli:

Jak masz na imię?
Albert Einstein
Ile wynosi liczba pi?
Nazywasz się Albert i Twoim zdaniem liczba pi wynosi 0.

Komputer nie poprosił o wpisanie wartości liczby pi i na dodatek uciął nazwisko! Dlaczego?

Problem ten dotyczy spacji. Gdy nacisnąłem klawisz Enter, komputer skopiował tekst wpisany przez użytkownika do pamięci. Ale zatrzymał się na pierwszej spacji, czyli pierwszym przejściu do nowego wiersza. Z liczbami nie ma tego typu problemów, ponieważ liczby nie zawierają spacji.

Natomiast z typem string ten problem występuje. Oczywiście w łańcuchach znaków czasami muszą występować spacje. Ale komputer dzieli łańcuchy w niewłaściwym miejscu — za pierwszym słowem. A ponieważ nie jest bardzo złośliwy, przyjmuje, że podane nazwisko jest wartością liczby pi!

Dlatego musimy sprawić, aby cały wiersz był traktowany jako pierwsze słowo. Doskonale do tego celu nadaje się funkcja getline(). Szczegółowy opis funkcji znajduje się trochę dalej. Na razie skoncentrujemy się tylko na rozwiązaniu naszego problemu.

Wiersz zawierający instrukcję cin >> imieUzytkownika należy zastąpić wywołaniem funkcji getline():

#include <iostream>
#include <string>
using namespace std;

int main()
{
    cout << "Jak masz na imię?" << endl;
    string imieUzytkownika("Brak imienia");     // Rezerwujemy miejsce w pamięci na łańcuch znaków
    getline(cin, imieUzytkownika);              // Zapisujemy w tym miejscu wszystko, co wpisze użytkownik
    cout << "Ile wynosi liczba pi?" << endl;
    double piUzytkownika(-1.);                  // Rezerwujemy miejsce w pamięci na liczbę rzeczywistą
    cin >> piUzytkownika;                       // Zapisujemy w nim to, co wpisze użytkownik
    cout << "Nazywasz się " << imieUzytkownika << " i Twoim zdaniem liczba pi wynosi " << piUzytkownika << "." << endl;
    return 0;
}

W programie tym użyliśmy takich samych konstrukcji, co poprzednio. Mamy tu instrukcję cin i zmienną o nazwie imieUzytkownika. Różnica polega na tym, że tym razem elementy te znajdują się w nawiasie okrągłym i nie ma nawiasów ostrych.

Kolejność elementów w nawiasie jest bardzo ważna. Instrukcja cin bezwzględnie musi być pierwsza.

Teraz wynik działania programu będzie prawidłowy:

Jak masz na imię?
Alber Einstein
Ile wynosi liczba pi?
3.14
Nazywasz się Albert Einstein i Twoim zdaniem liczba pi wynosi 3.14.

5.1.4. Pobieranie najpierw wartości pi

Gdybyśmy najpierw użyli instrukcji cin, a potem funkcji getline(), aby na przykład najpierw pobrać wartość liczby pi, a dopiero potem imię użytkownika, program by nie zadziałał. Komputer nie poprosiłby użytkownika o podanie imienia i by go później nie wyświetlił. Problem ten można rozwiązać poprzez wpisanie wiersza kodu cin.ignore(); po wierszu, w którym użyta została instrukcja cin.

#include <iostream>
#include <string>
using namespace std;
int main()
{
	cout << "Ile wynosi pi?" << endl;
	double piUzytkownika(-1.);                  // Rezerwujemy w pamięci miejsce na liczbę rzeczywistą
	cin >> piUzytkownika;                       // Zapisujemy w tym miejscu to, co wpisze użytkownik
	cin.ignore();
	cout << "Jak masz na imię?" << endl;
	string imieUzytkownika("Brak imienia");      // Rezerwujemy w pamięci miejsce na łańcuch znaków
	getline(cin, imieUzytkownika);               // Zapisujemy w tym miejscu to, co wpisze użytkownik
	cout << "Nazywasz się " << imieUzytkownika << " i Twoim zdaniem liczba pi wynosi " << piUzytkownika << "." << endl;
	return 0;
}

Teraz nie będzie żadnych problemów.

Kiedy w jednym programie używane są zamiennie instrukcja cin i funkcja getline(), należy zawsze po instrukcji cin>>a wpisać wiersz cin.ingore();.

Teraz spróbujemy zrobić coś przydatnego z naszymi zmiennymi, np. zsumować dwie liczby.

5.2. Modyfikowanie zmiennych

5.2.1. Zmienianie zawartości zmiennej

Na początku tego rozdziału napisałem, że pamięć komputera działa w podobny sposób, jak pamięć kalkulatora. To nie jedyne podobieństwo między tymi urządzeniami. Za pomocą komputera można także wykonywać działania matematyczne. Do tego celu wykorzystuje się zmienne.

Zaczniemy od tego, jak zmienia się zawartość zmiennych. Służy do tego znak =. Jeśli mamy zmienną typu int, której wartość chcemy zmienić, musimy napisać nazwę tej zmiennej, po niej wpisać znak =, a na koniec podać nową wartość. Proces ten nazywamy przypisywaniem wartości zmiennej:

int liczba(0);  // Utworzyłem miejsce w pamięci o nazwie liczba i zawierające wartość 0.
liczba = 5;   // Zapisałem 5 w miejscu pamięci o nazwie liczba.

Można także zmienić wartość zmiennej na wartość innej zmiennej:

int a(4), b(5); // Deklaracja dwóch zmiennych.
a = b; // Przypisanie zmiennej a wartości zmiennej b.

O co dokładnie w tym chodzi? Gdy komputer dojdzie do drugiego wiersza powyższego kodu, odczyta zawartość szufladki pamięci o nazwie b, która jest liczbą 5. Następnie otworzy szufladkę o nazwie a i zamieni znajdującą się tam liczbę 4 na liczbę 5. Proces ten przedstawia poniższy schemat.

Rysunek 5.2. Przypisywanie wartości zmiennym w języku C++

Rysunek 5.2. Przypisywanie wartości zmiennym w języku C++

Możemy wyświetlić zawartość obu zmiennych, aby sprawdzić rezultat naszych działań:

#include <iostream>
using namespace std;

int main()
{
    int a(4), b(5); // Deklaracja dwóch zmiennych.

    cout << "Wartość zmiennej a: " << a << ", wartość zmiennej b: " << b << endl;

    cout << "Przypisanie!"<< endl;
    a = b; // Przypisanie zmiennej a wartości zmiennej b.

    cout << "Wartość zmiennej a: " << a << ", wartość zmiennej b: " << b << endl;

    return 0;
}

Przetestowałeś ten program? Zrób to, ponieważ sprawdzenie w praktyce działania programów pozwala je lepiej zrozumieć. Poniżej znajduje się wynik jego działania.

Wartość zmiennej a: 4, wartość zmiennej b: 5
Przypisanie!
Wartość zmiennej a: 5, wartość zmiennej b: 5

Wynik jest dokładnie taki, jakiego należało się spodziewać.

Wartość zmiennej b pozostała niezmieniona. Należy pamiętać, że w operacji przypisania zmianie ulega tylko wartość zmiennej znajdującej się po lewej stronie znaku =.

Teraz obie zmienne zawierają takie same dane. Zawartość zmiennej znajdującej się po prawej stronie została skopiowana do zmiennej znajdującej się po lewej stronie.

Na początek całkiem nieźle, ale to nie wystarczy, żeby napisać kalkulator. Musimy jeszcze wiedzieć, jak wykonywać działania matematyczne.

5.2.2. Podstawa kalkulatora

Zaczniemy od najprostszego działania, jakim jest dodawanie. Do jego oznaczania oczywiście służy znak +. Wykonanie tego działania w programie jest naprawdę łatwe:

int a(5), b(8), wynik(0);
wynik = a + b; // Dodanie wartości dwóch zmiennych

Ponieważ jest to pierwszy przykład wykonywania działań, opiszę go szczegółowo. W pierwszym wierszu tworzone są trzy zmienne o nazwach a, b i wynik i wartościach odpowiednio 5, 8 oraz 0. To już znamy.

Natomiast w wierszu drugim znajduje się instrukcja powodująca zmianę wartości zmiennej wynik. Po prawej stronie znaku równości znajduje się wyrażenie oznaczające sumę wartości zmiennych a i b. Komputer pobiera zatem wartości tych zmiennych nie modyfikując ich, wykonuje działanie matematyczne i zapisuje sumę w zmiennej wynik. Wszystko to dzieje się w mgnieniu oka. Jeśli chodzi o wykonywanie obliczeń, komputery nie mają sobie równych.

Możemy sprawdzić, czy to rzeczywiście tak działa, jak napisałem:

#include <iostream>
using namespace std;

int main()
{
    int wynik(0), a(5), b(8);

    wynik = a + b;

    cout << "5 + 8 = " << wynik << endl;
    return 0;
}

Na ekranie pojawi się następujący napis:

5 + 8 = 13

Oprócz dodawania, możemy wykonywać jeszcze cztery inne działania matematyczne. Zebrałem je wszystkie w poniższej tabeli.

DziałanieZnakPrzykład
Dodawanie+wynik = a + b;
Odejmowanie-wynik = a - b;
Mnożenie*wynik = a * b;
Dzielenie/wynik = a / b;
Modulo%wynik = a % b;

Co to takiego modulo? W szkole nic o tym nie mówili. Jestem pewien, że mówili, tylko używali innej nazwy. Modulo to reszta z dzielenia całkowitoliczbowego. Jeśli przejrzysz swoje szkolne zeszyty do matematyki, to na pewno znajdziesz w nich zapisy działań typu 13 : 3. Ponieważ 13 nie jest wielokrotnością liczby 3, trzeba coś od niej odjąć, aby uzyskać taką wielokrotność. To coś, co odejmujemy nazywa się resztą z dzielenia. To pojęcie pewnie już gdzieś słyszałeś. Modulo to operacja, której wynikiem jest właśnie reszta z dzielenia dwóch liczb całkowitych.

Operatora dzielenia modulo można używać tylko z liczbami całkowitymi!

Wiedząc jak zapisać działania matematyczne, możemy napisać bardziej skomplikowane wyrażenia zawierające większą liczbę zmiennych. W razie potrzeby można też używać nawiasów:

int a(2), b(4), c(5), d; // Kilka zmiennych
d = ((a+b) * c ) - c; // Skomplikowane obliczenia

Wszystkie wyrażenia, które są poprawne z punktu widzenia matematyki są również poprawne w C++.

5.3. Stałe

W poprzednim podrozdziale pokazałem Ci, jak się modyfikuje zmienne. Mam nadzieję, że dobrze przyswoiłeś sobie tamten materiał, ponieważ teraz pokażę Ci coś odwrotnego. W tym podrozdziale dowiesz się, jak deklarować zmienne, których nie można modyfikować.

Fachowo zmienne tego rodzaju nazywają się stałymi. Wiem że wprowadziłem sporo nowych pojęć w tym rozdziale, ale obiecuję, że w następnym będzie już tego mniej.

Do czego mogą służyć zmienne, których nie można modyfikować? To dobre pytanie. Poniżej znajdziesz na nie odpowiedź.

Wyobraź sobie rewolucyjną grę komputerową, którą kiedyś napiszesz. Powiedzmy, że ma ona dziesięć poziomów do przejścia. Oczywiście liczba ta w czasie trwania gry nigdy nie powinna się zmienić — od momentu jej rozpoczęcia przez gracza, aż do zakończenia poziomów cały czas jest tyle samo. Liczba ta jest stała. W związku z tym w języku C++ do jej przechowywania możemy utworzyć zmienną o nazwie liczbaPoziomow, którą zamienimy w stałą.

To oczywiście nie jest jedyne zastosowanie stałych. Pomyśl o kalkulatorze, w którym może być zdefiniowana stała Π albo o grze, w której postaci mogą się przewracać i trzeba uwzględnić stałą przyspieszenia grawitacyjnego, która wynosi g = 9,81 itd. Te wartości nigdy się nie zmienią. Liczba Π zawsze będzie w przybliżeniu wynosiła 3,14, a przyspieszenie grawitacyjne na ziemi zawsze będzie wynosić 9,81. Są to wielkości stałe. Co więcej ich wartości znamy już na etapie pisania kodu źródłowego.

Ale to nie wszystko. Istnieją też wartości, które nigdy się nie zmieniają, ale których nie znamy z góry. Weźmy na przykład wynik działania w kalkulatorze. Gdy obliczenia zostaną wykonane, ich wynik już się nie zmieni. Zatem zmienna służąca do jego przechowywania jest w istocie stałą.

Zobaczmy w takim razie, jak definiuje się stałe.

5.3.1. Definiowanie stałych w języku C++

Definiowanie stałych jest bardzo łatwe. Należy zdefiniować zwykłą zmienną i między jej typem a nazwą wpisać słowo kluczowe const:

int const liczbaPoziomow(10);

Opisana zasada tworzenia stałych dotyczy wszystkich typów danych:

string const haslo("wAsTZsaswQ");
double const pi(3.14);
unsigned int const maksLiczbaPunktowZycia(100); // Maksymalna liczba punktów życia gracza

Można by tak te przykłady mnożyć w nieskończoność, ale myślę że tyle wystarczy, aby zrozumieć, o co chodzi.

Definiuj stałe zawsze, gdy jest to możliwe. Pozwala to nie tylko uniknąć błędów wynikających z roztargnienia, lecz również umożliwia kompilatorowi wygenerowanie bardziej wydajnego kodu wykonywalnego.

Do stałych wrócimy jeszcze w dalszych rozdziałach, a na razie przygotuj się na pierwsze zadanie.

5.4. Pierwsze zadanie

Mamy już wszystkie składniki potrzebne do napisania pierwszego prawdziwego programu. Przedstawiony wcześniej przykładowy program sumował dwie liczby wpisane bezpośrednio w kod źródłowy. Jednak program ten byłby znacznie bardziej przydatny, gdyby prosił użytkownika o podanie liczb, które chce zsumować! To jest właśnie nasze pierwsze zadanie. Napisać program proszący użytkownika o podanie dwóch liczb, obliczający ich sumę i wyświetlający wynik na ekranie.

Bądź spokojny, pomogę Ci to zrobić, ale zachęcam Cię też, abyś sam spróbował znaleźć rozwiązanie. Samodzielne wykonywanie zadań jest najefektywniejszą metodą nauki.

Pracę należy rozpocząć od zastanowienia się, jakie zmienne będą potrzebne w nowym programie. Potrzebujemy po jednej zmiennej na liczby wpisane przez użytkownika. Skorzystamy z programu, który napisaliśmy wcześniej i zmiennym tym nadamy nazwy a i b.

Musimy też wybrać typ dla tych zmiennych. Jako że będą one wykorzystywane do wykonywania działań arytmetycznych, w grę wchodzą typy int, unsigned int oraz double. Wybierzemy typ double, dzięki czemu będzie można sumować także liczby z częścią dziesiętną.

Możemy zatem napisać już podstawową strukturę naszego programu:

#include <iostream>
using namespace std;
int main()
{
    double a(0), b(0); // Definicje potrzebnych zmiennych

    return 0;
}

Kolejny etap to napisanie procedur pozwalających poprosić użytkownika o podanie liczb. Przypomnę, że do tego potrzebna jest instrukcja cin >>:

#include <iostream>
using namespace std;
int main()
{
	double a(0), b(0); // Definicje potrzebnych zmiennych
	cout << "Witaj w programie sumującym liczby a i b !" << endl;
	cout << "Podaj wartość liczby a : ";    // Poproszenie użytkownika o pierwszą liczbę
	cin >> a;
	cout << "Podaj wartość liczby b : ";    // Poproszenie użytkownika o drugą liczbę
	cin >> b;
	//...
	return 0;
}

Pozostało już tylko wykonanie działania i wyświetlenie wyniku. Do tego będziemy potrzebować jeszcze jednej zmiennej. Ponieważ wynik obliczeń jest niezmienny, do jego przechowywania możemy (a wręcz powinniśmy) użyć stałej. Nazwiemy ją wynik.

Aby zsumować liczby, musimy oczywiście użyć operatora +:

#include <iostream>
using namespace std;
int main()
{
	double a(0), b(0); // Definicje potrzebnych zmiennych
	cout << "Witaj w programie sumującym liczby a i b!" << endl;
	cout << "Podaj wartość liczby a: ";    // Poproszenie użytkownika o pierwszą liczbę
	cin >> a;
	cout << "Podaj wartość liczby b: ";    // Poproszenie użytkownika o drugą liczbę
	cin >> b;

 double const wynik(a + b);   // Wykonanie działania

 cout << a << " + " << b << " = " << wynik << endl; // Wyświetlenie wyniku
	return 0;
}

Skompiluj i przetestuj powyższy program. Powinieneś otrzymać wynik podobny do poniższego:

Witaj w programie sumującym liczby a i b!
Podaj wartość liczby a: 123.784
Podaj wartość liczby b: 51.765
123.784 + 51.765 = 175.549

Doskonale! Dokładnie o to nam chodziło.

No dobrze. Ja już sobie popracowałem. Teraz Twoja kolej. Oto kilka propozycji zadań do wykonania:

  • Oblicz iloczyn liczb a i b.
  • Wykonaj bardziej skomplikowane działanie, typu a * b + c.
  • Pobierz od użytkownika dwie liczby całkowite i oblicz ich iloraz i resztę z dzielenia.

Powodzenia i dobrej zabawy!

5.5. Skracanie zapisu niektórych działań

Po wykonaniu ostatniego ćwiczenia znasz wszystkie podstawowe operacje. Może będzie to dla Ciebie coś niezwykłego, ale to naprawdę wszystkie dostępne działania. Przy ich użyciu można zrobić wszystko, włącznie z grami komputerowymi, które są przedstawione na początku tego kursu.

Występują one jednak w różnych wariantach, z którymi zapoznam Cię właśnie w tej części rozdziału.

5.5.1. Inkrementacja

Jednym z najczęściej wykonywanych działań w programowaniu jest zwiększenie wartości zmiennej o jeden. Oto kilka przykładowych sytuacji, w których się to robi:

  • Przejście z poziomu 4 do 5 w grze komputerowej.
  • Zwiększenie liczby żyć postaci w grze.
  • Dodanie gracza do gry.

Operacja ta jest tak często wykonywana, że nadano jej nawet specjalną nazwę. Jest to inkrementacja. Tak naprawdę to my już potrafimy zwiększyć wartość dowolnej zmiennej o jeden:

int liczbaGraczy(4); // W grze jest aktualnie czterech graczy
liczbaGraczy = liczbaGraczy + 1; // Dodaliśmy jednego gracza
// Teraz w grze jest pięciu graczy

Jednak programiści to bardzo leniwy naród i dlatego wynaleźli sposób na skrócenie zapisu działania widocznego w drugim wierszu powyższego kodu. Służy do tego specjalny operator w postaci dwóch znaków + obok siebie:

int liczbaGraczy(4); // W grze jest czterech graczy
++liczbaGraczy;
// Teraz w grze jest pięciu graczy

Operator inkrementacji ma zatem postać ++. Wpisujemy go przed nazwą zmiennej, po której z kolei tradycyjnie stawiamy średnik. Ten kod działa dokładnie tak samo, jak poprzedni, tylko jest krótszy.

Możemy także napisać liczbaGraczy++, tzn. umieścić operator ++ za nazwą zmiennej. Jest to tzw. postinkrementacja, natomiast poprzednia wersja z operatorem ++ przed nazwą zmiennej to preinkrementacja.

W pierwszej chwili może się to wydawać śmieszne i nieprzydatne, ale jestem pewien, że już wkrótce zakochasz się w obu wersjach tego operatora.

Operator ++ jest tak popularną częścią języków programowania, że znalazł się nawet w nazwie języka C++. Tak, tak język C++ zgodnie z nazwą jest w założeniu twórcy „wzbogaconą wersją języka C”.

5.5.2. Dekrementacja

Dekrementacja to odwrotność inkrementacji — powoduje odjęcie jeden od wartości zmiennej. Kod w wersji długiej wygląda tak:

int liczbaGraczy(4); // W grze jest czterech graczy
liczbaGraczy = liczbaGraczy - 1; // Odejmujemy jednego
// Od tej pory w grze jest trzech graczy

Zapewne domyślasz się, jak będzie wyglądała wersja skrócona. Skoro do dodawania służył operator ++, to do odejmowania musi służyć operator --:

int liczbaGraczy(4); // W grze jest czterech graczy
--liczbaGraczy; // Odejmujemy jednego
// Od tej pory w grze jest trzech graczy

W przypadku dekrementacji również istnieją dwie wersje operatora. Możemy zatem pisać liczbaGraczy-- i --liczbaGraczy.

5.5.3. Skracanie innych operacji

Wiemy już jak odjąć lub dodać jeden do zmiennej przy użyciu skróconego zapisu, ale to nie jedyne skróty, jakie można stosować. Istnieją też skrócone notacje dla wszystkich operacji podstawowych.

Jeśli zatem chcemy podzielić wartość zmiennej przez 3, to możemy posłużyć się poniższym długim zapisem:

double liczba(456);
liczba = liczba / 3;
// Od tej pory zmienna liczba ma wartość 456/3 = 152

…albo użyć zapisu skróconego z użyciem znaków /=, którego efekt będzie identyczny z poprzednim:

double liczba(456);
liczba /= 3;
// Od tej pory zmienna liczba ma wartość 456/3 = 152

Takie skróty są dostępne dla wszystkich operacji podstawowych: +=, -=, *=, /= oraz %=. Warto sobie je przyswoić, bo gdy raz ich użyjesz, to już nie będziesz chciał używać innych form zapisu.

Poniżej przedstawiam niewielki przykładowy program ilustrujący użycie różnych skróconych wersji operatorów.

#include <iostream>
using namespace std;

int main()
{
    double liczba(5.3);
    liczba += 4.2;       // Teraz zmienna liczba będzie miała wartość 9.5
    liczba *= 2.;        // Teraz zmienna liczba będzie miała wartość 10.6
    liczba -= 1.;        // Teraz zmienna liczba będzie miała wartość 4.3
    liczba /= 3.;        // Teraz zmienna liczba będzie miała wartość 1.76667
    return 0;
}

Te operatory są przydatne, gdy trzeba dodać lub odjąć od zmiennej inną wartość niż 1.

5.6. Jeszcze trochę matematyki

Lubisz matematykę? To dobrze, bo nasz kalkulator jest jak na razie ubogi w funkcje i nie obsługuje nawet wszystkich podstawowych działań arytmetycznych. To raczej nie jest powód do dumy, biorąc pod uwagę, że działa na najpotężniejszej maszynie do liczenia, czyli komputerze.

Nie ma rady, trzeba to jakoś poprawić.

5.6.1. Nagłówek cmath

Aby móc korzystać z dodatkowych funkcji matematycznych, należy dodać na początku programu specjalny wiersz kodu, podobnie jak wcześniej dodaliśmy instrukcję informującą o tym, że planujemy używać typu string. Oto kod, który należy dodać:

#include <cmath>
W tej części rozdziału pokażę Ci, jak się używa niektórych funkcji z biblioteki cmath języka C++. Niektórych z nich możesz nie znać, ale to nie problem, nie będą Ci one potrzebne w dalszej części kursu. Przydadzą Ci się natomiast w przyszłości, jeśli zechcesz więcej zajmować się matematyką.

Na początek zapoznamy się z często używaną funkcją obliczającą pierwiastek kwadratowy. Po angielsku pierwiastek kwadratowy to square root, w skrócie sqrt. Ponieważ w języku C++ używane jest słownictwo angielskie, to właśnie tę nazwę nadano funkcji obliczającej pierwiastek kwadratowy.

Aby użyć funkcji matematycznej, należy napisać jej nazwę i w nawiasie wartość, na której ta funkcja ma działać. Oznacza to, że wynik działania funkcji zapisujemy w zmiennej korzystając z techniki przypisania.

wynik = funkcja(wartosc);

Podobnie w matematyce stosuje się zapis y = f(x). Trzeba tylko zapamiętać czasami skomplikowane nazwy funkcji. Jeśli zechcemy obliczyć pierwiastek kwadratowy z dowolnej liczby, napiszemy wynik = sqrt(wartosc);.

Nie zapomnij postawić średnika na końcu wiersza!

Spójrzmy na kompletny przykładowy program:

#include <iostream>
#include <cmath> // Ten wiersz jest bardzo ważny
using namespace std;
int main()
{
	double const liczba(16);       // Wartość, dla której będzie obliczany pierwiastek kwadratowy
	// Ponieważ wartość ta nie będzie się zmieniać, definiujemy ją jako stałą
	double wynik;               // Miejsce w pamięci na zapisanie wyniku
	wynik = sqrt(liczba);  // Wykonanie obliczeń
	cout << "Pierwiastek kwadratowy z " << liczba << " wynosi " << wynik << endl;
	return 0;
}

Wynik działania tego programu jest następujący:

Pierwiastek kwadratowy z 16 wynosi 4

W następnym podrozdziale znajdziesz opis kilku innych ciekawych funkcji matematycznych.

5.6.2. Inne funkcje dostępne w bibliotece cmath

Ponieważ w bibliotece cmath znajduje się bardzo dużo funkcji, poniżej przedstawiam zestawienie kilku najczęściej używanych z nich.

Ogólna nazwa funkcjiZapis matematycznyNazwa funkcji w C++Przykład użycia
Pierwiastek kwadratowy√xsqrt()wynik = sqrt(wartosc);
Sinussin(x)sin()wynik = sin(wartosc);
Cosinuscos(x)cos()wynik = cos(wartosc);
Tangenstan(x)tan()wynik = tan(wartosc);
Funkcja wykładniczaexexp()wynik = exp(wartosc);
Logarytm naturalnylnxlog()wynik = log(wartosc);
Logarytm o podstawie 10log10xlog10xwynik = log10(wartosc);
Wartość bezwzględna|x|fabs()wynik = fabs(wartosc);
Zaokrąglenie w dół⌊x⌋floor()wynik = floor(wartosc);
Zaokrąglenie do góry⌈x⌉ceil()wynik = ceil(wartosc);
Funkcje trygonometryczne (sin(), cos() itd.) jako jednostki miary kąta używają radianów.
Funkcje matematyczne mogą działać tylko na zmiennych liczbowych (typów double, int itp.). Obliczanie pierwiastka kwadratowego z liczby albo cosinusa zdania nie ma sensu.

5.6.3. Niezwykła funkcja potęgowania

Potęgowanie jest wyjątkowym rodzajem działania, ponieważ wymaga podania dwóch liczb. Jak na przykład wykonać działanie 45? Należy użyć funkcji pow(), która przyjmuje dwa argumenty. Argumenty to wartości, które wpisuje się w nawiasie za nazwą funkcji, podobnie jak w przypadku funkcji getline(), o której była mowa wcześniej.

Aby obliczyć wynik działania 45, należy napisać kod podobny do poniższego:

double const a(4);
double const b(5);
double const wynik = pow(a,b);

Zdefiniowaliśmy trzy stałe do przechowywania liczb 4 i 5 oraz wyniku. Dwie pierwsze stałe zainicjowaliśmy od razu odpowiednimi wartościami. Natomiast zmienną wynik inicjujemy przy użyciu znaku = rezultatem działania funkcji pow().

Możemy przepisać poprzedni przykładowy program i zastąpić w nim operację dodawania nowo poznaną funkcją pow(). Najlepiej spróbuj to zrobić samodzielnie, a poniżej znajduje się moja wersja programu:

#include <iostream>
#include <cmath> // Ważne!
using namespace std;
int main()
{
	double a(0), b(0); // Definicje potrzebnych zmiennych
	cout << "Witaj w programie obliczającym a^b!" << endl;
	cout << "Podaj wartość a: ";    // Monit o podanie pierwszej liczby
		cin >> a;
	cout << "Podaj wartość b: ";    // Monit o podanie drugiej liczby
		cin >> b;
	double const wynik(pow(a, b));   // Wykonanie obliczeń
	// Można też napisać tak:
	// double const wynik = pow(a,b);
	// Zapamiętaj te dwie formy inicjacji zmiennych
		cout << a << " ^ " << b << " = " << wynik << endl; // Wyświetlenie wyniku
		return 0;
}

Twój program wygląda podobnie? Doskonale! Masz zadatki na dobrego programistę. Sprawdźmy wynik działania tego programu.

Witaj w programie obliczającym a^b!
Podaj wartość a: 4
Podaj wartość b: 5
4 ^ 5 = 1024

Mam nadzieję, że przynajmniej niektóre z opisanych tu funkcji matematycznych kiedyś Ci się przydadzą. Jeśli kiedykolwiek będziesz ich potrzebować, zawsze będziesz mógł wrócić do tego kursu, aby znaleźć ich opis.

Na tym kończy się drugi z dwóch rozdziałów o używaniu pamięci w języku C++. W tym rozdziale nauczyliśmy się modyfikować zmienne za pomocą znaku = i wykonywać działania matematyczne przy ich użyciu.

W następnym rozdziale zmienne odłożymy chwilowo na bok i zajmiemy się sposobami modyfikowania ścieżki wykonywania programów, a więc poznamy instrukcje sterujące.

Autor: Mathieu Nebra i Matthieu Schaller

Źródło: http://openclassrooms.com/courses/programmez-avec-le-langage-c/une-vraie-calculatrice

Tłumaczenie: Łukasz Piwko

Treść tej strony dostępna jest na zasadach licencji CC BY-NC-SA 2.0