Zmienne i stałe.
Program musi w jakiś sposób reprezentować dane, z których korzysta w
trakcie pracy. Zmienne i stałe pozwalają na pracę z wartościami dowolnego
typu: liczby, teksty i wiele innych.
Co to jest zmienna?
Z programistycznego punktu widzenia zmienna to fragment pamięci, w
którym można przechowywać wartość i z którego można tę wartość odczytać.
Każda zmienna posiada swój adres. Jednak w programie zmienne
identyfikowane są nie poprzez ich adresy, lecz poprzez nazwy.
RAM to pamięć o swobodnym dostępie (ang: Random Access Memory). Kiedy
uruchamiacie program, to ładowany on jest z pliku do pamięci RAM.
Wszystkie zmienne tworzone są w pamięci RAM.
Przykładowo można stworzyć zmienną MojWiek. Nazwa zmiennej to etykieta
pewnego obszaru w pamięci. Można używać tej nazwy, zamiast posługiwać
się adresem.
Schemat pamięci
MojaZmienna
100
101
102
103
104
105
106
Nazwa zmiennej
RAM
Adres
Rezerwacja pamięci.
Rozmiary zmiennych typu całkowitego
Zmienna znakowa – char (służy do przechowywania znaków) jest na ogół
jednobajtowa. short int zajmuje najczęściej dwa bajty, a long int – cztery.
int (bez przedrostka short lub long) może być zmienną dwu lub
czterobajtową. Kiedy uruchomicie program pod systemem Windows 95,
Windows 98 lub Windows NT, zobaczycie, że zmienna typu int zajmuje w
pamięci cztery bajty.
Gdy definiujecie zmienną w C++, to oprócz jej nazwy musicie podać, jakiego
typu wartość ma ona przechowywać. Czy ma to być liczba całkowita ze
znakiem czy bez, czy ma to być znak, czy łańcuch znaków. Nazywamy to
typem zmiennej.
Podstawową jednostką pamięci jest bajt. Jeśli zmienna, którą tworzycie, jest
rozmiaru dwóch bajtów, to wymaga dwóch bajtów w pamięci do jej
przechowywania.
Typ zmiennej to informacja dla kompilatora, ile pamięci ma
zarezerwować na wartość przechowywaną przez daną zmienną.
Funkcja sizeof() jest
standardowo dostarczona z
kompilatorem. Pozwala na
określenie rozmiaru obiektu
przekazanego jej jako
parametr.
Np. jest to słowo kluczowe int
definiujące zmienną typu
całkowitego. Widzimy, że na
komputerze, na którym
uruchomiono przykładowy program,
rozmiar zmiennej typu int jest
równy rozmiarowi zmiennej typu
long int i wynosi 4 bajty.
Przykładowy program
Zmienne ze znakiem i bez znaku
Dla każdej zmiennej typu całkowitego możemy dodatkowo określić czy ma
być ona traktowana jako liczba ze znakiem czy bez. Przyczyną tego jest to, że
nie zawsze wykorzystujemy liczby ujemne. Do określenia rodzaju zmiennej
wykorzystuje się dwa słowa kluczowe:
signe
d
– dla liczb ze znakiem
unsigned
– dla liczb bez znaku
UWAGA
!
Liczby całkowite (short, long), bez słowa unsigned będą zawsze
traktowane jako liczby ze znakiem (signed). Będzie można im
przypisać wartości zarówno dodatnie jak i ujemne. Zmiennym bez
znaku (unsigned) można przypisać tylko wartości nieujemne.
Ponieważ w obydwu przypadkach macie do dyspozycji tę samą liczbę bajtów
na zmienną, to największą wartość którą możecie przechować w zmiennej
typu unsigned jest dwa razy większa niż największa wartość dodatnia
możliwa do przechowania w zmiennej typu signed. Zmienna typu unsigned
int może reprezentować liczby z zakresu od 0 do 65535. Połowa liczb
reprezentowanych przez zmienną typu signed int jest ujemna, dlatego
zmienna tego typu może reprezentować wartości z zakresu od –32768 do
32767.
Podstawowe typy zmiennych
C++ zawiera wiele różnych typów zmiennych. Mogą być one prosto
podzielone na zmienne typu całkowitego, zmiennoprzecinkowego i
znakowego.
Zmienne typu zmiennoprzecinkowego mogą reprezentować wartości
przedstawiane jako liczby rzeczywiste. Zmienne typu znakowego zajmują
jeden bajt i mogą przechowywać jeden z 256 znaków i symboli ASCII.
ASCII (American Standard Code for Information Interchange) to zestaw
standardowych znaków i ich kodów wykorzystywanych na komputerach.
Praktycznie każdy system operacyjny wykorzystuje standard ASCII, obok
innych dostępnych, międzynarodowych standardów.
Typ
Rozmiar Zakres (Wartości)
unsigned
short int
2 bajty
0 – 65535
short int
2 bajty
-32768 – 32767
unsigned long
int
4 bajty
0 – 4294967295
long int
4 bajty
-2147483648 – 2147483647
char
1 bajt
0 – 255 (256 różnych znaków)
bool
1 bajt
prawda lub fałsz
float
4 bajty
1.2e-38 – 3.4e38
double
8 bajtów
2.2e-308 – 1.8e308
Definiowanie zmiennych
Przykłady poprawnych nazw zmiennych to np.: x, J23qrsnf i MojWiek.
Dobra nazwa zmiennej to taka, która określa w jakim celu tę zmienną
stworzono – jaka jest interpretacja wartości, którą ona reprezentuje.
Używanie dobrych nazw ułatwia zrozumienie programu.
Oto przykład definicji zmiennej o nazwie MojWiek:
int MojWiek;
Jako generalną programistyczną praktykę, stosuj takie nazwy zmiennych,
które mówią do czego dana zmienna jest wykorzystywana.
Nazwy takie jak MojWiek czy IlePieniedzy są łatwiejsze do zrozumienia i do
zapamiętania niż np. xJ4 czy I345pl. Jeżeli będziecie rozsądnie nazywać
zmienne, to wówczas będziecie mogli pominąć część komentarzy
niezbędnych do zrozumienia kodu.
Nazwy zmiennych składają się z liter, cyfr i szeregu innych znaków.
Nie mogą
zawierać spacji i zaczynać się od cyfry.
Zmienne tworzy się i definiuje się poprzez napisanie nazwy typu, a
następnie listy nazw zmiennych oddzielonych przecinkami.
Spróbujcie zgadnąć co robią podane niżej programy:
Eksperyment
Przykład 1
main ()
{
unsigned short x;
unsigned short y;
unsigned short z;
z = x * y;
}
Przykład 2
main ()
{
unsigned short nSzerokosc;
unsigned short nDlugosc;
unsigned short nPowierzchnia;
nPowierzchnia = nSzerokosc * nDlugosc;
}
Rozróżnianie wielkich i małych liter
C++ rozróżnia wielkość liter. Duże i małe litery traktowane są jako
różne.
Zmienna wiek to nie to samo co zmienna Wiek, która z kolei jest inna niż zmienna WIEK.
Przykład
Niektóre kompilatory pozwalają na wyłączenie kontroli wielkości liter. Nie
wykorzystujcie tej możliwości; wasze programy nie będą wtedy działać
poprawnie z innymi kompilatorami, a inni programiści nie będą chcieli
korzystać z waszych programów.
UWAGA:
Wielu programistów preferuje wykorzystywanie jedynie małych liter w
nazwach zmiennych.
Jeśli zmienna musi składać się z kilku słów (np. mój samochód) to stosowane
są dwie popularne konwencje: mój_samochod i mojSamochod.
Forma z wielkimi literami na początku każdego słowa określana jest czasem
jako notacja wielbłąda ponieważ wielkie litery przypominają garby.
Słowa kluczowe
Niektóre słowa są w C++ zarezerwowane i nie można ich wykorzystywać jako
nazwy zmiennych. Są to tzw.
słowa kluczowe
wykorzystywane przez
kompilator do kontrolowania programu.
Przykład słów kluczowych:
main, if, while, for
Tworzenie wielu zmiennych jednocześnie
Można stworzyć wiele zmiennych tego samego typu jednocześnie
poprzez napisanie słowa definiującego typ, a następnie listy nazw
zmiennych oddzielonych przecinkami.
Przykład:
unsigned int nMojWiek, nMojaWaga; // dwie zmienne typu unsigned
int
long lPowierzchnia, lDlugosc, lSzerokosc; // trzy zmienne typu
long
Przypisywanie wartości do zmiennych
Wartości przypisuje się do zmiennych za pomocą operatora przypisania (
=
).
Jeśli chcesz, aby zmienna nSzerokosc miała wartość 5 to musisz napisać:
unsigned short nSzerokosc;
nSzerokosc = 5;
Można połączyć oba kroki i zainicjować zmienną w momencie definiowania:
unsigned short nSzerokosc = 5;
Inicjalizacja wygląda tak jak przypisanie, dla zmiennych całkowitych różnica
jest drugorzędna. Później, kiedy wprowadzimy stałe, zobaczycie, że niektóre
wartości muszą być inicjowane ponieważ nie będą mogły być przypisane.
dołączany jest plik iostream niezbędny do
działania funkcji cout
Definicja zmiennej nSzerokosc typu int i
inicjowana jest ona wartością 5. Definiowana jest
również druga zmienna - nDlugosc, lecz nie jest
ona inicjowana.
zmiennej nDlugosc przypisywana jest
wartość 10
Definiowana jest zmienna nPole inicjowana
wartością
będącą
wynikiem
mnożenia
zmiennych nDlugosc i nSzerokosc
typedef
Przykład:
typedef
unsigned short int
USHORT
W ten sposób tworzymy słowo kluczowe
USHORT
, którego możemy używać
do definiowania zmiennych typu
unsigned short int
.
Ciągłe pisanie unsigned short int wydaje się być nudne i podatne na błędy.
C++ pozwala na tworzenie alternatywnych nazw typów poprzez użycie słowa
kluczowego
typedef
służącego do definiowania typów.
Faktycznie tworzony jest synonim dla istniejącego typu i należy to odróżniać
od tworzenia nowego typu.
typedef używa się poprzez napisanie
typedef,
a następnie nazwy
istniejącego typu i nazwy alternatywnej.
Demonstracja typedef
Niektóre
kompilatory
mogą
zgłosić ostrzeżenie, że konwersja
może powodować utratę cyfr
znaczących.
Dzieje się tak, ponieważ iloczyn
dwóch zmiennych typu USHORT
może
być
większy
niż
maksymalna liczba możliwa do
przedstawienia w zmiennej typu
USHORT i przypisanie może
spowodować obcięcie. W tym
konkretnym przypadku można to
ostrzeżenie pominąć.
Kiedy używać short a kiedy long?
Jednym z problemów programistycznych jest kiedy definiować zmienne jako
long, a kiedy jako short.
Reguła jest tutaj bardzo prosta:
Jeśli istnieje szansa, że wartość, którą będziesz przypisywał do
zmiennej przekroczy dopuszczalny zakres tej zmiennej to wykorzystaj
większy typ.
Zmienne typu unsigned short, przy założeniu, że są one dwubajtowe, mogą
przechowywać wartości nie większe niż 65535.
Zmienne typu signed int mogą przechować wartość dodatnią o połowę
mniejszą. Mimo że zmienne unsigned long mogą reprezentować bardzo
duże liczby (do 4294967295), to są one i tak ograniczone.
Jeśli potrzebujecie większych liczb, to musicie się odwołać do zmiennych typu
float lub double, lecz wtedy tracicie na precyzji w reprezentacji liczb.
Zmienne float i double mogą przyjmować ekstremalnie duże wartości, lecz
na większości komputerów jedynie pierwsze 7 lub 19 cyfr jest znaczących.
Oznacza to, że liczba jest zaokrąglona na pozostałych miejscach.
Przekraczanie zakresu w zmiennych
unsigned
Fakt, że zmienne typu
unsigned long
mają ograniczony zakres wartości
raczej rzadko stanowi problem.
Ale co się dzieje gdy jednak przekroczymy dopuszczalny
zakres?
Kiedy liczba całkowita bez znaku (unsigned) osiągnie
swoją maksymalną wartość, to wraca do początku zakresu
– do zera (tak jak licznik w magnetofonie).
Deklarowana jest zmienna
nMalaLiczba, (jeśli nie
napiszemy słowa unsigned, to
zostanie ona potraktowana
jako signed).
Zmienne całkowite ze znakiem
„zawijają się” od największej
wartości dodatniej do
największej (co do wartości
bezwzględnej) ujemnej.
Stałe
Stałe, podobnie jak zmienne, służą do przechowywania danych. Wartość
zmiennej może ulec zmianie. W przypadku stałych, jak sama nazwa wskazuje,
wartość nie może zostać zmieniona. Stałą trzeba zainicjować w momencie
tworzenia. Nie można jej potem przypisać innej wartości.
W C++ stosowane są dwa typy stałych:
Stała liczbowa to wartość podawana
bezpośrednio w programie tam
gdzie jest ona potrzebna.
Przykład
int nMojWiek = 23;
nMojWiek to zmienna typu int;
23 to stała liczbowa.
Nie można przypisać wartości do
23 i wartość 23 nie może zostać
zmieniona.
Stałe liczbowe
Stałe symboliczne
Stała
symboliczna
to
stała
reprezentowana przez nazwę, tak jak
w przypadku zmiennych. Jednak, w
przeciwieństwie do zmiennych, po
inicjalizacji stałej jej wartość nie może
zostać zmieniona.
nNewKasa = nOldKasa / DEWALUACJA;
Przykład
Gdzie DEWALUACJA = 10000
Definiowanie stałych za pomocą # define
Żeby zdefiniować stałą w stary, całkowicie niesłuszny sposób, możesz
napisać:
#define DEWALUACJA 10000
Zauważmy, że DEWALUACJA nie jest żadnego typu (int, char itd.). Użycie
#define
powoduje wykonanie zwykłej zmiany tekstu. Za każdym razem, gdy
procesor napotka w tekście programu DEWALUACJA to wstawi w to miejsce
tekst 10000.
Ponieważ procesor jest uruchamiany przed kompilatorem, to kompilator nigdy
nie zobaczy stałej, lecz wartość 10000.
Definiowanie stałych za pomocą const
Mimo że #define działa, to wprowadzono nową, lepszą, bardziej gustowną
metodę definiowania stałych w C++:
const
unsigned short int
DEWALUACJA = 10000;
Ten przykład definiuje stałą symboliczną o nazwie DEWALUACJA, jednak w tym
przypadku DEWALUACJA jest typu
unsigned short int
.
Taka definicja jest dłuższa do wpisywania, ale posiada dodatkowe zalety.
Największa różnica polega na tym, że stała jest określonego typu i kompilator
może ją traktować zależnie od tego typu.
Stałe wyliczeniowe
Stałe wyliczeniowe tworzą zbiór stałych o określonym zakresie wartości.
można zdefiniować KOLOR jako wyliczenie i podać pięć
wartości dla KOLOR: CZERWONY, NIEBIESKI, ZIELONY, BIAŁY i
CZARNY.
Przykład:
Żeby stworzyć stałą wyliczeniową trzeba użyć słowa kluczowego
enum
,
a następnie napisać nazwę stałej, otworzyć klamrę, wypisać wszystkie
dopuszczalne wartości oddzielone przecinkami, zamknąć klamrę i
postawić średnik.
Przykład:
enum KOLOR {CZERWONY, NIEBIESKI, ZIELONY, BIAŁY, CZARNY } ;
Spowoduje to wykonanie następujących czynności:
KOLOR staje się nazwą wyliczenia. Powstaje zatem nowy typ.
Do CZERWONY zostaje przypisana wartość 0, do NIEBIESKI wartość 1, do
ZIELONY wartość 2 itd.
Każda stała wyliczeniowa posiada wartość całkowitą. Jeśli tego specjalnie nie
określi się, to pierwsza stała przyjmie wartość 0, druga 1 itd.
Każda ze stałych może zostać zdefiniowana z określoną wartością. Jeśli któraś
z wartości nie zostanie podana to zostanie ona wyliczona na podstawie
poprzedniej.
enum KOLOR {CZERWONY=100, NIEBIESKI, ZIELONY=500, BIAŁY, CZARNY=700 };
Wtedy:
CZERWONY przyjmie wartość 100,
NIEBIESKI wartość 101,
ZIELONY wartość 500,
BIAŁY wartość 501,
CZARNY wartość 700.
Jeśli napisze się: