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

> Dodaj do ulubionych

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.

Rysunek 5.1. 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 jest dost─Öpna na zasadach licencji CC BY-NC-SA 2.0