Kurs C++
TI 312[01]
Kurs C++
2
Spis treści
1. Wielkie i małe litery........................................................................................................ 4
Przykład 1.1 .................................................................................................................... 4
2. Komentarze .................................................................................................................... 4
Przykład 2.1 .................................................................................................................... 4
3. Słowa kluczowe .............................................................................................................. 4
Tabela 3.1. Słowa kluczowe ............................................................................................ 5
Tabela 3.2. Leksemy alternatywne .................................................................................. 5
4. Funkcja return................................................................................................................ 6
Przykład 4.1 .................................................................................................................... 6
5. Dyrektywa #include ....................................................................................................... 6
6. Deklaracja stałych .......................................................................................................... 6
Przykład 6.1 .................................................................................................................... 6
Przykład 6.2 .................................................................................................................... 7
7. Deklaracja zmiennych .................................................................................................... 7
Tabela 7.1. Podstawowe typy zmiennych ........................................................................ 7
Przykład 7.1 .................................................................................................................... 7
Tabela 7.2. Podstawowe manipulatory............................................................................ 8
8. Operatory ....................................................................................................................... 8
a) Operatory arytmetyczne ............................................................................................. 8
Tabela 8.1. Operatory arytmetyczne ............................................................................ 8
Przykład 8.1................................................................................................................. 8
b) Operatory relacyjne .................................................................................................... 8
Tabela 8.2. Operatory relacyjne ................................................................................... 9
Przykład 8.2................................................................................................................. 9
c) Operatory logiczne...................................................................................................... 9
Tabela 8.3. Operatory logiczne .................................................................................... 9
Przykład 8.3................................................................................................................. 9
d) Bitowe operatory logiczne ........................................................................................ 10
Tabela 8.4. Bitowe operatory logiczne ....................................................................... 10
Przykład 8.4............................................................................................................... 10
9. Funkcje......................................................................................................................... 12
Przykład 9.1. Mnożenie dwóch liczb .............................................................................. 12
Przykład 9.2 Mnożenie dwóch liczb (typ void) ............................................................... 13
10. Instrukcje warunkowe ............................................................................................... 13
a)
instrukcja niepełna (wybór niepełny): ................................................................ 13
b)
instrukcja pełna (wybór pełny) ........................................................................... 13
Przykład 10.2 Zagnieżdżanie instrukcji warunkwych .................................................... 14
11. Instrukcja switch......................................................................................................... 14
Przykład 11.1. Kalkulator .............................................................................................. 15
Przykład 11.2. Sprawdzanie ile wynosi reszta z dzielenia wprowadzonej liczby przez 4.
..................................................................................................................................... 16
12. Pętla while i do while ................................................................................................... 16
a)
Pętla while .......................................................................................................... 16
Przykład 12.1. Sumowanie liczb naturalnych od 1 do n.............................................. 16
b)
Pętla do while ...................................................................................................... 17
Przykład 12.2. Sumowanie liczb naturalnych od 1 do n (ze sprawdzaniem czy n jest
większe od 1) ............................................................................................................ 17
13. Pętla for ..................................................................................................................... 17
Przykład 13.1. Program wypisujący liczby naturalne od 1 do n ..................................... 18
Przykład 13.2. Program sprawdzający, czy liczba jest pierwsza.................................... 18
14. Typ tablicowy ............................................................................................................. 19
a) Tablice jednowymiarowe .......................................................................................... 19
Przykład 14.1. Wypełnianie i wypisywanie elementów tablicy za pomocą pętli ......... 19
Przykład 14.2. Wypisanie elementów zadeklarowanej (wypełnionej) tablicy. ........... 19
Kurs C++
3
Przykład 14.3............................................................................................................. 20
b) Tablice wielowymiarowe........................................................................................... 20
Przykład 14.4 Wprowadzanie imion i nazwisk do bazy (za pomocą pętli) i szukanie
osób w bazie o podanym nazwisku. ........................................................................... 20
15. Struktury danych........................................................................................................ 21
Przykład 15.1. Struktura ............................................................................................... 22
Przykład 15.2. Tablica struktur (tablica typu strukturalnego)....................................... 22
Przykład 15.2. Baza danych - tablica struktur (tablica typu strukturalnego)................. 22
16. Klasy .......................................................................................................................... 26
Przykład 16.1. Program „Przedstaw się”....................................................................... 27
Przykład 16.2. Tablica klas– baza danych „Osoby”........................................................ 27
Przykład 16.3. Tablica klas– baza danych „Osoby 2”..................................................... 28
17. Hermetyzacja ............................................................................................................. 30
Przykład 17.1. Program „Bankomat”............................................................................. 30
18. Konstruktor i destruktor ............................................................................................. 31
Przykład 18.1. Nadawanie wartości początkowych tworzonemu obiektowi za pomocą
konstruktora ................................................................................................................. 31
Przykład 18.2. Nadawanie wartości początkowych tworzonemu obiektowi za pomocą
konstruktora i informowanie za pomocą destruktora o usunięciu obiektu po skończeniu
programu ...................................................................................................................... 32
19. Zagnieżdżona definicja klasy ...................................................................................... 33
Przykład 19.1. Konstruktory zagnieżdżonych klas......................................................... 34
20. Przeciążenie funkcji.................................................................................................... 35
Przykład 20.1. Przeciążenie funkcji............................................................................... 35
21. Przeciążenie operatorów ............................................................................................ 35
Tabela 20.1. Lista operatorów, które mogą być przeładowane...................................... 36
Przykład 20.1. Przeciążenie operatorów ....................................................................... 36
21. Zapis i odczyt pliku ..................................................................................................... 37
Przykład 21.1. Zapis do pliku tekstowego ..................................................................... 37
Przykład 21.2. Odczyt z pliku tekstowego ..................................................................... 37
Tabela 21.1. Tryby klasy ios.......................................................................................... 38
22. Dziedziczenie.............................................................................................................. 38
Przykład 22.1. Dziedziczenie składowej klasy podstawowej przez klasę pochodną....... 38
23 Polimorfizm ................................................................................................................. 39
24. Unie............................................................................................................................ 39
Przykład 24.1 ................................................................................................................ 39
25. Pola bitowe................................................................................................................. 40
Przykład 25.1 ................................................................................................................ 40
26. Wskaźniki ................................................................................................................... 40
Przykład 26.1 ................................................................................................................ 40
Przykład 26.2. Manipulowanie danymi za pomocą wskaźników .................................... 42
a) Zarządzanie pamięcią ............................................................................................... 42
Przykład 26.3. Rezerwacja i zwalnianie pamięci ........................................................... 43
Kurs C++
4
1. Wielkie i małe litery
C++ rozróżnia wielkie i małe litery (ważne przy deklaracji zmiennych!) , polecenia C++ piszemy
zawsze małymi literami.
Przykład 1.1
#include <iostream>
using namespace std;
int main()
{
int zmienna, ZMIENNA, Zmienna;
zmienna=1;
ZMIENNA=2;
Zmienna=3;
cout << „Zmienne to: ” << endl;
cout << zmienna << „\n” << ZMIENNA << „\n” << Zmienna << „\n” <<
Zmienna << „\n”;
}
2. Komentarze
Komentarz składający się z jednej linii rozpoczynamy
//. Komentarz składający się z kilku linijek
rozpoczynamy
/* i kończymy */.
Przykład 2.1
#include <iostream>
using namespace std;
int main()
{
// Komentarz zajmujacy jedną linijke
cout << „Bla bla bla”;
/* Komentarz zajmujący wiecej
niz jedna linijke */
cout << „bla bla bla”;
}
3. Słowa kluczowe
Słowo kluczowe to identyfikator w C++ zarezerwowany dla określonych zadań. Deklarowana zmienna
nie może być słowem kluczowym.
Kurs C++
5
Tabela 3.1. Słowa kluczowe
Słowo kluczowe
Znaczenie
Słowo kluczowe
Znaczenie
asm
new
auto
operator
bool
private
break
przerwij
protected
case
„jeśli” w wyborze
wielokrotnym
public
catch
register
char
zmienna znakowa
reinterpret_cast
class
return
zwróć
const
short
const_cast
signed
continue
sizeof
default
static
delete
static_cast
do
wykonuj w pętli „do-
while”
struct
double
zmienna rzeczywista
switch
testuj zmienną (w
wyborze
wielokrotnym)
dynamic_cast
template
else
w pozostałym
przypadku
this
enum
throw
explicit
true
prawda
extern
try
false
fałsz
typedef
float
zmienna rzeczywista
typeid
for
identyfikator pętli
typename
friend
union
goto
unsigned
if
identyfikator instrukcji
warunkowej
using
inline
virtual
int
zmienna całkowita
void
long
volatile
mutable
wchar_t
namespace
while
identyfikator pętli
Tabela 3.2. Leksemy alternatywne
Leksem
Znaczenie
and
&&
and_eq
&=
bitand
&
bitor
|
compl
~
not
!
not_eq
!=
or
||
Kurs C++
6
or_eq
|=
xor
^
xor_eq
^=
4. Funkcja return
Funkcja
return zwraca wartość zdefiniowaną w funkcji.
Przykład 4.1
#include <iostream>
using namespace std;
int dodawanie(int x, int y)
{
return x+y;
}
int main()
{
int x, y;
cout << „Podaj 1 liczbe: “;
cin >> x;
cout << „Podaj 2 liczbe: “;
cin >> y;
cout << „Wynik dodawania liczb ” << x << „ i ” << y << „ to ” <<
dodawanie(x,y);
}
5. Dyrektywa #include
Dyrektywa służy do włączania do pliku źródłowego bibliotek standardowych (np. iostream) lub innych
plików nagłówkowych (tworzonych przez użytkownika). Nawiasy <> służą do dołączania bibliotek
standardowych, natomiast „” do dołączania własnych plików nagłówkowych.
6. Deklaracja stałych
Z chwilą deklarowania zmiennych możemy od razu przypisać im konkretne wartości.
Przykład 6.1
#include <iostream>
using namespace std;
int main()
{
int x=5;
cout << x;
}
Kurs C++
7
Deklarowana wartość może być w każdym miejscu skryptu zmieniona (może osiągnąć inną wartość).
Jeśli zachodzi konieczność aby zmienna zachowała w obrębie całego programu tą samą wartość (aby nie
można jej było zmienić), to wykorzystujemy w tym celu słowo kluczowe
const.
Przykład 6.2
#include <iostream>
using namespace std;
int main()
{
const int x=5;
cout << x;
}
7. Deklaracja zmiennych
Zmienna musi zostać zadeklarowana zanim zaczniemy jej używać. Deklaracja zmiennej powoduje
rezerwację miejsca w pamięci.
Tabela 7.1. Podstawowe typy zmiennych
Zmienna
Opis zmiennej
Zakres wartości (pamięć)
bool
Zmienna boole’owska (true/false)
0 lub 1 (1b)
unsigned
short int
Liczba całkowita krótka (dodatnia)
0÷65535 (2B)
short int
Liczba całkowita krótka
-32768÷32767 (2B)
unsigned long
int
Liczba całkowita długa (dodatnia)
0 ÷ 4294967295 (4B)
long int
Liczba całkowita długa
-2147483648 ÷ 2147483647 (4B)
int
Liczba całkowita
-2147483648 ÷ 2147483647 (4B)
unsigned int
Liczba całkowita (dodatnia)
0 ÷ 4294967295 (4B)
char
Zmienna znakowa
-128 ÷ 127 (1B)
float
Liczba rzeczywista (do 7 miejsc po
przecinku)
1,2x10
-38
÷ 3,4x10
38
(4B)
double
Liczba rzeczywista (do 15 miejsc po
przecinku)
2,2x10
-308
÷ 1,8x10
308
(8B)
Aby sprawdzić ile miejsca (w bajtach) w pamięci rezerwuje każdy typ zmiennej używamy funkcji
sizeof()
Przykład 7.1
#include <iostream>
using namespace std;
int main()
{
cout << “Zmienna int zajmuje w pamieci “ << sizeof(int) << “ bajtow”;
}
Kurs C++
8
Tabela 7.2. Podstawowe manipulatory
Manipulator
Znaczenie
\a
Dzwonek (Bell)
\n
Nowa linia
\b
Powrót o 1 znak
\r
Powrót na początek linii
\’
Apostrof
\\
Backslash
\t
Tabulator
\”
Cudzysłów
8. Operatory
Operand – zmienna lub wartość liczbowa sąsiadująca z operatorem
a) Operatory arytmetyczne
Tabela 8.1. Operatory arytmetyczne
Operator
Przykład
Zastosowanie
+
x+y
Suma x i y
-
x-y
Róznica x i y
*
x*y
Iloczyn x i y
/
x/y
Iloraz x i y
%
x%y
Reszta z dzielenia x przez y (tylko dla typów
int, short int, long int)
Przykład 8.1
#include <iostream>
using namespace std;
int main()
{
int x,y,z,w;
cout << „podaj 1 liczbe: ”;
cin >> x;
cout << „podaj 2 liczbe: ”;
cin >> y;
z=x+y;
w=x-y;
cout << “Suma wprowadzonych liczb wynosi “ << z << “, a roznica ” << w;
}
b) Operatory relacyjne
Operatory relacyjne zwracają wartość
true (gdy sprawdzany warunek jest prawdziwy) lub false (gdy
sprawdzany warunek jest fałszywy).
Kurs C++
9
Tabela 8.2. Operatory relacyjne
Operator
Przykład
Zastosowanie
<
x<y
x mniejsze od y
<=
x<=y
x mniejsze lub równe y
>
x>y
x większe od y
>=
x>=y
x większe lub równe y
!=
x!=y
x różne od y
==
x==y
x równe y
Przykład 8.2
#include <iostream>
using namespace std;
int main()
{
int x;
cout << „podaj liczbe: ”;
cin >> x;
if (x>10)
{
cout << “Wprowadzona liczba jest wieksza od 10”;
}
else
{
cout << “Wprowadzona liczba jest mniejsza lub rowna 10”;
}
}
c) Operatory logiczne
Tabela 8.3. Operatory logiczne
Operator
Znaczenie
&&
and - część wspólna (iloczyn logiczny)
||
or – suma logiczna
!
not - negacja
Przykład 8.3
#include <iostream>
using namespace std;
int main()
{
int x;
cout << „podaj liczbe: ”;
cin >> x;
if ((x>10)&&(x<=15))
Kurs C++
10
{
cout << “Wprowadzona liczba nalezy do przedzialu (10,15>”;
}
else
{
cout << “Wprowadzona liczba jest mniejsza rowna 10 lub wieksza od
15”;
}
}
d) Bitowe operatory logiczne
Tabela 8.4. Bitowe operatory logiczne
Operator
Przykład
Nazwa
|
x|y
Alternatywa bitowa
&
x&y
Koniunkcja bitowa
^
x^y
Bitowa różnica symetryczna
<<
x<<y
Bitowe przesunięcie w lewo
>>
x>>y
Bitowe przesunięcie w prawo
~
~x
Negacja bitowa
Przykład 8.4
#include <iostream>
using namespace std;
int main()
{
unsigned int x,y;
cout << „podaj 1 liczbe: ”;
cin >> x;
cout << „podaj 2 liczbe: ”;
cin >> y;
cout << “1. Bitowa alternatywa liczb “ << x << „ i ” << y << „ wynosi „
<< (x|y) << endl;
cout << “2. Bitowa koniunkcja liczb “ << x << „ i ” << y << „ wynosi „
<< (x&y) << endl;
cout << “3. Bitowa roznica symetryczna liczb “ << x << „ i ” << y << „
wynosi „ << (x^y) << endl;
cout << “4. Bitowa negacja liczby “ << x << „ wynosi „ << (~x) << endl;
cout << “5. Bitowe przesuniecie w lewo liczby “ << x << „ o liczbe ” <<
y << „ wynosi „ << (x<<y) << endl;
cout << “6. Bitowe przesuniecie w prawo liczby “ << x << „ o liczbe ”
<< y << „ wynosi „ << (x>>y) << endl;
}
Dla licz x=50 i y=4 dostajemy:
1. Bitowa alternatywa liczb 50 i 6 wynosi 54
Kurs C++
11
2. Bitowa koniunkcja liczb 50 i 6 wynosi 2
3. Bitowa roznica symetryczna liczb 50 i 6 wynosi 52
4. Bitowa negacja liczby 50 wynosi 4294967245
5. Bitowe przesuniecie w lewo liczby 50 o liczbe 6 wynosi 3200
6. Bitowe przesuniecie w prawo liczby 50 o liczbe 6 wynosi 0
Zapisując liczby 50 i 6 w systemie otrzymujemy:
(50)
10
=(110010)
2
i (6)
10
=(110)
2
Ad. 1
Zapisujemy liczby 50 i 6 w systemie binarnym jedną pod drugą (uzupełniając krótszą liczbę zerami z
lewej strony aby dwie liczby miały tą samą długość)
50
1 1
0 0
1
0
6
0 0 0
1 1
0
50|6
↓
1
↓
1
↓
0
↓
1
↓
1
↓
0
Jeśli na tych samych pozycjach jednej i drugiej liczby mamy co najmniej jedną jedynkę to alternatywa
binarna
liczb będzie miała na tej samej pozycji jedynkę binarną. W pozostałych przypadkach mamy 0 binarne.
Dostajemy zatem liczbę
11
0
11
0, co po przeliczeniu na system dziesiętny daje liczbę 54
Ad. 2
50
1 1
0 0
1
0
6
0 0 0
1 1
0
50&6
↓
0
↓
0
↓
0
↓
0
↓
1
↓
0
Jeśli na tych samych pozycjach jednej i drugiej liczby mamy dwie jedynki to koniunkcja binarna
liczb będzie miała na tej samej pozycji jedynkę binarną. W pozostałych przypadkach mamy 0 binarne.
Dostajemy zatem liczbę
0000
1
0, co po przeliczeniu na system dziesiętny daje liczbę 2
Ad. 3
50
1 1
0 0
1
0
6
0 0 0
1 1
0
50^6
↓
1
↓
1
↓
0
↓
1
↓
0
↓
0
Jeśli na tych samych pozycjach jednej i drugiej liczby mamy tylko jedną jedynkę to binarna różnica
symetryczna liczb będzie miała na tej samej pozycji jedynkę binarną. W pozostałych przypadkach mamy
0 binarne.
Dostajemy zatem liczbę
11
0
1
00, co po przeliczeniu na system dziesiętny daje liczbę 52
Ad. 4
Zmienna typu
unsigned int zajmuje w pamięci 4B=32 bity. Uzupełniamy liczbę x=6 (110) zerami z
lewej strony aby miała długość 32 bity.
Kurs C++
12
50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1
0 0
1
0
~
50
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
1
↓
0
↓
0
↓
1
↓
1
↓
0
↓
1
Jeśli na tych samych pozycjach jednej i drugiej liczby mamy tylko jedną jedynkę to binarna różnica
symetryczna liczb będzie miała na tej samej pozycji jedynkę binarną. W pozostałych przypadkach mamy
0 binarne.
Dostajemy zatem liczbę
11111111111111111111111111
00
11
0
1
, co po przeliczeniu na system
dziesiętny daje liczbę 4294967245
Ad. 5
50
1 1 0 0 1 0
50<<6
1 1 0 0 1 0
0 0 0 0 0 0
Bitowe przesunięcie o liczbę 6 w lewo polega na dopisaniu 6 zer z prawej strony liczby przesuwanej.
Dostajemy zatem liczbę
110010
000000, co po przeliczeniu na system dziesiętny daje liczbę 3200
Ad. 6
50
1 1 0 0 1 0
50>>6
0 0 0 0 0 0
Bitowe przesunięcie o liczbę 6 w prawo polega na usunięciu z prawej strony 6 cyfr liczby przesuwanej.
Dostajemy zatem liczbę
000000, co po przeliczeniu na system dziesiętny daje liczbę 0.
9. Funkcje
Funkcja to podprogram, który jest realizowany w chwili wywołania. Po zakończeniu wykonywania
funkcji sterowanie jest przekazane do kolejnej linii kodu programu (po linii w której następuje wywołanie
funkcji). Konstrukcja funkcji:
typ_danych nazwa_fun(typ_zmiennej_1 zmienna_1, typ_zmiennej_2 zmienna_2,…)
Przykład 9.1. Mnożenie dwóch liczb
#include <iostream>
using namespace std;
float mnozenie(float x, float y)
{
return x*y;
}
int main()
{
float x, y;
cout << „Podaj 1 liczbe: “;
cin >> x;
Kurs C++
13
cout << „Podaj 2 liczbe: “;
cin >> y;
cout << „Iloczyn liczb ” << x << „ i ” << y << „ to ” << mnozenie(x,y);
}
Przykład 9.2 Mnożenie dwóch liczb (typ
void)
#include <iostream>
using namespace std;
void mnozenie(float x, float y)
{
cout << "Iloczyn liczb " << x << " i " << y << " to " << x*y;
}
int main()
{
float x, y;
cout << "Podaj 1 liczbe: ";
cin >> x;
cout << "Podaj 2 liczbe: ";
cin >> y;
mnozenie(x,y);
}
Typ
void oznacza, że funkcja nie zwraca wartości (jak ma to miejsce w funkcjach typu całkowitego lub
rzeczywistego).
10. Instrukcje warunkowe
Występują dwa typy funkcji warunkowej:
a) instrukcja niepełna (wybór niepełny):
if(warunek)
{
lista_instrukcji;
}
b) instrukcja pełna (wybór pełny)
if(warunek)
{
lista_instrukcji;
}
else
{
lista_instrukcji_2;
}
Instrukcje warunkowe można zagnieżdżać.
Kurs C++
14
Przykład 10.1 Sprawdzanie, czy liczba jest parzysta
#include <iostream>
using namespace std;
int main()
{
int x;
cout << "Podaj liczbe: ";
cin >> x;
if(x%2==0)
{
cout << „Liczba ” << x << “ jest parzysta”;
}
else
{
cout << „Liczba ” << x << “ nie jest parzysta”;
}
}
Przykład 10.2 Zagnieżdżanie instrukcji warunkwych
#include <iostream>
using namespace std;
int main()
{
int x;
cout << "Podaj liczbe: ";
cin >> x;
if(x==1)
{
cout << „Wpisano jedynke”;
}
else
{
if(x==2)
{
cout << „Wpisano liczbe dwa”;
}
else
{
cout << „Wpisano inna liczbe niz jeden i dwa”;
}
}
}
11. Instrukcja
switch
Instrukcja
swich pozwala przetestować i wybrać (w przypadku spełnienia warunku) spośród wielu
dostępnych wartości. Konstrukcja
switch:
Kurs C++
15
switch(zmienna)
{
case 1_wartosc_zmiennej:
lista_instrukcji_1;
break;
case 2_wartosc_zmiennej:
lista_instrukcji_2;
break;
...
case n_wartosc_zmiennej:
lista_instrukcji_n;
break;
default:
inna_lista_instrukcji;
}
Przykład 11.1. Kalkulator
#include <iostream>
using namespace std;
int main()
{
float x,y;
char dzialanie;
cout << "Podaj 1 liczbe: ";
cin >> x;
cout << "Podaj 2 liczbe: ";
cin >> y;
cout << "Podaj rodzaj dzialania (+,-,*,/): ";
cin >> dzialanie;
switch(dzialanie)
{
case ‘+’:
cout << „Suma liczb wynosi „ << x+y;
break;
case ‘-’:
cout << „Roznica liczb wynosi „ << x-y;
break;
case ‘*’:
cout << „Iloczyn liczb wynosi „ << x*y;
break;
case ‘/’:
cout << „Iloraz liczb wynosi „ << x/y;
break;
default:
cout << „Dzialanie zle okreslone „ ;
}
}
Kurs C++
16
Przykład 11.2. Sprawdzanie ile wynosi reszta z dzielenia wprowadzonej liczby przez 4.
#include <iostream>
using namespace std;
int main()
{
int x,y;
cout << "Podaj liczbe naturalna: ";
cin >> x;
y=x%4;
cout << „Reszta z dzielenia liczby „ << x << „ przez 4 wynosi „;
switch(y)
{
case 1:
cout << „jeden”;
break;
case 2:
cout << „dwa”;
break;
case 3:
cout << „trzy”;
break;
default:
cout << „zero”;
}
}
12. Pętla
while i do while
a) Pętla
while
Pętla
while jest pętlą 0-∞-krotną, tzn. może nie być wykonana ani razu (przy odpowiednim
warunku). Lista instrukcji jest wykonywana tylko w przypadku spełnienia określonego warunku (lub
warunków) zdefiniowanego na początku pętli.
Konstrukcja:
while (warunek)
{
lista instrukcji;
}
Przykład 12.1. Sumowanie liczb naturalnych od 1 do n
#include <iostream>
using namespace std;
int main()
{
unsigned int n,i,s;
cout << „Podaj liczbe naturalna wieksza od 1: „;
cin >> n;
i=1;
Kurs C++
17
s=0;
while(i<=n)
{
s=s+i;
i=i+1;
}
cout << „Suma liczb naturalnych od 1 do „ << n << „ wynosi „ << s;
}
b) Pętla
do while
Pętla
do while jest pętlą 1-∞-krotną, tzn. musi być wykonana co najmniej raz. Przy pierwszym
obiegu pętli najpierw jest wykonywana lista instrukcji, a dopiero potem jest sprawdzany warunek.
Jeśli warunek jest spełniony, to następuje drugi obieg pętli, itd. Konstrukcja:
do
{
lista instrukcji;
}
while (warunek);
Przykład 12.2. Sumowanie liczb naturalnych od 1 do n (ze sprawdzaniem czy n jest większe od 1)
#include <iostream>
using namespace std;
int main()
{
int n,i,s;
do
{
cout << „Podaj liczbe naturalna wieksza od 1: „;
cin >> n;
}
while (n<=1);
i=1;
s=0;
while(i<=n)
{
s=s+i;
i=i+1;
}
cout << „Suma liczb naturalnych od 1 do „ << n << „ wynosi „ << s;
}
13. Pętla
for
Pętla
for jest pętlą iteracyjną (krokową). Konstrukcja:
Kurs C++
18
for(instrukcja_poczatkowa; warunek; instrukcja_krokowa)
{
lista_instrukcji;
}
instrukcja_poczatkowa polega z reguły na przypisaniu wartości początkowej pewnej zmiennej z
opcjonalnym określeniem typu zmiennej;
warunek określa sprawdzany na początku, a potem w trakcie pętli warunek decydujący o ponownym
wykonaniu (lub pierwszym wykonaniu) instrukcji zawartych w pętli;
instrukcja_krokowa określa krok pętli (rosnący lub malejący);
Przykład 13.1. Program wypisujący liczby naturalne od 1 do n
#include <iostream>
using namespace std;
int main()
{
unsigned int n,i;
cout << „Podaj liczbe naturalna wieksza od 1: „;
cin >> n;
for(i=1;i<=n;i++)
{
cout << i << ”,”;
}
}
Przykład 13.2. Program sprawdzający, czy liczba jest pierwsza.
#include <iostream>
using namespace std;
int main()
{
unsigned int n,i,t;
cout << „Podaj liczbe naturalna wieksza od 1: „;
cin >> n;
t=0;
for(i=2;i<n;i++)
{
if(n%i!=0)
{
t=t+1;
}
}
if(t==n-2)
{
cout << „Liczba „ << n << „ jest pierwsza”;
}
else
{
Kurs C++
19
cout << „Liczba „ << n << „ nie jest pierwsza”;
}
}
14. Typ tablicowy
a) Tablice jednowymiarowe
Aby zadeklarować tablicę należy podać jej typ (typ danych zawartych w tablicy), nazwę (identyfikator)
i rozmiar. Elementy w tablicy są numerowane od zera. Deklaracja tablicy:
typ nazwa_tablicy[ilosc_elementow];
Np. deklaracja
int tab[4] oznacza tablicę składającą się z 4 elementów całkowitych mających postać:
tab[0], tab[1], tab[2], tab[3].
Przykład 14.1. Wypełnianie i wypisywanie elementów tablicy za pomocą pętli
#include <iostream>
using namespace std;
int main()
{
int i;
int tab[5];
for(i=0;i<=4;i++)
{
cout << “Podaj “ << i+1 << “ element tablicy: “;
cin >> tab[i];
}
for(i=0;i<=4;i++)
{
cout << i+1 << „ element tablicy jest rowny “ << tab[i] << “\n“;
}
}
Jeśli chcemy zadeklarować tablicę z wypełnionymi wartościami, to używamy zapisu:
typ nazwa_tablicy[]={element_1, element_2, ..., element_n};
W tym wypadku nie musimy podawać wymiaru tablicy.
Przykład 14.2. Wypisanie elementów zadeklarowanej (wypełnionej) tablicy.
#include <iostream>
using namespace std;
int main()
{
int i;
int tab[]={2,3,5,6,7};
Kurs C++
20
for(i=0;i<=4;i++)
{
cout << i+1 << „ element tablicy jest rowny “ << tab[i] << “\n“;
}
}
Przykład 14.3
#include <iostream>
using namespace std;
int main()
{
int i;
char decyzja;
char
tab[]={‘a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’,’i’,’j’,’k’,’l’,’m’,’n’,’o’,’p’,
’q’,’r’,’s’,’t’,’u’,’v’,’w’,’x’,’y’,’z’};
do
{
do
{
cout << “Podaj liczbe od 1 do 26: “;
cin >> i;
}
while((i<1)||(i>26));
cout << i << „ litera alfabetu to „ << tab[i-1] << „\n”;
cout << „Jesli chcesz sprawdzic kolejna litere wcisnij \”t\”: „;
cin >> decyzja;
}
while(decyzja==’t’);
}
b) Tablice wielowymiarowe
Tablica wielowymiarowa jest zbiorem tablic jednowymiarowych, tzn. elementami tablicy są tablice.
Deklaracja tablicy wielowymiarowej:
typ nazwa_tablicy[wymiar_1][wymiar_2];
Np. zapis
int tab[3][2] oznacza deklarację tablicy składającej się z 3 tablic, z których każda zawiera
2 elementy.
Jej elementami są:
tab[1][1], tab[1][2], tab[2][1], tab[2][2], tab[3][1],
tab[3][2].
Przykład 14.4 Wprowadzanie imion i nazwisk do bazy (za pomocą pętli) i szukanie osób w bazie o
podanym nazwisku.
#include <iostream>
using namespace std;
Kurs C++
21
int main()
{
int i,j,s;
string tab[5][2];
string nazw;
for(i=0;i<=4;i++)
{
for(j=0;j<=1;j++)
{
if (j==0)
{
cout << “Podaj “ << i+1 << “ imie ”;
}
else
{
cout << “Podaj “ << i+1 << “ nazwisko ”;
}
cin >> tab[i][j];
}
}
cout << „Podaj nazwisko: „;
cin >> nazw;
s=0;
for(i=0;i<=4;i++)
{
if (tab[i][1]==nazw)
{
cout << tab[i][0] << „\n”;
s=s+1;
}
}
if(s==0)
{
cout << „Nie ma osob o podanym nazwisku”;
}
}
15. Struktury danych
Struktura służy do operowania zbiorami danych różnych typów (tekst, liczba). Jeśli chcemy przechować
dane różnych typów używamy struktury definiując z osobna jej poszczególne elementy. Deklaracja
struktury:
struct nazwa_struktury
{
typ_1 element_1;
typ_2 element_2;
...
typ_n element_n;
};
Kurs C++
22
Przykład 15.1. Struktura
#include <iostream>
using namespace std;
struct sam
{
string marka_model;
int rok_prod;
};
int main()
{
sam peugeot={“Peugeot 106”,2000};
sam skoda={“Skoda Octavia”,2010};
cout << peugeot.marka_model << “\n”;
cout << peugeot.rok_prod << “\n”;
}
Przykład 15.2. Tablica struktur (tablica typu strukturalnego)
#include <iostream>
using namespace std;
struct sam
{
string marka_model;
int rok_prod;
};
int main()
{
int i;
sam tab[3]={{“Peugeot 106”,2000}, {“Skoda Octavia”,2010}, {“Honda
Civic”,2003}};
cout << „Dostepne sa samochody: “ << “\n”;
for(i=0;i<=2;i++)
{
cout << tab[i].marka_model << „\n”;
}
}
Przykład 15.2. Baza danych - tablica struktur (tablica typu strukturalnego)
#include <iostream>
using namespace std;
struct sam
{
string marka;
string model;
Kurs C++
23
int rok;
int poj;
int przebieg;
int cena;
};
int main()
{
int i,k,pmax,pmin,szukanie,rmin,rmax,prmin,prmax,cmin,cmax;
string szukanamarka, szukanymodel;
char decyzja;
sam tab[20]={
{"Peugeot", "106",2000,1000,115000,5000},
{"Opel", "Astra",1995, 1600, 104000, 4000},
{"Fiat","Cinquecento",1993, 700, 105000, 3000},
{"Audi", "80", 1990, 1600, 340000, 2500},
{"Opel", "Astra", 1998, 1600, 198000, 10500},
{"Fiat", "Panda", 2004, 1100, 40000, 10000},
{"Toyota", "Yaris", 2010, 1400, 10000, 40000},
{"Renault", "Megane", 1998, 1400, 140500, 5000},
{"Opel", "Astra", 1996, 1600, 235000, 3000},
{"VW", "Golf II", 1992, 1800, 210000, 2500},
{"Skoda", "Fabia", 2009, 1600, 20000, 35000},
{"Mercedes", "A170", 2005, 1600, 90000, 25000},
{"Mitsubishi", "Lancer", 2009, 1800, 30000, 40000},
{"Subaru","Impreza", 2010, 2500, 1000, 50000},
{"Mazda", "RX-8", 2008, 1300, 45000, 60000},
{"Bugatti", "Veyron", 2009, 8000, 10000,3500000},
{"Porsche", "911", 2009, 4500, 6000, 150000},
{"Fiat", "125p", 1985, 1300, 150000, 1500},
{"BMW", "M3", 2010, 4000, 20000, 200000},
{"Ford", "Fusion", 2010, 1600, 1000, 45000}
};
do
{
system("cls");
cout << "Podaj kryterium wyszukiwania \n 1-marka \n 2-model \n 3-
rok produkcji \n 4-pojemnosc \n 5-przebieg \n 6-cena \n Wybieram:
";
cin >> szukanie;
switch(szukanie)
{
case 1:
{
cout << "Podaj marke samochodu: ";
cin >> szukanamarka;
k=0;
for (i=0;i<=19;i++)
{
if (tab[i].marka==szukanamarka)
{
Kurs C++
24
cout << tab[i].marka << " " << tab[i].model
<< ", rok produkcji: " << tab[i].rok << "r"
<< ", pojemnosc: " << tab[i].poj << " cm3" <<
", przebieg: " << tab[i].przebieg << " km" <<
", cena: " << tab[i].cena << " zl" << "\n";
k=k+1;
}
}
if (k==0)
cout << "Nic nie znaleziono" << "\n";
break;
}
case 2:
{
cout << "Podaj model samochodu: ";
cin >> szukanymodel;
k=0;
for (i=0;i<=19;i++)
{
if (tab[i].model==szukanymodel)
{
cout << tab[i].marka << " " << tab[i].model
<< ", rok produkcji: " << tab[i].rok << "r"
<< ", pojemnosc: " << tab[i].poj << " cm3" <<
", przebieg: " << tab[i].przebieg << " km" <<
", cena: " << tab[i].cena << " zl" << "\n";
k=k+1;
}
}
if (k==0)
cout << "Nic nie znaleziono" << "\n";
break;
}
case 3:
{
cout << "Podaj rok produkcji min: ";
cin >> rmin;
cout << "Podaj rok produkcji max: ";
cin >> rmax;
k=0;
for (i=0;i<=19;i++)
{
if ((tab[i].rok>=rmin) && (tab[i].rok<=rmax))
{
cout << tab[i].marka << " " << tab[i].model
<< ", rok produkcji: " << tab[i].rok << "r"
<< ", pojemnosc: " << tab[i].poj << " cm3" <<
", przebieg: " << tab[i].przebieg << " km" <<
", cena: " << tab[i].cena << " zl" << "\n";
k=k+1;
}
Kurs C++
25
}
if (k==0)
cout << "Nic nie znaleziono" << "\n";
break;
}
case 4:
{
cout << "Podaj pojemnosc min: ";
cin >> pmin;
cout << "Podaj pojemnosc max: ";
cin >> pmax;
k=0;
for (i=0;i<=19;i++)
{
if ((tab[i].poj>=pmin) && (tab[i].poj<=pmax))
{
cout << tab[i].marka << " " << tab[i].model
<< ", rok produkcji: " << tab[i].rok << "r"
<< ", pojemnosc: " << tab[i].poj << " cm3" <<
", przebieg: " << tab[i].przebieg << " km" <<
", cena: " << tab[i].cena << " zl" << "\n";
k=k+1;
}
}
if (k==0)
cout << "Nic nie znaleziono" << "\n";
break;
}
case 5:
{
cout << "Podaj przebieg min: ";
cin >> prmin;
cout << "Podaj przebieg max: ";
cin >> prmax;
k=0;
for (i=0;i<=19;i++)
{
if ((tab[i].przebieg>=prmin) &&
(tab[i].przebieg<=prmax))
{
cout << tab[i].marka << " " << tab[i].model
<< ", rok produkcji: " << tab[i].rok << "r"
<< ", pojemnosc: " << tab[i].poj << " cm3" <<
", przebieg: " << tab[i].przebieg << " km" <<
", cena: " << tab[i].cena << " zl" << "\n";
k=k+1;
}
}
if (k==0)
cout << "Nic nie znaleziono" << "\n";
break;
Kurs C++
26
}
case 6:
{
cout << "Podaj cene min: ";
cin >> cmin;
cout << "Podaj cene max: ";
cin >> cmax;
k=0;
for (i=0;i<=19;i++)
{
if ((tab[i].cena>=cmin) && (tab[i].cena<=cmax))
{
cout << tab[i].marka << " " << tab[i].model
<< ", rok produkcji: " << tab[i].rok << "r"
<< ", pojemnosc: " << tab[i].poj << " cm3" <<
", przebieg: " << tab[i].przebieg << " km" <<
", cena: " << tab[i].cena << " zl" << "\n";
k=k+1;
}
}
if (k==0)
cout << "Nic nie znaleziono" << "\n";
break;
}
default:
cout << "Zle kryterium wyszukiwania";
}
cout << "\n" << "Jesli chcesz wyszukac ponownie wciscij \"t\": ";
cin >> decyzja;
}
while(decyzja=='t');
}
16. Klasy
Klasa służy do operowania zbiorami danych różnych typów (składowe klasy) przydzielając im różne
uprawnienia (etykiety): public, private, protected oraz zezwala na implementowanie funkcji składowych
operujących na składowych tej klasy. Deklaracja klasy:
class nazwa_klasy
{
private:
typy_składowych_1 lista_składowych_1;
funkcje_1;
public:
typy_składowych_2 lista_składowych_2;
funkcje_2;
};
Obiekt – grupa składowych klasy wraz z funkcjami odnoszącymi się do tych składowych
Funkcja składowa – funkcja wchodząca w skład klasy
Kurs C++
27
Przykład 16.1. Program „Przedstaw się”.
#include<iostream>
using namespace std;
//deklaracja klasy
class osoba
{
//deklaracja składowych wraz z atrybutami
public:
string imie;
string nazwisko;
int wiek;
void przedstawsie();
};
//definiowanie składowej funkcyjnej
void osoba::przedstawsie()
{
cout << "Nazywam sie " << imie << " " << nazwisko << endl;
cout << "Mam " << wiek << " lat." << endl;
}
int main()
{
//tworzenie obiektów
osoba czlowiek1;
osoba czlowiek2={"Adam","Nowak",30};
czlowiek1.imie="Jan";
czlowiek1.nazwisko="Kowalski";
czlowiek1.wiek = 40;
//wywołanie funkcji
czlowiek1.przedstawsie();
czlowiek2.przedstawsie();
system("Pause");
}
Przykład 16.2. Tablica klas– baza danych „Osoby”
#include<iostream>
using namespace std;
class osoba
{
public:
string imie;
string nazwisko;
int wiek;
void dane();
};
void osoba::dane()
{
cout << imie << ", " << nazwisko << ", " << wiek << " lat" << endl;
}
Kurs C++
28
int main()
{
int s;
// tworzenie tablicy obiektów klasy osoba
// każdy obiekt klasy będzie miał postać czlowiek[i]
osoba czlowiek[5]={
{"Jan", "Kowalski" ,30},
{"Adam", "Nowak", 40},
{"Marcin", "Krol", 27},
{"Pawel", "Brodziak", 19},
{"Dariusz", "Sukiennik", 19}
};
cout << "Ktora osobe chcesz wyszukac? ";
cin >> s;
cout << s << " osoba w bazie to " ;
// wywołanie funkcji
czlowiek[s-1].dane();
system("Pause");
}
Przykład 16.3. Tablica klas– baza danych „Osoby 2”
#include<iostream>
using namespace std;
class osoba
{
public:
string imie;
string nazwisko;
int wiek;
void dane();
};
void osoba::dane()
{
cout << imie << ", " << nazwisko << ", " << wiek << " lat" << endl;
}
int main()
{
string szukane;
int wybor, wiekmin, wiekmax;
osoba czlowiek[15]={
{"Jan", "Kowalski" ,30},
{"Adam", "Nowak", 40},
{"Marcin", "Krol", 27},
{"Pawel", "Brodziak", 19},
{"Adam", "Mickiewicz", 52},
{"Rychu", "Peja", 30},
{"Arnold", "Boczek", 55},
{"Ferdek", "Kiepski", 54},
Kurs C++
29
{"Marian", "Pazdzioch", 60},
{"John", "Rambo", 40},
{"Dzoana", "Krupa", 31},
{"Kuba", "Gminny", 45},
{"Adam", "Kurc", 35},
{"Turbo", "Dymomen", 25},
{"Super", "S", 40},
};
cout << "Podaj kryterium wyszukiwania (1-imie, 2-nazwisko, 3-wiek):" ;
cin >> wybor;
switch(wybor)
{
case 1:
{
cout << "Podaj imie: ";
cin >> szukane;
int k=0;
for(int i=0;i<15;i++)
{
if(czlowiek[i].imie==szukane)
{
czlowiek[i].dane();
k++;
}
}
if (k==0)
cout << "Nie ma osoby o podanym imieniu \n";
}
break;
case 2:
{
cout << "Podaj nazwisko: ";
cin >> szukane;
int k=0;
for(int i=0;i<15;i++)
{
if(czlowiek[i].nazwisko==szukane)
{
czlowiek[i].dane();
k++;
}
}
if (k==0)
cout << "Nie ma osoby o podanym nazwisku \n";
}
break;
case 3:
{
cout << "Podaj wiek min: ";
Kurs C++
30
cin >> wiekmin;
cout << "Podaj wiek max: ";
cin >> wiekmax;
int k=0;
for(int i=0;i<15;i++)
{
if((czlowiek[i].wiek>=wiekmin)&&(czlowiek[i].wiek<=wiek
max))
{
czlowiek[i].dane();
k++;
}
}
if (k==0)
cout << "Nie ma osoby o podanym wieku \n";
}
break;
default:
cout << "Zle kryterium wyszukiwania \n";
}
system("Pause");
}
17. Hermetyzacja
Hermetyzacja (kapsułkowanie) - ukrywaniu pewnych danych składowych lub funkcji składowych
danej klasy tak, aby były one dostępne tylko funkcjom z nią zaprzyjaźnionym. O hermetyzacji mówimy,
gdy wszystkie pola w klasie znajdują się w sekcji prywatnej.
Przykład 17.1. Program „Bankomat”
#include<iostream>
using namespace std;
class bankomat
{
private:
int pin;
int saldo;
public:
int uwierzytelnij(int pinnew);
int zapamietaj(int pinnew, int saldonew);
};
int bankomat::zapamietaj(int pinnew, int saldonew)
{
pin=pinnew;
saldo=saldonew;
};
Kurs C++
31
int bankomat:: uwierzytelnij(int pinnew)
{
if (pinnew==pin)
{
cout << "Twoje saldo wynosi " << saldo;
}
}
int main()
{
int pinnew,i,k;
bankomat klient[100];
klient[0].zapamietaj(11,1000);
klient[1].zapamietaj(12,2000);
cout << "Podaj pin: ";
cin >> pinnew;
for (i=0;i<=1;i++)
{
klient[i].uwierzytelnij(pinnew);
}
system("Pause");
}
18. Konstruktor i destruktor
Konstruktor i destruktor to funkcje składowe klasy. Konstruktor ma taką samą nazwę jak nazwa klasy,
a jego zadaniem jest budowanie obiektów swojej klasy. Takie budowanie obiektu powoduje, że komputer
przydziela obiektowi pamięć i przypisuje wartości do niestatycznych zmiennych składowych. Jeśli w
klasie nie zadeklarowano konstruktora to zostaną one stworzone automatycznie przez kompilator i użyte
w chwili tworzenia obiektu. W ciele konstruktora możemy nadać tworzonemu obiektowi wartości
początkowe. Obiekt podczas tworzenia za pomocą domyślnego konstruktora nie ma przypisanych
wartości początkowych dla swoich składowych.
Destruktor to funkcja, która ma nazwę taką samą jak klasa, której dotyczy i jest poprzedzona znakiem
~. Destruktor nie ma parametrów. Jest wywoływany zawsze automatycznie, gdy obiekt jest usuwany.
Zadaniem destruktora jest zwalnianie rezerwowanej dynamicznie podczas tworzenia obiektów pamięci
(dodatkowej pamięci zarezerwowanej podczas tworzenia obiektu). Destruktor ma za zadanie wykonać
czynności składające się na usunięcie obiektu (np. poinformowanie o usuwaniu obiektu) ale sam nie
usuwa obiektu i nie zwalnia miejsca w pamięci po usunięciu obiektu.
Przykład 18.1. Nadawanie wartości początkowych tworzonemu obiektowi za pomocą konstruktora
#include<iostream>
using namespace std;
class samochod
{
private:
string rok;
string marka;
public:
string model;
Kurs C++
32
string przebieg;
samochod();
};
samochod::samochod()
{
cout << "Do tej pory nasz obiekt ma dane: \n";
cout << "\n Marka: " << marka;
cout << "\n Rocznik: " << rok;
cout << "\n Przebieg: " << przebieg;
cout << "\n Model: " << model;
cout << "\n \n Teraz konstruktor nadaje poczatkowe wartosci danemu
obiektowi: \n";
marka="Peugeot";
model="106";
rok="2000";
przebieg="120000";
cout << "\n Konstruktor nadal wartosci: \n";
cout << "\n Marka: " << marka;
cout << "\n Model: " << model;
cout << "\n Rocznik: " << rok;
cout << "\n Przebieg: " << przebieg;
}
int main()
{
samochod PEUGEOT;
cout << "\n-----------------------------";
cout << "\n Przypisanie nowej wartosci do skladowej model i przebieg
\n";
PEUGEOT.model="206";
PEUGEOT.przebieg="65000";
cout << "\n Teraz model to: " << PEUGEOT.model << " i przebieg to: " <<
PEUGEOT.przebieg << "\n\n";
system("pause");
}
Przykład 18.2. Nadawanie wartości początkowych tworzonemu obiektowi za pomocą konstruktora
i informowanie za pomocą destruktora o usunięciu obiektu po skończeniu programu
#include<iostream>
using namespace std;
class samochod
{
private:
string rok;
string marka;
public:
string model;
string przebieg;
samochod();
~samochod();
Kurs C++
33
};
samochod::samochod()
{
cout << "Do tej pory nasz obiekt ma dane: \n";
cout << "\n Marka: " << marka;
cout << "\n Rocznik: " << rok;
cout << "\n Przebieg: " << przebieg;
cout << "\n Model: " << model;
cout << "\n \n Teraz konstruktor nadaje poczatkowe wartosci danemu
obiektowi: \n";
marka="Peugeot";
model="106";
rok="2000";
przebieg="120000";
cout << "\n Konstruktor nadal wartosci: \n";
cout << "\n Marka: " << marka;
cout << "\n Model: " << model;
cout << "\n Rocznik: " << rok;
cout << "\n Przebieg: " << przebieg;
}
samochod::~samochod()
{
cout << “\n Obiekt PEUGEOT zostal zniszczony \n”;
}
int main()
{
samochod PEUGEOT;
cout << "\n-----------------------------";
cout << "\n Przypisanie nowej wartosci do skladowej model i przebieg
\n";
PEUGEOT.model="206";
PEUGEOT.przebieg="65000";
cout << "\n Teraz model to: " << PEUGEOT.model << " i przebieg to: " <<
PEUGEOT.przebieg << "\n\n";
PEUGEOT.~samochod();
system("pause");
}
19. Zagnieżdżona definicja klasy
Z zagnieżdżoną definicją klasy mamy do czynienia, gdy wewnątrz jednej klasy definiujemy inną klasę
(klasa w klasie). Konstrukcja:
class klasa_1
{
private:
skladowe_klasy_1;
public:
skladowe_klasy_1;
class klasa_2
Kurs C++
34
{
private:
skladowe_klasy_2;
public:
skladowe_klasy_2
};
};
Przykład 19.1. Konstruktory zagnieżdżonych klas
#include<iostream>
using namespace std;
class motocykl
{
public:
int rok;
string producent;
string model;
motocykl();
class kierowca
{
public:
int wiek;
string imie;
kierowca();
};
};
motocykl::motocykl()
{
producent="Romet";
model="Komar";
rok=1965;
cout << "\n Konstruktor nadal wartosci poczatkowe: \n";
cout << "\n Producent: " << producent;
cout << "\n Model: " << model;
cout << "\n Rok produkcji: " << rok;
}
motocykl::kierowca::kierowca()
{
wiek=60;
imie="Rajmund";
cout << "\n Imie kierowcy: " << imie;
cout << "\n Wiek kierowcy: " << wiek << " lat";
}
int main()
{
Kurs C++
35
motocykl MOTOR1;
motocykl::kierowca KIEROWCA1;
cout << "\n -----------------------------";
cout << "\n Motocyklem " << MOTOR1.producent << ", ";
cout << "\n model: " << MOTOR1.model << ", ";
cout << "\n rok: " << MOTOR1.rok << ", ";
cout << "\n jedzie kierowca o imieniu " << KIEROWCA1.imie;
cout << "\n i ma on " << KIEROWCA1.wiek << " lat \n \n";
system("Pause");
}
20. Przeciążenie funkcji
W języku C++ możliwe jest utworzenie wielu funkcji mających tą samą nazwę. W tym wypadku
identyfikator funkcji określamy jako przeciążony. Podczas wywołania funkcji wykonana jest ta funkcja
do której „pasują” parametry (typy zmiennych) i ilość parametrów.
Przykład 20.1. Przeciążenie funkcji
#include<iostream>
using namespace std;
int funkcja_przeciazona(int x, int y, int z)
{
return x*y*z;
}
void funkcja_przeciazona(string imie, int wiek)
{
cout << „Mam na imie „ << imie << „ i mam „ << wiek << „ lat.”;
}
int main()
{
cout << funkcja_przeciazona(3,4,5) << „\n”;
funkcja_przeciazona(„Marcin”,27);
}
21. Przeciążenie operatorów
Przeciążenie operatorów (przeładowanie operatorów) ma miejsce, gdy operatorom nadajemy nowe
funkcje. Konstrukcja:
typ_zwracany operator@(argumenty)
{
cialo_funkcji
}
gdzie @ oznacza odpowiedni operator.
Kurs C++
36
Tabela 20.1. Lista operatorów, które mogą być przeładowane
+ - *
/
$
^ & | ~ ! = < > += -= *=
/=
%= ^= &=
|= >> << >>= <<= == != >= <= && || ++ -- ->* -> new delete () [] ,
Przeładowanie może nadać operatorowi dowolne znaczenie. Nie można zmienić argumentowości
operatorów (np / musi być zawsze operatorem dwuargumentowym). Przynajmniej jeden z argumentów
funkcji operatora musi być typu zdefiniowanego przez użytkownika.
Przykład 20.1. Przeciążenie operatorów
#include<iostream>
using namespace std;
class liczba
{
public:
int a;
int b;
liczba(int wartosc=0);
liczba operator+(int);
};
liczba::liczba(int wartosc)
{
a=wartosc;
b=wartosc;
}
liczba liczba::operator+(int zmiana)
{
liczba rezultat;
rezultat.a=a+zmiana;
rezultat.b=b+2*zmiana;
return rezultat;
}
int main()
{
liczba pierwszaliczba(1);
liczba drugaliczba;
drugaliczba=pierwszaliczba+100;
cout << "Pierwsza skladowa pierwszej liczby ma wartosc " <<
pierwszaliczba.a << endl;
cout << "Druga skladowa pierwszej liczby ma wartosc " <<
pierwszaliczba.b << endl;
cout << "------------------------------------------------------\n";
cout << "Pierwsza skladowa drugiej liczby ma wartosc " << drugaliczba.a
<< endl;
cout << "Druga skladowa drugiej liczby ma wartosc " << drugaliczba.b
<< endl;
cout << "------------------------------------------------------\n";
Kurs C++
37
drugaliczba=drugaliczba+200;
cout << "A teraz pierwsza skladowa drugiej liczby ma wartosc " <<
drugaliczba.a << endl;
cout << "Druga skladowa drugiej liczby ma wartosc " << drugaliczba.b
<< endl;
}
21. Zapis i odczyt pliku
Przykład 21.1. Zapis do pliku tekstowego
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
ofstream zapisywanie;
//tworzenie obiektu ‘zapisywanie’
//należącego do klasy fstream
cout << "Zapisuje do pliku \n";
zapisywanie.open("plik.txt",ios::out);//skojarzenie obiektu
//‘zapisywanie’ z plikiem
//‘plik.txt’, plik nie musi
//istniec (zostanie utworzony, gdy
//nie istnieje lub zostanie
//nadpisany, gdy istnieje)
zapisywanie << "Test zapisu do pliku";
//zapisanie tekstu do pliku
zapisywanie.close();
//zamkniecie polaczenia z plikiem ‘plik.txt’
cout << "Zapisalem \n";
system("pause");
}
Przykład 21.2. Odczyt z pliku tekstowego
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
char notatka;
ifstream czytanie;
//tworzenie obiektu ‘czytanie’ należącego
//do klasy fstream
cout << "Odczytuje z pliku \n";
czytanie.open("plik.txt", ios::in); //skojarzenie obiektu ‘czytanie’
//z plikiem ‘plik.txt’
czytanie >> noskipws >> notatka;
//wczytanie pierwszego znaku
//z obiektu ‘czytanie’ do zmiennej
//notatka (manipulator ‘noskipws’
//„nakazuje” pobierac spacje)
while (!czytanie.eof())
//petla sprawdzajaca, czy osiagnelismy
Kurs C++
38
//koniec pliku (funcja eof()), zamiast
//‘(!czytanie.eof()’ mozna uzyc zapisu
//‘(czytanie.good()’
{
cout << notatka;
czytanie >> noskipws >> notatka;
};
czytanie.close();
//zamkniecie polaczenia z plikiem ‘plik.txt’
cout << "\n Przeczytalem \n";
system("pause");
}
Kojarzenie obiektu klasy
fstream z plikiem przebiega według schematu:
fstream obiekt;
obiekt.open(polozenie_i_nazwa_pliku,ios::tryb);
W przypadku nie podania trybu dla obiektu klasy
ifstream domyślnym trybem jest in (czytanie
istniejącego pliku), a dla obiektu klasy
ofstream – out (tworzenie lub nadpisanie pliku)
Tabela 21.1. Tryby klasy
ios
Tryb
Funkcja
ios::in
czytanie istniejącego pliku
ios::out
tworzenie nowego pliku lub nadpisanie istniejącego
ios::ate
ustawienie wskaźnika na koniec pliku
ios::app
dopisanie do pliku
22. Dziedziczenie
Przykład 22.1. Dziedziczenie składowej klasy podstawowej przez klasę pochodną
#include<iostream>
using namespace std;
class samochod
{
public:
string producent;
samochod();
~samochod();
};
class autobus:public samochod
{
public:
autobus();
~autobus();
};
samochod::samochod()
{
producent="Peugeot";
Kurs C++
39
}
autobus::autobus()
{
producent="Jelcz";
}
samochod::~samochod()
{
cout << "Peugeot zostal skasowany";
}
autobus::~autobus()
{
cout << "Jelcz zostal skasowany";
}
int main()
{
autobus nowy;
cout << nowy.producent;
system("pause");
}
23 Polimorfizm
Polimorfizm to różnorodność zachowania się metody (funkcji) w zależności od obiektu dla którego
zostaje wykonana (obiektu klasy podstawowej lub pochodnej).
24. Unie
Unia to typ danych pozwalający przechowywać zmienne różnego typu, ale tylko jedną wartość w danej
chwili. Deklaracja unii:
union nazwa_unii
{
skladowe_unii;
};
Przykład 24.1
#include<iostream>
#include<string>
using namespace std;
union rower
{
int numer_pasazera;
char imie_pasazera;
};
int main()
{
rower BMX, Salto;
Kurs C++
40
BMX.numer_pasazera=1;
Salto.numer_pasazera=2;
cout << "Rowerami jada pasazerowie o numerach " << BMX.numer_pasazera;
cout << " i " << Salto.numer_pasazera;
BMX.imie_pasazera='M';
Salto.imie_pasazera='A';
cout << "\n Teraz rowerami jada " << BMX.imie_pasazera;
cout << " i " << Salto.imie_pasazera;
cout << "\n Rowerem Salto dalej jedzie " << Salto.numer_pasazera;
system("pause");
}
25. Pola bitowe
Pola bitowe wykorzystujemy, gdy chcemy ograniczyć pamięć (zajmowane miejsce w pamięci)
deklarowanych typów zmiennych. Konstrukcja:
typ_zmiennej nazwa_zmiennej : ilosc_bitow;
Przykład 25.1
#include<iostream>
using namespace std;
struct test_pola_bitowego
{
unsigned int obwod1 :4;
int obwod2 : 4;
};
int main()
{
test_pola_bitowego kwadrat={15,15};
cout << "\n Dla unsigned int obwod wynosi " << kwadrat.obwod1;
cout << "\n Dla int obwod wynosi " << kwadrat.obwod2;
system("pause");
}
26. Wskaźniki
Wskaźniki to zmienne nie przechowujące danych, a jedynie ich adresy w pamięci komputera (wskazuje
początek zmiennej w pamięci). Aby określić adres zmiennej należy posłużyć się operatorem adresu &.
Przykład 26.1
#include<iostream>
using namespace std;
int main()
{
unsigned int zmienna1=8;
cout << “Adres zmiennej w pamieci komputera to “ << &zmienna1 << endl;
Kurs C++
41
cout << „Wartosc zmiennej to „ << zmienna << endl;
}
Do wskaźnika można przypisać adres konkretnego typu zmiennej. Aby zadeklarować wskaźnik do
przechowywani adresu zmiennej korzystamy z zapisu:
typ_zmiennej *nazwa_wskaznika=0;
Wskaźnik, którego wartość jest równa 0 określany jest jako null, tzn. nie wskazuje na żaden obiekt. aby
przypisać do wskaźnika adres konkretnej zmiennej należy posłużyć się zapisem:
typ_zmiennej=wartosc;
typ_zmiennej *nazwa_wskaznika=0;
nazwa_wskznika=&wartosc;
np.
unsigned int wiek=27;
//deklaracja zmiennej ‘wiek’ z wartoscia 27
unsigned int *wwiek=0; //deklaracja zmiennej wskaznikowej ‘wwiek’
//z wartoscia null
wwiek=&wiek;
//przypisanie do wskaznika ‘wwiek’ adresu
//zmiennej ‘wiek’
Operator dostępu pośredniego
* może służyć do odczytywania i zmieniania wartości zmiennej
przechowywanej pod adresem przechowywanym we wskaźniku, np.
unsigned int wiek=27;
//deklaracja zmiennej ‘wiek’ z wartoscia 27
unsigned int *wwiek=&wiek;
//deklaracja zmiennej wskaznikowej ‘wwiek’
//i przypisanie jej adresu zmiennej ‘wiek’
unsigned int nowy_wiek;
//deklaracja zmiennej ‘nowy_wiek’;
nowy_wiek=*wwiek;
//przypisanie zmiennej ‘nowy_wiek’ wartosci
//zmiennej ‘wiek’ za pomoca operatora dostepu
//posredniego * zmiennej wskaznikowej wwiek
//(*zmienna_wskaznikowa oznacza wartosc
//przechowywana pod adresem zmiennej
//‘zmienna_wskaxnikowa’
Operator dostępu pośredniego jest wykorzystywany zatem w dwóch wariantach
przy deklaracji zmiennej wskaźnikowej
typ_zmiennej *nazwa_wskaznika=0;
przy odczytywaniu lub zmianie wartości zmiennej
nowa_zmienna=*stara_zmienna //przypisanie do zmiennej ‘nowa_zmienna’
//wartości przechowywanej pod adresem
///‘*stara_zmienna’
lub
*stara_zmienna=nowa_zmienna //przypisanie wartosci ‘nowa_zmienna’ do
//zmiennej wskazywanej przez wskaznik
//‘stara_zmienna’
Kurs C++
42
Przykład 26.2. Manipulowanie danymi za pomocą wskaźników
#include<iostream>
using namespace std;
int main()
{
int mojwiek;
//deklaracja zmiennej ‘mojwiek’;
int *wwiek=0;
//deklaracja zmiennej wskaznikowej ‘wwiek’
mojwiek=5;
cout << “mojwiek: “ << mojwiek << “\n”;
wwiek=&mojwiek;
//przypisanie adresu zmiennej ‘mojwiek’
//do wskaznika ‘wwiek’
cout << „*wwiek: ” << *wwiek << „\n\n”;
//wypisanie wartosci zmiennej
//mojwiek za pomoca wartosci
//wskaznika ‘wwiek’
*wwiek=7;
//przypisanie wartosci zmiennej ‘mojwiek’ za pomoca
//wskaznika ‘wwiek’
cout << „*wwiek: ” << *wwiek << „\n”;
cout << „mojwiek: ” << mojwiek << „\n\n”;
mojwiek=9;
cout << „mojwiek: ” << mojwiek << „\n”;
cout << „*wwiek: ” << *wwiek << „\n”;
system(„pause”);
}
a) Zarządzanie pamięcią
new
Do rezerwacji pamięci służy słowo kluczowe
new. Następuje po nim nazwa typu obiektu dla którego
rezerwujemy pamięć. Dzięki temu kompilator wie, ile pamięci ma zarezerwować. Na przykład
new unsigned short int;
zarezerwuje 2 bajty na stercie (sterta – wolna pamięć programu nie przeznaczona na zmienne lokalne,
kod programu, zmienne globalne, rejestry). Wartością zwracaną przez
new jest adres w pamięci. Musi on
być przypisany do wskaźnika. Aby stworzyć na stercie miejsce dla konkretnej zmiennej możemy użyć
zapisu:
typ_zmiennej *nazwawskaznika;
wskaznik=new typ_zmiennej;
np.
unsigned short int *wskaznik;
//deklaracja zmiennej wskaznikowej ‘wskaznik’
wskaznik=new unsigned short int; //przypisanie do zmiennej wskaznikowej
//‘wskaznik’ nowego adresu w stercie
//i zarezerwowanie odpowiedniego obszaru
//pamieci
lub zapisu skróconego
Kurs C++
43
unsigned short int *wskaznik = new unsigned short int;
Zaletą sterty jest fakt, że pamięć w niej zarezerwowana jest dostępna tak długo, aż jej bezpośrednio
nie zwolnimy (w przeciwieństwie do zmiennych lokalnych, które są automatycznie czyszczone z
pamięci).
delete
Aby zwolnić pamięć na stercie należy użyć słowa kluczowego
delete. Np.
delete nazwa_wskaznika;
Usuwając wskaźnik kasujemy pamięć wskazywaną przez ten wskaźnik. Taka pamięć będzie mogła być
zarezerwowana przez kolejną instrukcję
new. sam wskaźnik nadal istnieje i będzie mu można przypisać
nowy adres.
Przykład 26.3. Rezerwacja i zwalnianie pamięci
#include<iostream>
using namespace std;
int main()
{
int zmiennalokalna=5;
int *wzmiennalokalna=&zmiennalokalna; //deklaracja zmiennej wskaznikowej
//’wzmiennalokalna’ i przypisanie
//jej adresu zmiennej
//‘zmiennalokalna’
int *wsterta=new int;
//deklaracja zmiennej wskaznikowej ‘wstarta’
//i przypisanie dla niej nowego adresu
//w stercie wraz z rezerwacja pamieci
*wsterta=7;
// przypisanie wartosci 7 do zmiennej wskazywanej przez
//wskaznik ‘wsterta’
cout << „zmiennalokalna: ” << zmiennalokalna << „\n”;
cout << „*wzmiennalokalna: ” << *wzmiennalokalna << „\n”;
cout << „*wsterta: ” << *wsterta << „\n”;
delete wsterta; //zwolnienie miejsca w pamieci dla wskaznika ‘wsterta’
wsterta=new int;
//rezerwacja i przypisanie nowego obszaru
//w pamieci dla wskaznika ‘wsterta’
*wsterta=9;
cout << „*wsterta: ” << *wsterta << „\n”;
delete wsterta;
system(„pause”);
}
Aby nie tracić obszarów na stercie należy pamiętać o zwolnieniu obszaru zajmowanego
(wskazywanego) przez wskaźnik po zakończeniu pracy ze wskaźnikiem.