1
P
ROGRAMOWANIE I
J
Ę
ZYK
C++
DR INŻ.
M
AŁGORZATA
A.
J
ANKOWSKA
P
OLITECHNIKA
P
OZNAŃSKA
W
YDZIAŁ
B
UDOWY
M
ASZYN I
Z
ARZĄDZANIA
I
NSTYTUT
M
ECHANIKI
S
TOSOWANEJ
POK
.
446,
TEL
.
+ 48 61 665-20-69
www.icpnet.pl/~mjank
2
L
ITERATURA
H. M. Deitel, P. J. Deitel, Arkana C++ Programowanie,
Wydawnictwo RM, Warszawa 1998.
S. Prata, Szkoła Programowania Język C++, Wydawnictwo Helion, Gliwice 2006.
B. Stroustrup, Język C++, Wydawnictwa Naukowo-Techniczne, Warszawa 2002.
J. Grębosz, Symfonia C++. Programowanie w języku C++ orientowane
obiektowo
, Tom 1,2,3, Oficyna Kallimach, Kraków 1999.
A. Zalewski, Programowanie w językach C i C++ z wykorzystaniem pakietu
Borland C++
, Wydawnictwo Nakom, Poznań 1996.
JĘZYK C/C++
VISUAL STUDIO
P. Besta, Visual Studio 2005. Programowanie z Windows API w języku C++,
Wydawnictwo Helion, Gliwice 2008.
3
L
ITERATURA
D. E. Knuth, Sztuka programowania. Tom1 Algorytmy podstawowe,
Wydawnictwa Naukowo-Techniczne, Warszawa 2002.
D. E. Knuth, Sztuka programowania. Tom2 Algorytmy seminumeryczne,
Wydawnictwa Naukowo-Techniczne, Warszawa 2002.
D. E. Knuth, Sztuka programowania. Tom3 Sortowanie i wyszukiwanie,
Wydawnictwa Naukowo-Techniczne, Warszawa 2002.
D. E. Knuth, Sztuka programowania. Tom4 Generowanie wszystkich krotek
i permutacji,
Wydawnictwa Naukowo-Techniczne, Warszawa 2002.
N. Wirth, Algorytmy + struktury danych = programy, Wydawnictwa
Naukowo-Techniczne, Warszawa 2004.
ALGORYTMY / PROGRAMOWANIE
INNE CIEKAWE POZYCJE LITERATUROWE
W. Duch, Fascynujący świat programów komputerowych,
Wydawnictwo Nakom, Poznań 1997.
4
W
YKŁAD
1 P
ROGRAMOWANIE W JĘZYKU
C/C
++
W
PROWADZENIE
5
JĘZYKI PROGRAMOWANIA
Język programowania – zbiór zasad określających ciąg symboli tworzących
program. Język programowania pozwala na precyzyjny
zapis zadań, które mają być wykonane przez komputer.
Podział języków programowania:
• języki maszynowe (kod maszynowy)
Dowolny komputer (ściśle mówiąc procesor komputera) bezpośrednio rozumie
jedynie swój własny język maszynowy, który zdefiniowany jest przez projekt
sprzętu tego komputera.
Każdy typ procesora ma swój własny język maszynowy. Mówi się więc, że języki
te są maszynowo zależne. Z tego właśnie powodu przenośność kodu
maszynowego jest bardzo mała.
Zapis programu w języku maszynowym wymaga użycia rozkazów danych
w postaci łańcuchów cyfr (ostatecznie sprowadzanych do 0 i 1). Instruują one
komputer w przeprowadzaniu najbardziej elementarnych działań.
Kod maszynowy może być również tworzony w procesie kompilacji (w przypadku
języków wysokiego poziomu) oraz asemblacji (w przypadku asemblera).
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
6
• języki asemblera
Języki asemblera należą do języków programowania niskiego poziomu.
Utworzone zostały na bazie języków maszynowych danego procesora. Każda
instrukcja programu napisanego w języku asemblera odpowiada jednej instrukcji
wykonywanej przez mikroprocesor.
Składnia języka asemblera zależy nie tylko od architektury procesora, ale
również od używanego asemblera (czyli programu, który tłumaczy program
napisany w języku asemblera na język maszynowy).
• języki wysokiego poziomu
Celem twórców języków wysokiego poziomu było przyśpieszenie oraz
ułatwienie procesu programowania.
Pojedyncze instrukcje programu realizują teraz konkretne zadania, a składnia
i słowa kluczowe mają maksymalnie ułatwić rozumienie kodu programu
zwiększając jednocześnie poziom abstrakcji.
Kod napisany w języku wysokiego poziomu nie jest bezpośrednio „rozumiany”
przez komputer. Program trzeba tłumaczyć bezpośrednio na język maszynowy za
pomocą kompilatora lub etapami najpierw na język asemblera przy pomocy
kompilatora, a następnie na język maszynowy przy pomocy asemblera.
Do języków wysokiego poziomu zaliczamy Fortran, C, C++, Pascal.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
7
HISTORIA C / C++
Język C
Dlaczego powstał ... ?
Dennis Ritchie z Bell Laboratories (początek lat 70. XX wieku) pracował nad
stworzeniem systemu operacyjnego Unix.
Zadanie wymagało użycia języka programowania, który umożliwiłby szybkie
tworzenie zwartych programów pozwalających na dobrą komunikację ze sprzętem.
Do tej pory wykorzystywano do podobnych celów język asembler, który jednak będąc
językiem niskiego poziomu powiązany jest ściśle z określonym typem procesora.
Chcąc uniezależnić tworzony system od konkretnego komputera Ritchie postanowił
opracować nowy język programowania wysokiego poziomu.
Jakie ma zalety ... ?
• Język C łączy wydajność i łatwość dostępu do sprzętu komputerowego
(cecha charakterystyczna dla języków niskiego poziomu) z ogólnością
i przenośnością oprogramowania (co charakteryzuje języki wysokiego
poziomu).
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
8
• Pozwala programować strukturalnie.
Programowanie strukturalne jest pewnym wzorcem programowania wymagającym
hierarchicznego dzielenia kodu na określone bloki. Założone funkcje realizowane
są począwszy od zadań początkowych i kontynuowane w logicznej kolejności.
Do zalecanych struktur należą instrukcje warunkowe (if, if ... else), pętle
(for, while, do while). Za wyjątkiem przypadków, w których jest to konieczne,
powinno się unikać instrukcji takich jak break, continue, swich.
• Udostępnia instrukcje, które odwołują się bezpośrednio do bitowej reprezentacji
danych w jednostce centralnej (CPU) co sprawia, że programy skompilowane
w języku C działają szybciej niż programy napisane w innych językach wysokiego
poziomu.
• Programy napisane w języku C mogą być z łatwością przeniesione na inne
platformy. Konieczna jest jedynie ponowna kompilacja.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
Zalet ciąg dalszy ...
• Jest to język proceduralny, czyli taki w którym kładziemy nacisk na budowę
algorytmu potrzebnego do wykonania określonego zadania (np. danych obliczeń).
Program dzielimy na mniejsze fragmenty (procedury) wykonujące dane zadanie.
Język C wspiera wspomniany paradygmat (model, wzorzec) programowania
poprzez dostarczenie odpowiednich mechanizmów do przekazywania
argumentów do funkcji oraz wyników z funkcji.
9
Język C++
Dlaczego powstał ... ?
Język C++ został stworzony przez Bjarne Stroustrup’a w Bell Laboratories (na
początku lat 80. XX wieku) jako rozszerzenie języka C głownie o abstrakcję
danych, programowanie obiektowe oraz programowanie ogólne.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
Jakie ma zalety ... ?
• Język C++ został utworzony w oparciu o język C (za nielicznymi wyjątkami C++
jest nadzbiorem języka C).
Dzięki temu programiści mają możliwość wyboru preferowanego dla danego
zadania sposobu programowania wliczając w to również wszystkie możliwości
jakie daje język C.
Jak powiedział sam Stroustrup:
„C++ został stworzony głownie po to, abym wraz ze swoimi przyjaciółmi nie musiał
programować w asemblerze, C i innych współczesnych językach wysokiego poziomu.
Chodziło głównie o to, aby pisanie programów stało się łatwiejsze i przyjemniejsze.”
(zob. B. Stroustrup – Język C++, WNT)
Nazwa języka C++ pochodzi od istniejącego w już C operatora inkrementacji ++.
W ten sposób ma się ona kojarzyć z rozszerzoną wersją języka C.
10
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
Zalet ciąg dalszy ...
• Pozwala programować modularnie.
W wyniku wzrostu rozmiarów programu w procesie programowania większy
nacisk zaczęto kłaść na organizację danych, a nie projektowanie procedur
(algorytmów), jak to miało miejsce w przypadku programowania proceduralnego.
Pojawiło się pojęcie modułu, jako zbioru powiązanych ze sobą procedur wraz
z danymi, na których procedury te działają.
W ten sposób powstał nowy paradygmat programowania (zwany także zasadą
ukrywania danych), według którego program dzielimy na moduły, w których
ukrywany odpowiednie dane.
Mechanizmem wspierającym programowanie modularne jest tzw. przestrzeń
nazw (ang. namespace).
W jej obrębie możemy grupować zarówno związane ze sobą dane jak również
pewne informacje, czyli nazwy funkcji czy typów danych, które w ten sposób
stają się lokalne dla modułu.
W ogólności możemy powiedzieć, że język C++ pozwala na umieszczenie
w przestrzeni nazw dowolnej deklaracji.
11
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
Zalet ciąg dalszy ...
• Jest to język obiektowy – dostarcza mechanizmów wspierających programowa-
nie obiektowe (ang. object-oriented programming).
Inaczej niż w przypadku programowania proceduralnego, w którym staramy się
dopasować problem do metod proceduralnych, teraz próbujemy dostosować
język do problemu. Projektujemy taką postać danych, która najlepiej odpowiada-
łaby realizowanemu zadaniu.
W języku obiektowym największy nacisk kładziemy na dane (a nie na algoryt-
my, jak to miało miejsce w przypadku programowania proceduralnego).
W programowaniu obiektowym tworzymy tzw. klasy, będące typami użytkownika
zawierającymi deklaracje zarówno danych (definiujących przedmiot) jak i funkcji
składowych (metod) – określających właściwości przedmiotu.
Program oparty jest na zbiorze obiektów (będących „egzemplarzami”
zdefiniowanych klas), które komunikują się ze sobą w celu wykonania określonych
zadań.
• Pozwala na programowania uogólnione (ang. generic programming).
Jest to paradygmat programowania pozwalający na pisanie kodu algorytmów
sparametryzowanych w taki sposób, aby możliwe było ich użycie bez
wcześniejszej znajomości typów danych, na których będą działały.
12
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
Standard języka C++ ...
1990 r. – Amerykański Narodowy Urząd Standaryzacyjny (ANSI, ang. American
National Standards Institute) tworzy komitet ANSI X3J16 – jego zadaniem
jest opracowanie standardu języka C++.
Do projektu tego Międzynarodowa Organizacja Standaryzacyjna
(ISO, ang. International Organization for Standarization) dołączyła swój
komitet ISO-WG-21.
1998 r. – ISO, ANSI oraz Międzynarodowa Komisja Elektrotechniki (IEC,
ang. International Electrotechnical Commission) przyjmują ostateczny
standard międzynarodowy:
ISO/IEC 14882:1998 (Standard for the C++ Programming Language)
2003 r. – publikacja drugiej (poprawionej) edycji standardu – ISO/IEC 14882:2003
2009 r. – planowane ogłoszenie nowego standardu – tzw. C++ 0x
13
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
MICROSOFT VISUAL STUDIO
Visual Studio – zintegrowane środowisko programistyczne (IDE, ang. Integrated
Development Environment), w skład którego wchodzi:
• Microsoft Visual C++,
• Microsoft Visual C#,
• Microsoft Visual Basic,
• Microsoft Visual J#,
• Microsoft Web Developer ASP.NET.
Microsoft Visual Studio pozwala na tworzenie zarówno samodzielnych aplikacji, jak
też aplikacji i usług sieciowych oraz serwisów internetowych.
14
Tworzenie prostego projektu działającego w konsoli:
KROK 1: Po uruchomieniu środowiska programistycznego Microsoft Visual Studio
2008 na ekranie monitora widzimy okno główne postaci.
KROK 2:
Wybieramy
z menu File
polecenie New,
a następnie
Project.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
15
KROK 3: W oknie New Project wybieramy kolejno:
1. Typ projektu –
Visual C++ Win32
2. Szablon projektu
(ang. Templates) –
Win32 Console Application
... a następnie podajemy:
3. Nazwę projektu (pole Name),
np. Pierwszy
5. Nazwę rozwiązania (pole
Solution Name),
np. MojeRozwiazanie
4. Lokalizację katalogu
z projektem na dysku
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
16
KROK 4: W dialogowym Win32 Application Wizard – Overview możemy:
a) zakończyć tworzenie projektu klikając przycisk Finish, lub
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
b) przejść do kolejnego okna,
w którym zmieniamy ustawienia
projektu klikając przycisk Next.
17
W wyniku wcześniejszych operacji utworzone zostało Rozwiązanie (ang. Solution)
o nazwie MojeRozwiazanie, Projekt (ang. Project) o nazwie Pierwszy, zbiór plików
nagłówkowych o rozszerzeniu .h oraz zbiór plików źródłowych o rozszerzeniu .cpp.
W oknie edycji widzimy kod
ź
ródłowy pliku Pierwszy.cpp
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
18
SYSTEMY LICZBOWE
System liczbowy – zbiór reguł określających jednolity zapis i nazywanie liczb.
Liczby w danym systemie liczbowym zapisujemy używając określonego zbioru znaków
(symboli) nazywanych cyframi.
Do najbardziej znanych cyfr należą:
• cyfry arabskie : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
• systemy pozycyjne – liczbę przedstawia się jako ciąg cyfr, a wartość
poszczególnych znaków cyfrowych zależy od ich położenia (pozycji)
względem sąsiednich znaków cyfrowych.
Podział systemów liczbowych ...
• systemy addytywne – wartość liczby jest sumą wartości jej cyfr,
np. rzymski system liczbowy, gdzie
IV = 4, XII = 12
Cyfra
I
V
X
L
C
D
M
Wartość
1
5
10
50
100
500
1000
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
• cyfry rzymskie : I, V, X, L, C, D, M
19
W pozycyjnym systemie liczbowym dana jest:
• ustalona podstawa b,
• skończony zbiór cyfr ,
o wartościach równych odpowiednio .
1
,
,
1
,
0
−
b
K
Najważniejsze pozycyjne systemy liczbowe ...
• Jedynkowy system liczbowy – do zapisu liczby w tym systemie wykorzystuje się
wyłącznie jeden znak „1”, który oznacza liczbę 1.
Mamy podstawę b = 1 oraz zbiór cyfr postaci { 1 }.
Np. "11111" = 5, gdyż
.
5
1
1
1
1
1
1
1
1
1
1
0
1
2
3
4
=
⋅
+
⋅
+
⋅
+
⋅
+
⋅
{
}
1
1
0
,
,
,
−
b
c
c
c
K
1
1
0
,
,
,
−
b
w
w
w
K
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
Liczba zapisana
w postaci
ma wartość liczbową
gdzie
k
k
k
a
a
a
a
a
a
a
−
−
−
−
K
K
2
1
0
1
1
,
,
1
1
0
0
1
1
1
k
k
k
k
k
k
b
a
b
a
b
a
b
a
b
a
b
a
−
−
−
−
−
−
+
+
+
+
+
+
+
K
K
{
}
.
1
,
,
1
,
0
,
,
,
,
,
,
,
1
1
0
1
−
∈
−
−
−
b
a
a
a
a
a
a
k
k
k
K
K
K
część całkowita
część ułamkowa
20
•
Dwójkowy (binarny) system liczbowy – do zapisu liczby w tym systemie
wykorzystuje się dwa znaki „0” i „1”.
Mamy podstawę b = 2 oraz zbiór cyfr postaci { 0, 1 }.
Np. "1010" = 10, gdyż
.
10
0
2
0
8
2
0
2
1
2
0
2
1
0
1
2
3
=
+
+
+
=
⋅
+
⋅
+
⋅
+
⋅
Stosujemy oznaczenie
(
)
( )
.
10
1010
10
2
=
liczba zapisana
w systemie binarnym
liczba zapisana
w systemie dziesiętnym
• Dziesiętny (decymalny, arabski) system liczbowy – do zapisu liczby
w tym systemie wykorzystuje się dziesięć znaków.
Mamy podstawę b = 10 oraz zbiór cyfr postaci { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }.
Np. "125" = 125, gdyż
.
125
5
20
100
10
5
10
2
10
1
0
1
2
=
+
+
=
⋅
+
⋅
+
⋅
Najważniejsze pozycyjne systemy liczbowe – ciąg dalszy ...
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
21
• Szesnastkowy (heksadecymalny) system liczbowy – do zapisu liczby
w tym systemie wykorzystuje się szesnaście znaków.
Mamy podstawę b = 16 oraz zbiór cyfr postaci
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F },
wartości odpowiednich cyfr wynoszą odpowiednio
Cyfra
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
Wartość
0
1
2
3
4
5
6
7
8
9
10
11
12 13 14
15
.
2639
15
64
2560
16
15
16
4
16
10
0
1
2
=
+
+
=
⋅
+
⋅
+
⋅
Np. „A4F" = 2639, gdyż
UWAGA
System szesnastkowy jest powszechnie używany w naukach
informatycznych, gdyż
wartość
jednego bajtu
można zapisać
wykorzystując
jedynie dwie cyfry szesnastkowe.
Np.
(
)
(
)
(
)
.
10
2
16
2 3 9
1 1 1 0 1 1 1 1
E F
=
=
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
Najważniejsze pozycyjne systemy liczbowe – ciąg dalszy ...
22
22
Kod alfanumeryczny – kod pozwalający zapisać cyfry, litery oraz znaki
specjalne.
ASCII (ang. American Standard Code for Information Interchange)
jest to 7-bitowy kod, w którym liczbom z zakresu 0 – 127
przyporządkowywane są:
• małe i duże litery (alfabetu angielskiego): A, B, ... ,Y, Z, a, b, ... , y, z,
• cyfry: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
• znaki przestankowe: kropka, przecinek, dwukropek, średnik, wykrzyknik,
znak zapytania, myślnik, nawiasy, cudzysłowy,
• znaki sterujące (służące do sterowania urządzeniami, np. drukarką),
• inne symbole (@, &, %, itp.).
Rozszerzony kod ASCII
jest to 8-bitowy kod, w którym liczba możliwych do zakodowania znaków
zwiększyła się do 256.
STANDARDY REPREZENTOWANIA (KODOWANIA)
CYFR, LITER I ZNAKÓW SPECJALNYCH
UWAGA
Istnieje wiele różnych rozszerzeń kodu ASCII. Należą do nich przykładowo:
zestawy ISO /IEC 8859, Windows 1250 (CP-1250), Unicode.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
23
...
...
Rozszerzony
kod ASCII ...
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
24
TYPY DANYCH I ZMIENNE
Typy danych dostępne w języku C możemy podzielić na:
• typy proste (nazywane również skalarnymi lub po prostu skalarami), które są
niepodzielne i niejednokrotnie stosowane do tworzenia typów
strukturalnych,
• typy strukturalne (złożone), które mogą składać się zarówno z elementów typów
prostych, jak też z innych typów złożonych.
Typy proste dzielimy na typy:
• arytmetyczne (całkowitoliczbowe
i rzeczywiste),
• wskaźnikowe,
• referencyjne (język C++).
Do typów złożonych zaliczamy:
• tablice,
• struktury,
• unie ,
• klasy (język C++).
W programie reprezentantami typów danych są zmienne.
Typ danych to pojęcie logiczne – nie stanowi on bowiem obiektu, który możemy
wykorzystać w programie.
UWAGI
Zmienne zajmują pewien obszar w pamięci operacyjnej komputera. Rozmiar
i interpretacja tego obszaru zależą od typu zmiennej. W przeciwieństwie do typów
danych, zmienne są więc pojęciami fizycznymi.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
25
TYPY PROSTE (SKALARNE)
TYPY CAŁKOWITOLICZBOWE
Nazwa typu
Nazwy
równoważne
Rozmiar
[bajty (bity)]
Wartość
minimalna
Wartość
Maksymalna
char
signed char
1 (8)
–128
127
short
short int
signed short int
2 (16)
–32 768
32 767
int
signed int
4 (32)
–2 147 483 648
2 147 483 647
long
long int
signed long int
4 (32)
–2 147 483 648
2 147 483 647
Do typów całkowitoliczbowych zaliczamy typy całkowitoliczbowe ze znakiem
(reprezentują liczby ujemne i dodatnie z zerem) oraz typy całkowitoliczbowe bez
znaku (reprezentują liczby dodatnie z zerem).
Nazwa typu
Nazwy
równoważne
Rozmiar
[bajty (bity)]
Wartość
minimalna
Wartość
Maksymalna
unsigned char
char (z opcją /J)
1 (8)
0
255
unsigned short
unsigned short int
2 (16)
0
65 535
unsigned int
unsigned
4 (32)
0
4 294 967 295
unsigned long
unsigned long int
4 (32)
0
4 294 967 295
Tabela 1 / Tabela 2. Typy całkowitoliczbowe ze znakiem / bez znaku udostępnione przez kompilator
Microsoft C++ dla procesorów 32-bitowych. Uwaga: Typ char może być równoważny typowi signed
char (domyślnie) albo typowi unsigned char (po włączeniu opcji kompilatora /J).
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
26
Długość słowa procesora [bity]
16
32
64
Kompilator
Microsoft
10
8
8
Intel (Windows)
-
16
16
Intel (Linux)
-
12
16
Borland
10
10
-
Gnu
-
12
16
Tabela 3. Liczba bajtów zajmowanych przez zmienne typu long double w zależności od długości
słowa procesora oraz rodzaju kompilatora. Liczba zapisywana jest na pierwszych 10 bajtach (lub 8
bajtach – w przypadku kompilatorów Microsoft C++ dla procesorów 32-bitowych i 64-bitowych),
pozostałe bajty nie są wykorzystywane.
Do typów zmiennopozycyjnych zaliczmy typ float (pojedyncza precyzja) zazwyczaj
o rozmiarze 4 bajtów, typ double (podwójna precyzja) zazwyczaj o rozmiarze 8
bajtów oraz long double (rozszerzona precyzja) zajmująca od 8 do 16 bajtów.
Rozmiar typów zmiennopozycyjnych zależy od konkretnej implementacji języka C++.
Nazwa
typu
Rozmiar
[bajty (bity)]
Znak
[bity]
Wykładnik
[bity]
Mantysa
[bity]
Przybliżony zakres wartości
float
4 (32)
1
8
23
(+/-) 3.4 · 10
–38
do 3.4 · 10
+38
double
8 (64)
1
11
52
(+/-) 1.7 · 10
–308
do 1.7 ·
10
+308
long double
8 (64)
1
11
52
(+/-) 1.7 · 10
–308
do 1.7 ·
10
+308
Tabela 4. Typy rzeczywiste udostępnione przez kompilator Microsoft C++ dla procesorów
32-bitowych i 64-bitowych.
TYPY ZMIENNOPOZYCYJNE (RZECZYWISTE)
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
27
TYP LOGICZNY (ANG. BOOLEAN)
Typ logiczny bool służy do reprezentowania dwóch wartości logicznych true
(prawdy) oraz false (fałszu). Może być wykorzystany do wyrażania wyników
operacji logicznych lub jako typ wyniku funkcji sprawdzającej dany warunek.
PRZYKŁAD
main ()
{
int a = 3; int b = 5;
bool wynik = a==b;
}
bool CzyWiekszy (int a, int b) { return a>b; };
Pod zmienną wynik typu logicznego bool zostanie
podstawiony (przypisanie =) wynik porównania (operator
==) dwóch liczb całkowitych a oraz b.
Wartości są różne więc w danym przykładzie wynik będzie
miał wartość false.
Wynikiem funkcji będzie wartość logiczna true lub false odpowiadająca wynikowi
porównania (a > b) dwóch wartości a oraz b.
Wartości całkowite niezerowe przekształcane są do wartości logicznej true, a
wartość 0 do wartości logicznej false.
Zapis bool w = 7; jest równoważny zapisowi bool w = bool(7);
Po konwersji bool(7) otrzymujemy wartość true, więc w jest równe true.
UWAGI
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
Wartość logiczna true po przekształceniu do wartości całkowitej jest równa 1,
natomiast wartość logiczna false – równa jest 0.
Zapis int i = true; jest równoważny zapisowi int i = int(true);
Po konwersji int(true)otrzymujemy wartość 1, więc i jest równe 1.
28
TYP ZNAKOWY
Typ znakowy char służy do przechowywania pojedynczego znaku ze zbioru znaków
implementacji.
Język C++ zamiast przechowywać znaki przechowuje ich kody (czyli jednobajtowe
liczby całkowite ze znakiem – signed char, lub bez znaku – unsigned char).
Stąd typ char zaliczany jest w języku C++ do typów liczbowych.
Zmiennym typu znakowego możemy nadać wartość przez podanie:
• stałej dziesiętnej,
• znaku ujętego w apostrofy.
PRZYKŁAD 1
main ()
{
char z = 65;
char w = ’B’;
}
Pod zmienną z typu znakowego char podstawiony zostanie kod o
wartości 65 (odpowiadający znakowi litery A).
Pod zmienną w typu znakowego char podstawiony zostanie znak
litery B (o kodzie równym 66).
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
29
/* ... */
char z;
int kod;
for (int i=65; i<=90; i++)
{
z = i;
kod = z;
cout << "Znak " << z << " ma kod ASCII = " << kod;
cout << endl;
}
Program wyświetla na ekranie znaki odpowiadające wielkim literom alfabetu
angielskiego tj. znak ’A’ o kodzie 65, znak ’B’ o kodzie 66, aż do znaku ’Z’
o kodzie 90.
UWAGI DO PROGRAMU
PRZYKŁAD 2
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
O sposobie działania obiektu cout decyduje typ zmiennej, która ma być
wyświetlona. W zmiennej z typu char przechowywany jest kod znaku, który
przed wypisaniem na ekran zamieniany jest na odpowiadający mu znak.
Podobnie kod znaku, jako liczbę całkowitą, możemy wyświetlić po podstawieniu
wartości całkowitej przechowywanej w zmiennej z typu char do zmiennej
kod typu int.
30
TYPY I ZMIENNE WSKAŹNIKOWE
W języku C/C++ zdefiniowane są zmienne wskaźnikowe, które jako swoją wartość
przechowują adres pewnego obszaru w pamięci. Obszar ten można interpretować
jako zmienną określonego typu.
Zmienne wskaźnikowe mogą zawierać adres zmiennych należących zarówno do
typów prostych, jak i złożonych. Zmienne na które wskazują zmienne wskaźnikowe
nazywamy wówczas zmiennymi wskazywanymi.
PRZYKŁAD
A
15
• Zmienna o nazwie A
zawiera bezpośrednio wartość 15
pA
adres
zmiennej A
w pamięci
A
15
• Zmienna wskaźnikowa (wskaźnik)
o nazwie pA zawiera adres zmiennej A;
tak więc wskaźnik pośrednio wskazuje wartość 15
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
31
DEKLARACJA
Deklaracja zmiennej wskaźnikowej (wskaźnika), o nazwie określonej przez
identyfikator-wskaźnika, do wartości typu określonego przez typ-wartości:
typ-wartości * identyfikator-wskaźnika
INICJACJA
Inicjację wskaźnika (zmiennej wskaźnikowej) możemy wykonać zarówno po dekla-
racji jak również łącznie z deklaracją.
Adres danej zmiennej możemy otrzymać wykorzystując jednoargumentowy operator
pobierania adresu & (ang. address operator), który zwraca adres operandu:
typ-wartości * identyfikator-wskaźnika = &identyfikator-zmiennej
DEREFERENCJA
Synonim lub alias obiektu wskazywanego przez zmienną wskaźnikową możemy
wykonać wykorzystując jednoargumentowy operator adresowania pośredniego *
(ang. indirection operator) nazywany również operatorem dereferencji (ang.
dereference operator):
* identyfikator-wskaźnika
Powyższy sposób korzystania z operatora * jest określany jako dereferowanie
wskaźnika (ang. dereferencing a pointer). Dereferowany wskaźnik może być użyty
zarówno po lewej jak i po prawej stronie operatora przypisania.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
32
PRZYKŁAD
/* ... */
int A = 10;
int * pA = &A;
- deklaracja zmiennej A typu int połączona z inicjacją wartością
całkowitą równą 10
- deklaracja wskaźnika (zmiennej wskaźnikowej) pA
do wartości typu int połączona z inicjacją adresem zmiennej A
UWAGI
Do wartości, które mogą zostać nadane wskaźnikom należy dowolny adres
logiczny oraz 0 i NULL. Wskaźniki o wartości 0 i NULL nie wskazują żadnej
wartości (a mówiąc dokładnie wartość liczbowa adresu, na który wskazują jest
równa 0, przy czym w obecnych systemach operacyjnych żaden proces nie ma
dostępu do komórki pamięci o adresie 0).
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
NULL jest stałą symboliczną, a inicjowanie wskaźnika wartością NULL jest
równoważne inicjowaniu go wartością 0. W języku C++ zaleca się inicjowanie
wskaźników wartością 0, gdyż zostaje ona przekonwertowana na wskaźnik do
odpowiedniego typu.
- deklaracja zmiennej B typu double
- deklaracja wskaźników pB oraz pC do wartości typu double
- zmiennej B przypisujemy wartość 8.5
- zmiennej pB przypisujemy adres zmiennej B (mówimy, że pB
„wskazuje” na zmienną B
- zmiennej pC przypisujemy wskazanie puste
double B;
double * pB, * pC;
B = 8.5;
pB = &B;
pC = NULL;
- w wyniku przypisania *pB = 12.5 operujemy na zmiennej, na
którą wskazuje zmienna pB, czyli w tym przypadku na zmiennej
B (jest to równoważne przypisaniu B = 12.5)
*pB = 12.5;
cin >> *pB;
cout << *pB;
33
TYP VOID
Typ void jest tzw. pustym typem danych.
Składniowo zachowuje się w ten sam sposób jak typ podstawowy można go jednak
używać jedynie jako części bardziej złożonego typu, a co za tym idzie nie
możemy zadeklarować zmiennej typu void.
Sposoby użycia typu void:
• jako pseudotyp, aby wskazać, że funkcja nie przekazuje żadnej wartości (języki
C/C++), np.
void moja_funkcja ();
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
• w celu wskazania, że funkcja nie pobiera żadnych argumentów (język C), np.
int moja_funkcja (void);
• jako typ podstawowy dla wskaźników do obiektów nieznanego (dowolnego)
typu (języki C/C++), np.
void * pV;
34
WSKAZANIA ADRESOWE – TYP VOID *
W języku C/C++ zdefiniowane są zmienne typu void * (nazywane również wskaza-
niami adresowymi, lub wskaźnikami do obiektów nieznanego typu).
Zmienne te nie wskazują zmiennych jakiegoś określonego typu i mogą przechowy-
wać wartość wskaźnika dowolnego typu.
W ogólności wiemy, że wartość jednego wskaźnika może zostać przypisana
innemu wskaźnikowi w przypadku, gdy oba są tego samego typu. Np.
int A = 10, B = 20;
int * pA, * pB;
pA = &A; pB = pA;
UWAGI
Wskaźnik typu void, czyli void * jest wskaźnikiem ogólnym, który może
przechowywać wartość wskaźnika dowolnego typu. Możemy mu więc przypi-
sać wskaźniki do wszystkich typów bez konieczności wykonania konwersji.
double D = 12.5;
double * pD = &D;
// Wskaznik ogolny moze przechowywac wskaznik dowolnego typu
void * pV = pD;
// Wykonujemy jawna konwersja z powrotem do double *
double * pE = static_cast<double *> (pV);
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
35
Wskaźnikowi typu void możemy przypisać wskaźniki do typu void. Co więcej
możemy je również porównywać ze względu na równość lub nierówność, jak
również jawnie przekształcać do innego typu.
Nie możemy zastosować arytmetyki wskaźników, gdyż nie jest znany rozmiar
wskazywanej zmiennej. Np.
int A = 10, * pA = &A;
void * pV = pA;
// Dereferencja *pV jest niedozwolona
cout << *pV << endl;
// Nie mozemy stosowac arytmetyki wskaznikow, czyli operacji
pV++;
Wskaźnik typu void nie nie może podlegać dereferencji, gdyż wskazuje on
jedynie położenie danych nieznanego typu i w związku z tym nie jest w stanie
określić liczby bajtów zajmowanych przez daną. Np.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
36
TYPY I ZMIENNE REFERENCYJNE
W języku C/C++ zdefiniowane są zmienne referencyjne, których zadaniem jest
reprezentacja innych zmiennych w programie.
Operacje wykonywane na pewnej zmiennej x są równoważne operacjom
wykonywanym na zmiennej referencyjnej z nią związanej.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
DEKLARACJA
Deklaracja zmiennej referencyjnej o nazwie określonej przez identyfikator-
zmiennej-referencyjnej związanej ze zmienną daną przez identyfikator-zmiennej
połączona (zawsze!) z jej inicjalizacją:
typ &identyfikator-zmiennej-referencyjnej = identyfikator-zmiennej
lub
typ& identyfikator-zmiennej-referencyjnej = identyfikator-zmiennej
Przykłady wykorzystania typów i zmiennych referencyjnych:
• przekazywanie parametrów do funkcji,
• zwracanie wartości funkcji.
PRZYKŁAD
/* ... */
int A;
int &refA = A;
refA = 15;
Deklaracja zmiennej referencyjnej o nazwie refA połączona
z jej inicjacją, w wyniku której zmienna refA jest związana ze
zmienną A (stanowi alias zmiennej A).
Nadanie wartości 15 dla zmiennej refA jest równoważne
nadaniu tej wartości zmiennej A.
37
TABLICE
TYPY ZŁOŻONE (STRUKTURALNE)
Tablica – złożona struktura danych, składająca się z elementów tego samego typu
mających wspólną nazwę.
Cechy charakterystyczne tablicy:
• zajmuje ciągły obszar pamięci o rozmiarze potrzebnym do zapamiętania jej
wszystkich elementów,
• do konkretnej komórki (elementu tablicy) odwołujemy się podając jej nazwę oraz
liczbę określającą położenie elementu w tablicy (tzw. indeks lub numer pozycji),
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
38
DEKLARACJA
Deklaracja tablicy N - wymiarowej o wymiarach wymiar1, wymiar2, ... , wymiarN,
o nazwie określonej przez identyfikator i typie wszystkich elementów tablicy danym
przez typ-elementów:
typ-elementów identyfikator [wymiar1] [wymiar2] ... [wymiarN]
UWAGA
Elementy tablicy mogą być dowolnego typu za wyjątkiem typu referencyjnego.
Możemy więc w tablicy przechowywać nie tylko liczby całkowite i rzeczywiste, ale
również wskaźniki, struktury, unie, inne tablice oraz obiekty.
PRZYKŁADY DEKLARACJI
/* ... */
int z[10];
char str[30];
long double * tabld[12];
short w[3][20];
tablica o nazwie z zawierająca 10 elementów typu int
tablica o nazwie str zawierająca 30 znaków
tablica o nazwie tabld zawierająca 12
wskaźników liczb typu double
dwuwymiarowa tablica o nazwie w liczb całkowitych typu short
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
39
INICJACJA
Inicjację tablicy możemy wykonać:
• po deklaracji,
• łącznie z deklaracją. Polega ona wówczas na wymienieniu bezpośrednio po
deklaracji zmiennej listy inicjatorów tablicy ujętej w nawiasy klamrowe.
Zasady obowiązujące przy inicjacji tablic:
• lista inicjatorów nie może zawierać więcej elementów niż przewiduje to rozmiar
tablicy,
• w przypadku, gdy inicjatorów jest mniej niż elementów tablicy, wówczas pozostałe
elementy tablicy są inicjowane zerami (w przypadku tablic liczb i znaków), lub
wskazaniami pustymi NULL (w przypadku tablicy wskaźników),
• inicjator musi być stałą (język C), oraz może być stałą lub identyfikatorem zmiennej
(język C++).
PRZYKŁADY INICJACJI
/* ... */
double z[10] = {2.5, 8.1, 12.0};
int i[3][2] = {{1,2}, {3,4}, {5,6}};
int n[] = {1,2,4,5};
Tablicę o nazwie z zainicjowano trzema pierwszymi elementami,
pozostałym elementom zostanie domyślnie przypisana wartość zero.
Inicjacja tablicy dwuwymiarowej
o nazwie tabi – wartości zgrupo-
wane są w nawiasach
klamrowych według wierszy.
Wielkość tablicy n została pominięta w deklaracji z listą wartości
inicjujących – w takim przypadku liczba jej elementów będzie równa liczbie
elementów znajdujących się na liście wartości inicjujących, czyli 4.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
40
DOSTĘP DO ELEMENTÓW TABLICY
Dostęp do elementu tablicy możemy uzyskać poprzez podanie jego pozycji
(indeksu/ów) w nawiasach kwadratowych.
Odwołując się do elementu tablicy musimy pamiętać, że:
• pierwszy element tablicy ma indeks równy zero (w przypadku tablic wielowymia-
rowych wszystkie indeksy są równe zero), np.
tab[0][0]
jest odwołaniem do pierwszego elementu (elementu w pierwszym wierszu
i w pierwszej kolumnie) tablicy dwuwymiarowej o nazwie tab,
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
• pozycja ostatniego elementu tablicy jest równa wymiar-1, np.
tab[n-1]
jest odwołaniem do ostatniego elementu jednowymiarowej tablicy n-elementowej
o nazwie tab,
• zarówno w procesie kompilacji, jak i w trakcie wykonywania programu w C/C++
nie jest wykonywane sprawdzenie czy używane indeksy nie wskazują poza
tablice. Może to powodować niebezpieczne i trudne do wykrycia błędy. Zalecana
jest szczególna ostrożność zwłaszcza podczas umieszczania danych w tablicy.
41
c[0]
5
c[1]
12
c[2]
-7
c[3]
9
c[4]
5
c[5]
-51
PRZYKŁAD 1
- deklaracja tablicy jednowymiarowej o nazwie c zawierającej
6 elementów typu int połączona z inicjacją tych elementów
int c[6] = {5,12,-7,9,5,-51};
- zmieniamy wartość elementu o indeksie 2 (trzeciego
elementu w tablicy) na 17
c[2] = 17;
kolumna 0 kolumna 1 kolumna 2 kolumna 3
wiersz 0
a[0][0]
a[0][1]
a[0][2]
a[0][3]
wiersz 1
a[1][0]
a[1][1]
a[1][2]
a[1][3]
wiersz 2
a[2][0]
a[2][1]
a[2][2]
a[2][3]
Tablice jednowymiarowe ...
PRZYKŁAD 2
Tablice dwuwymiarowe ...
- deklaracja tablicy dwuwymiarowej o nazwie a zawierającej 3 wiersze oraz
4 kolumny; elementy tablicy są typu double; deklaracja połączona jest
z inicjacją początkowych elementów tablicy (wartości nie zostały zgrupowane
w nawiasach klamrowych tak więc elementy inicjowane są wierszami)
double a[3][4] = {1.5, 2.3, 1.5, 8.3, 14.1, 7.2, 9.1};
- odwołanie do elementu tablicy a znajdującego się w pierwszym wierszu i trzeciej
kolumnie i przypisanie mu wartości 12.5
a[1][3] = 12.5;
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
42
STRUKTURY
Struktura – złożony typ danych będący zbiorem elementów (prawie!) dowolnego
typu. Struktura definiuje w istocie nowy typ danych.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
DEKLARACJA
Deklaracja struktury (nowego typu danych) o nazwie identyfikator-typu-struktury
o polach określonych przez deklaracje-składowej1, deklaracje-składowej2, .... :
struct identyfikator-typu-struktury
{
deklaracja-składowej1
deklaracja-składowej2
...
} [identyfikator-struktury1 = [inicjator1], ... ,
identyfikator-struktury1 = [inicjator1] ];
Definicja typu struktury może być połączona z utworzeniem zmiennej strukturalnej
identyfikator-struktury1 i jej inicjacją przy pomocy inicjatora1.
W deklaracji możemy pominąć identyfikator-typu-struktury, identyfikatory-
struktury i ich inicjatory.
Cechy charakterystyczne struktury:
• składa się ona ze składowych różnych typów, które umieszczone są w pamięci
jedna za drugą,
• rozmiar struktury jest równy sumie rozmiarów jej składowych.
43
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
UWAGA
Składowe (pola) struktury mogą być dowolnego typu (w tym typu strukturalnego),
z dwoma wyjątkami:
• składowa nie może być typu strukturalnego, który jest aktualnie deklarowany, np.
struct osoba
{
char nazwisko[30];
int wiek;
osoba ojciec;
};
deklaracja niedozwolona
• (język C) składową struktury nie może być funkcja, natomiast może wskaźnik do
funkcji.
... może być ona natomiast wskaźnikiem do aktualnie deklarowanej struktury, np.
struct osoba
{
char nazwisko[30];
int wiek;
osoba * ojciec;
};
deklaracja dozwolona
44
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
DOSTĘP DO SKŁADOWYCH STRUKTURY
Dostęp do składowych struktury umożliwiają operatory:
• kropki . (bezpośredni selektor składowych) – stosujemy w przypadku struktur
reprezentowanych przez zmienne strukturalne;
• -> (pośredni selektor składowych) – wykorzystujemy w przypadku struktur
wskazywanych przez wskaźniki.
PRZYKŁADY DEKLARACJI I INICJACJI
/* Przyklad 1 ... */
struct Kolo
{
double x,y;
double r;
} k1 = {10,20,3};
Deklaracja struktury o nazwie Kolo
połączona z utworzeniem zmiennej
strukturalnej typu Kolo o nazwie k1.
Pola zmiennej k1 są inicjowane kolejno
wartościami: 10, 20, 3.
/* Przyklad 3 ... */ /* Przyklad 4 ... */
Kolo inneKolo; Kolo * pKolo = new Kolo;
inneKolo.x = 3.5; pKolo->x = 3.5;
inneKolo.y = 12.5; pKolo->y = 12.5;
inneKolo.r = 8.0; pKolo->r = 8.0;
Przykłady dostępu do
składowych struktury
za pomocą operatorów
w zależności od rodzaju
zmiennej strukturalnej.
Deklaracja zmiennej strukturalnej typu Kolo
o nazwie mojeKolo połączona z inicjacją składowych.
/* Przyklad 2 ... */
Kolo mojeKolo = {1,10,5};
45
JEDNOSTKI LEKSYKALNE JĘZYKA C++
Podstawowe jednostki leksykalne języka C++:
• słowa kluczowe (ang. key words) – specjalne identyfikatory zastrzeżone do
użytku przez sam język dla ściśle określonych celów.
Mogą być one wykorzystywane tylko zgodnie z ich przeznaczeniem ustalonym przez
definicję języka C/C++. Słów kluczowych nie można używać do innych celów, takich
jak np. nazywanie zmiennych.
SŁOWA KLUCZOWE JĘZYKÓW C/C++
auto
break
case
char
const
continue
default
do
double
else
enum
extern
float
for
goto
if
int
long
register
return
short
signed
sizeof
static
struct
switch
typedef
union
unsigned
void
volatile
while
SŁOWA KLUCZOWE JĘZYKA C++
asm
bool
catch
class
const_cast
delete
dynamic_cast
explicit
false
friend
inline
mutable
namespace
new
operator
private
protected
public
reinterpreted_cast
static_cast
template
this
throw
true
try
typeid
typename
using
virtual
wchar_t
UWAGA
Słowa kluczowe udostępnione dla programisty zależą od implementacji języka C++.
Przykładowo język C++ firmy Microsoft rezerwuje dla zachowania zgodności z innymi imple-
mentacjami słowo kluczowe asm ale nie implementuje go. Zamiast niego proponuje __asm.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
46
Podstawowe jednostki leksykalne języka C++ – ciąg dalszy:
• identyfikatory (ang. identifiers) – jednostki leksykalne tworzone przez
programistę zgodnie ze składnią języka programowania
umożliwiające identyfikację oraz odwołanie się do określonego
elementu kodu źródłowego programu.
PRZYKŁAD
main ()
{
double a,b,result;
result = a + b;
}
main – identyfikator nazwy funkcji
a,b,result – identyfikatory zmiennych typu double
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
Przy pomocy identyfikatorów możemy nazywać i identyfikować takie elementy
programu jak zmienne, stałe, typy, etykiety, pola struktur i klas, parametry,
podprogramy (procedury, funkcje, metody), klasy, moduły, pakiety, biblioteki,
programy.
Identyfikator w języku C/C++ może się składać z małych i wielkich liter, cyfr oraz
znaku podkreślenia. Należy przy tym pamiętać, że prawidłowo zdefiniowany
identyfikator zaczyna się od litery lub znaku podkreślenia. Standardowo kompilatory
języka C++ biorą pod uwagę maksymalnie 32 znaki. Kompilator języka C++ firmy
Microsoft pozwala na używanie identyfikatory o długości 2048.
47
Podstawowe jednostki leksykalne języka C++ – ciąg dalszy:
• literały (ang. literals) – jednostki leksykalne reprezentujące wartości wpisane
bezpośrednio w kod programu.
• literały znakowe (stałe znakowe) – literały reprezentujące w kodzie źródłowym
konkretną wartość typu znakowego.
UWAGI
Każdemu znakowi odpowiada w danym zestawie znaków wartość numeryczna
(kod znaku), czyli pewna jednobajtowa liczba całkowita.
Ten sam znak może mieć różne wartości (kody) w różnych zbiorach znaków
(w powszechnym użyciu jest wiele różnych zestawów znaków).
Ponadto nie każdy zbiór znaków ma wartości dla każdego znaku.
Dostępny zestaw znaków zależy od systemu komputerowego oraz ustawień.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
za pomocą znaku sterującego kodowanego w języku C/C++ jako ciąg znaków
poprzedzonych przez \, np. '\n‘ oznacza przejście do następnego wiersza,
za pomocą kodu liczbowego:
- dziesiętnego – liczby dziesiętnej, np. kod 65 odpowiada dla znaku 'A',
- ósemkowego – liczby ósemkowej poprzedzonej przez \,
np. '\107' odpowiada dla znaku ‘G',
- szesnastkowo – w postaci liczby szesnastkowej poprzedzonej przez \x,
np. '\x47' odpowiada dla znaku 'G'.
Sposoby użycia (zapisu) literału znakowego:
bezpośrednio – za pomocą znaku ujętego w apostrofy, np. 'A', '7';
48
char s1[10];
char s2[21] = ”Oto stala lancuchowa”;
char * s3 = ”Oto drugi napis”;
PRZYKŁAD
deklaracja łańcucha s1 o rozmiarze 10 znaków
połączenie deklaracji łańcuchów s2 i s3 z ich inicjacją
stałymi łańcuchowymi podanymi w cudzysłowach
• literały łańcuchowe (napisy, stałe łańcuchowe) (ang. string constants) – lite-
rały reprezentujące wartości składające się z ciągu znaków
(łańcucha znaków) wpisanego bezpośrednio w kod programu.
• literały liczbowe (stałe liczbowe) – literały reprezentujące konkretne wartości
liczbowe wpisane bezpośrednio w kod programu. Wartości te
znane są już na etapie tworzenia programu.
.
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
Wartość, która ma reprezentować w kodzie źródłowym określony ciąg znaków,
należy jednoznacznie od kodu programu wyodrębnić. W językach C/C++ ogranicz-
nikiem takim jest cudzysłów.
Literał łańcuchowy zawiera o jeden znak więcej, gdyż wszystkie napisy kończą się
znakiem ‘/0‘ o wartości 0.
Literały liczbowe dzielimy ze względu na sposób zapisu wartości liczbowej na
całkowitoliczbowe i zmiennopozycyjne. Podział ze względu na podstawę systemu
liczbowego wyróżnia literały ósemkowe, dziesiętne i szesnastkowe.
49
Do literałów całkowitoliczbowych zaliczamy:
• literały dziesiętne – reprezentowane przez cyfry arabskie 0,1,2,3,4,5,6,7,8,9.
• literały ósemkowe – reprezentowane przez zbiór cyfr 0,1,2,3,4,5,6,7.
Literały ósemkowe zaczynają się cyfrą 0, po której podajemy
liczbę w systemie ósemkowym.
• literały szesnastkowe – reprezentowane są przez cyfry 0,1,2,3,4,5,6,7,8,9 oraz
znaki A, B, C, D, E, F (wraz z ich małymi odpowiednikami).
Literały szesnastkowe zaczynają się znakami 0x, po których
podajemy liczbę w systemie szesnastkowym.
Stałe ujemne rozpoczynają się od znaku – (minus), stałe dodatnie mogą (nie muszą)
rozpoczynać się od znaku + (plus).
LITERAŁY CAŁKOWITOLICZBOWE (LITERAŁY CAŁKOWITE)
Do zaznaczenia, że dany literał ma być liczbą całkowitą bez znaku, należy na
jego końcu umieścić przyrostek u lub U.
Literał, którego wartość ma być typu long powinien mieć na końcu dodany
przyrostek l lub L.
Przyrostki mogą być używane łączenie, a ich kolejność nie ma znaczenia.
UWAGA
PRZYKŁAD
int Lit1 = 63;
int Lit2 = 077;
int Lit3 = 0x3F;
deklaracja zmiennych Lit1, Lit2, Lit3 typu int oraz ich
inicjalizacja literałami o wartości dziesiętnej równiej 63
(zapisanej w systemach – dziesiętnym, ósemkowym
i szesnastkowym)
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
50
Typ literału całkowitego zależy od jego postaci, wartości i przyrostka. Obowiązują
przy tym następujące zasady (zob. „B. Stroustrup, Język C++, Wydawnictwa
Naukowo-Techniczne, Warszawa 2002”):
Jeżeli dany jest literał dziesiętny i nie ma przyrostka, wówczas jego typem jest
pierwszy spośród podanych typów, w którym można reprezentować jego wartość:
int, long int, unsigned long int.
UWAGI
Jeżeli dany jest literał ósemkowy lub szesnastkowy i nie ma przyrostka, wówczas
jego typem jest pierwszy spośród podanych typów, w którym można
reprezentować jego wartość: int, unsigned int, long int, unsigned long int.
Jeżeli literał ma przyrostek u lub U, to jego typem jest pierwszy spośród
podanych typów, w którym można reprezentować jego wartość: unsigned int,
unsigned long int.
Jeżeli literał ma przyrostek l lub L, to jego typem jest pierwszy spośród podanych
typów, w którym można reprezentować jego wartość: long int,
unsigned long int.
PRZYKŁAD
za typ literału przyjęty zostanie
typ unsigned long int
za typ literału przyjęty zostanie typ long int
unsigned long int w = 12UL;
long int u = -1256L;
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE
51
Podstawowe jednostki leksykalne języka C++ – ciąg dalszy:
• stała (ang. constant) – jednostka leksykalna reprezentująca wartość (liczbową,
tekstową, itp.) zapamiętaną pod pewną nazwą, którą
możemy w kodzie używać wielokrotnie (w przeciwieństwie
do literału, który jest jedynie zapisem pewnej wielkości
w określonym miejscu w programie).
Stała może być wartością:
• znaną już na etapie kompilacji, której nie możemy już nigdy zmienić (C/C++),
• ustawianą jednorazowo, której wartości nie możemy już później zmienić (C++).
M
.
J
ANKOWSKA –
W
YKŁAD
1 W
PROWADZENIE