Zmienne i Typy
Zmienne i Typy
Deklaracje zmiennych
Deklaracje zmiennych
Każda nazwa w
C++
zanim zostanie użyta,
musi zostać
zadeklarowana
.
Deklaracja
informuje kompilator, że dana
nazwa reprezentuje obiekt określonego
typu, ale nie rezerwuje dla niego miejsca w
pamięci.
Definicja
zaś -
dodatkowo rezerwuje
miejsce. Definicja jest miejscem, gdzie
powołuje się obiekt do życia.
Oczywiście,
definicja
jest zawsze również
deklaracją
. Deklarować obiekt w programie
można wielokrotnie, natomiast definiować
można tylko raz.
Przykład:
int
licznik;
// definicja +
deklaracja
extern
int
licznik;
//
deklaracja
( tylko!)
Systematyka typów w C++
Systematyka typów w C++
Typy języka
C++
można podzielić
dwojako
:
Pierwszy
podział:
typy fundamentalne
;
typy pochodne
, które powstają na bazie
typów fundamentalnych.
Drugi
podział :
typy wbudowane
,
czyli takie, w które język
C++
jest wyposażony;
typy zdefiniowane
przez użytkownika.
Typy fundamentalne:
Typy fundamentalne:
Typy reprezentujące
liczby całkowite
:
short int
int
long int
Typ reprezentujący obiekty zadeklarowane
jako
znaki alfanumeryczne
:
char
Wymienione typy mogą być w dwóch
wariantach -
ze znakiem
i
bez znaku
. Do
wybrania
wariantu
posługujemy
się
odpowiednio modyfikatorami:
signed
unsigned
Przykłady:
signed int
x;
unsigned int
x;
Przez domniemanie przyjmuje się, że
zapis
int
a;
oznacza typ
signed int a
, czyli typ ze
znakiem.
Typy
reprezentujące
liczby
zmiennoprzecinkowe
:
float
double
long double
Typy te umożliwiają pracę na liczbach
rzeczywistych
z
różną dokładnością
.
Pamięć zajmowana przez zmienne różnych
typów:
typ
aplikacje 32-bitowe
char
1 bajt
short
2 bajty
int
4 bajty
long int
4 bajty
float
4 bajty
double
8 bajtów
long double
10 bajtów
bool
1 bajt
Zakres wartości różnych typów danych:
typ
aplikacje 32-bitowe
unsigned char
0
do
255
short
-32768
do
32767
int
-2147483648
do
2147483647
long
int
-2147483648
do
2147483647
float
1.210
-38
do
3.4 10
38
double
2.210
-308
do
1.8 10
308
long double
3.410
-4932
do
1.1
10
4932
bool
true
lub
false
Wewnętrzne reprezentacje
Wewnętrzne reprezentacje
danych
danych
:
:
0
1
5
0
3
1
int
long
int
16-bitowe całkowite
32-bitowe całkowite
0
1
5
short
int
0
3
1
int
long
int
Wewnętrzne reprezentacje
Wewnętrzne reprezentacje
danych
danych
:
:
Typy zmienoprzecinkowe
0
3
1
float
2
2
long double
7
9
0
6
4
double
0
6
3
5
1
- znak
wykładnika
-
wykładni
k
- znak
liczby
-
mantysa
Wewnętrzne reprezentacje
Wewnętrzne reprezentacje
danych
danych
:
:
Typy zmienoprzecinkowe
0
3
1
float
2
2
long double
7
9
0
6
4
double
0
6
3
5
1
- znak
wykładnika
-
wykładni
k
- znak
liczby
-
mantysa
1e35 + 2
2 0. 34(0) 2e35; 34*3b = 102 b
1e35 + 1e15
1e15 0. 19(0)1e35; 19*3b = 57 b
#include <iostream.h>
#include <conio.h>
int
main()
{
float
x;
clrscr();
x = 0;
x = x + 0.1;
x = x + 0.1;
x = x + 0.1;
x = x - 0.1;
x = x - 0.1;
x = x - 0.1;
cout << "x = " << x << endl;
getch();
return
0;
}
0.1 –
long double
(80 bitów)
x –
float
(32 bity)
Koprocesor wykonuje
obliczenia na 80 bitach
0.1
10
= 0001100110011...
2
Definiowanie obiektów “w biegu”
#include <iostream.h>
int
main ()
{
float
x;
//…
cout
<<
Podaj współczynnik kierunku
;
float
a;
cin
>>
a;
cout
<<
Podaj
współczynnik
przesunięcia
;
float
b;
cin
>>
b;
//… dalsze obliczenia
}
Stałe dosłowne
W programach często posługujemy się
stałymi. Mogą to być
liczby
,
znaki
albo
ciągi
znaków
.
Przykłady
:
x =
12.34
;
k = k +
14
;
znak =
*
;
ciag_znakow =
język C++
;
Stałe będące liczbami
całkowitymi
17
39
- 54
010
-
8
w systemie dziesiętnym
014
-
12
w systemie dziesiętnym (
8 + 4 = 12
)
091
-
błąd
, bo w systemie ósemkowym liczba
9
jest nielegalna
.
Liczby całkowite
ósemkowe:
Liczby całkowite
szesnastkowe:
0x10
-
16
w systemie dziesiętnym (
1*16 + 0 =
16
)
0xa1
-
161
w systemie dziesiętnym (
10*16 + 1
= 161
)
0xf
-
255
w systemie dziesiętnym (
15*16 +
15 = 255
)
Znaki
a, b, c, d, e, f
w liczbach oznaczają
odpowiednio
10, 11, 12, 13, 14, 15
w systemie
dziesiętnym.
W zapisie można posługiwać się zarówno
małymi literami, jak i wielkimi.
Stałe całkowite traktuje się jako typ
int
, chyba
że reprezentują tak wielkie liczby, które nie
zmieściłyby się w
int
. Wówczas stała taka jest
typu
long
.
Można zmienić typ nawet niewielkiej liczby z
typu
int
na typ
long
. Robi się to przez
dopisanie na końcu liczby litery
L
lub
l
:
0L
123L
Jeśli chcemy by liczba miała typ
unsigned
,
należy dopisać na końcu literę
u
.
Przykłady:
213u
34uL
main
()
{
int
i;
int
k, n, m, j;
clrscr ();
i = 5;
k = i + 010;
cout
<<
"
k=
"
<<
k
<<
endl
;
m = 100;
n = 0x100;
j = 0100;
cout
<<
"
m+n+j=
"
<<
(m+n+j)
<<
endl
;
cout
<<
"
wypisujemy:
"
<<
0x22
<<
" "
<<
022
<<
" "
<<
22
<<
endl
;
return
0;
}
k =
13
m+n+j =
420
wypisujemy:
34
18 22
Stałe zmiennoprzecinkowe
Przykłady:
12.3
3.1416
-123.45 -17.
5e2
oznacza
5 * 10
2
, czyli
500
32.5e4
oznacza
32.5 * 10
4
, czyli
325000
7.3e-3
oznacza
7.3 * 10
-3
, czyli
0.0073
Stałe znakowe
a
oznacza literę
a
8
oznacza cyfrę
8
(
nie liczbę
8
)
char
znak;
znak = ‘A’;
Znaki sterujące:
‘\
b
’
- cofacz
(ang.
B
ackspace
)
‘\
f
’
- nowa strona
(ang.
F
orm feed
)
‘\
n
’
- nowa linia
(ang.
N
ew line
)
‘\
r
’
- powrót karetki
(ang.
carriage
R
eturn
)
‘\
t
’
- tabulator poziomy (ang.
T
abulator
)
‘\
v
’
-
tabulator pionowy (ang.
V
ertical
tabulator
)
‘\
a
’
-
sygnał dźwiękowy (
A
larm
)
Znaki specjalne:
‘\
\
’
-
ukośnik lewostronny
‘\
’
’
-
apostrof
‘\
’
-
cudzysłów
‘\
0
’
-
NULL
, znak o kodzie
0
‘\
?
’
-
znak zapytania
Stałe tekstowe
Stała tekstowa to
ciąg znaków ujęty w cudzysłów
Przykłady:
Programowanie komputerów
język C++
Łańcuchy są przechowywane w pamięci jako
ciąg znaków, a na samym końcu tego ciągu
dodawany jest znak o kodzie
0
, czyli znak
NULL
.
Jeżeli cudzysłów ma stanowić jeden ze
znaków
ciągu,
należy
go
poprzedzić
ukośnikiem.
Przykładowo:
cout
<<
Polecam książkę J.Grębosza
<<
\ Symfonia C++\
;
Polecam książkę J.Grębosza Symfonia C++
Typy pochodne
Typy pochodne
są budowane na bazie
typów
fundamentalnych
.
Przykładem typu pochodnego może być
tablica
lub
wskaźnik
.
Możemy mieć kilka luźnych obiektów typu
int
, ale możemy je powiązać w
tablicę
obiektów typu
int
.
Tablica obiektów typu
int
jest typem
pochodnym od typu
int
.
Typy pochodne oznacza się stosując
nazwę
typu podstawowego
i
operator deklaracji
typu pochodnego
.
Przykład:
int
a;
// obiekt typu
int
int
b[10];
// tablica obiektów typu
int
(10-
elementowa)
Operatory tworzące obiekty typów
pochodnych:
[ ]
-
tablica
obiektów danego typu;
*
-
wskaźnik
do pokazywania na obiekty
danego typu;
( )
-
funkcja
zwracająca wartość danego
typu;
&
-
referencja
(przezwisko) obiektu danego
typu.
Przykład:
int
b;
// definicja obiektu typu
int
short int
c;
// definicja obiektu typu
short
float
x;
// definicja obiektu typu
float
int
t[20];
// tablica 20 elementów typu
int
float
*p;
// wskaźnik obiektu typu
float
char
funk();
// funkcja zwracająca wartość typu
char
Typy fundamentalne:
Typy pochodne:
Typ
void
void
*p; - oznacza, że
p
jest wskaźnikiem do
wskazywania obiektu
nieznanego typu.
void
fun(); - deklaracja ta mówi, że funkcja
fun
nie będzie zwracać żadnej
wartości.
Zakres ważności obiektu
Zakres ważności nazwy obiektu
, to ta część
programu, w której nazwa znana jest
kompilatorowi.
Czas życia obiektu
jest to okres od momentu,
gdy zostaje on zdefiniowany do momentu, gdy
przestaje istnieć, a jego miejsce w pamięci
zostaje zwolnione.
Różnica między zakresem ważności nazwy a
czasem życia obiektu jest taka, że w jakimś
momencie obiekt może istnieć, ale nie być
dostępny, ponieważ chwilowo znajdujemy się
poza zakresem jego ważności.
W zależności od tego, jak zdefiniowany jest
obiekt, zakres jego ważności może być różnego
rodzaju.
Zakres lokalny
#include <iostream.h>
int
main ()
{
{
int
x;
…
}
…
}
Zakres - blok funkcji
Zakres ważności ograniczony do
bloku funkcji
ma
etykieta.
Zakres - obszar pliku
Nazwa zadeklarowana na zewnątrz
jakiegokolwiek bloku, jest nazwą
globalną
. Ma
ona zakres
ważności pliku
.
Przykład:
float
x;
// nazwa
x
jest
globalna
int
main ()
{
// treść funkcji
}
Jednakże taka nazwa nie jest od razu
automatycznie znana w innych plikach. Jej
zakres ważności
ogranicza się
tylko
do tego
pliku
,
w którym ją zdefiniowano
.
Zasłanianie nazw
Przykład:
#include <iostream.h>
#include <conio.h>
int
k =33;
//zmienna
globalna
- PROG14.CPP
int
main ()
{
clrscr ();
cout
<<
"
Jestem w pliku głównym, k =
"
<<
k
<<
endl
;
{
//----------------------------------------------
int
k = 10;
//zmienna
lokalna
cout
<<
"
Po lokalnej definicji k =
"
<<
k
<<
endl
;
}
//----------------------------------------------
cout
<<
"
Poza blokiem k =
"
<<
k
<<
endl
;
return
0;
}
Jestem w pliku głównym, k =
33
Po lokalnej definicji k =
10
Poza blokiem k =
33
Istnieje możliwość odniesienia się do zasłoniętej
zmiennej globalnej za pomocą
operatora zakresu
::
(dwa dwukropki).
#include <iostream.h>
#include <conio.h>
int
k =33;
//zmienna
globalna - PROG15.CPP
int
main ()
{
clrscr ();
cout
<<
"
Jestem w pliku głównym, k =
"
<<
k
<<
endl
;
{
//----------------------------------------------
int
k = 10;
//zmienna
lokalna
cout
<<
"
Po lokalnej definicji k =
"
<<
k
<<
",
"
<<
endl
<<
"
ale obiekt globalny k =
"
<<
::k;
}
//----------------------------------------------
cout
<<
"\nPoza blokiem k =
"
<<
k
<<
endl
;
return
0;
}
Jestem w pliku głównym, k =
33
Po lokalnej definicji k =
10
,
ale obiekt globalny k =
33
Poza blokiem k =
33
Modyfikator
const
float
pi = 3.14;
const float
pi = 3.14;
Inicjowaniem
nazywamy nadanie obiektowi
wartości w momencie jego definicji.
Przypisaniem
nazywamy podstawienie do
obiektu wartości w jakimkolwiek późniejszym
momencie.
Obiekty
const
można inicjować, ale nie można
do nich nic przypisać
.
Instrukcja
typedef
Instrukcja
typedef
pozwala na nadanie
dodatkowej nazwy już istniejącemu typowi.
typedef int
cena;
cena x;
// co odpowiada:
int
x;
cena a, b, c;
// co odpowiada:
int
a, b, c;
Instrukcja
typedef
nie wprowadza nowego
typu, a
jedynie
synonim
do typu już
istniejącego.
Typ wyliczeniowy
enum
Wyliczenie deklaruje się słowem kluczowym
enum
, po którym następuje wykaz stałych
całkowitych oddzielonych przecinkiem i
zamkniętych w nawiasy klamrowe.
Wymienionym stałym są przypisywane wartości
domyślne: pierwszej z nich ‑ wartość
0
, a każdej
następnej - wartość o
1
większą od
poprzedzającej.
enum
{ pn, wt, sr, czw, pt, sob, nd }
const
pn = 0;
const
wt = 1;
…
const
nd = 6;
Stałym typu wyliczeniowego można również
przypisywać wartości
jawnie
, przy czym
wartości te
mogą się powtarzać
.
enum
{ poczatek, koniec = 0, dalej=1, cofnij = 1 };
W wyliczeniach można po
enum
umieścić
identyfikator, który staje się od tego momentu
nazwą nowego typu
, np.:
enum
dni_tygodnia {pn, wt, sr, czw, pt, sob, nd};
enum
dni_tygodnia {pn, wt, sr, czw, pt, sob, nd};
Typ wyliczeniowy
jest podobny do typów
char
oraz
int
.
Nie można jednakże na jego wartościach
wykonywać żadnych operacji arytmetycznych.
Gdy wartość typu wyliczeniowego pojawia się w
wyrażeniach arytmetycznych, to jest niejawnie
(ostrzeżenie) przekształcana do typu
int
przed
wykonaniem operacji.