osnovni tipovi podataka i operatori
TRANSCRIPT
Kolegij: Programski jezik C++
Ak. god. 2016/2017
Doc. Dr. Sc. Marko Maliković
Programiranje - Osnovni tipovi podataka i operatori -
Osnovni tipovi podataka Općenito podatke dijelimo na:
Konstante – nepromijenjive vrijednosti Najjednostavniji primjer su brojevi: 2, 5, 3.14159, ...
Varijable – podaci koji općenito mogu mijenjati svoj iznos Predstavljaju se svojim imenom (simboličkom oznakom):
x, y, i, j, BrojCipele, cijena_ulaznice, …
Svaki podatak ima dodijeljen deklarirani tip koji nam kaže: Koje su njegove moguće vrijednosti i dozvoljeni raspon Kakve operacije su moguće nad tim podacima
U jezik C++ su neki osnovni tipovi i operacije nad njima već ugrađeni Već znamo za tip int – tip cjelobrojnih vrijednosti
... ali postoje i drugi
Identifikatori (među koje spadaju i imena
varijabli) Identifikatori = Imena koja se dodijeljuju mnogim dijelovima
C++ programa kao na primjer: Varijablama Funkcijama (o kojima ćemo govoriti pred kraj kolegija) Klasama (o kojima će biti malo riječi na kraju kolegija) ...
Imena su proizvoljna ali se moraju poštovati tri pravila: 1. Mogu biti sastavljeni od:
Engleskog alfabeta
dakle, isključeni su hrvatski dijakritički znakovi
velika i mala slova se razlikuju
Znamenki
Znaka za podcrtavanje "_" (underscore)
2. Prvi znak mora biti slovo ili "_" 3. Ne smiju biti jednaki ključnim riječima (vidi tablicu →)
Ključne riječi jezika C++
Deklaracija varijabli Svaku varijablu treba prije korištenja deklarirati
Deklaracija varijable = Određivanje njenog tipa
Primjer: int a; - naredba kojom se određuje da će varijabla a biti cijeli broj
Brojevi: U C++ je ugrađeno nekoliko tipova brojeva:
Pozitivni i negativni cijeli brojevi (integer) tipa int
Vrlo kratki cijeli brojevi tipa short int
Dulji cijeli brojevi tipa long int
ako trebamo raditi s cijelim brojevima većim od određene vrijednosti
Još dulji cijeli brojevi tipa long long int
Realni brojevi tipa float
Dulji realni brojevi tipa double
Još dulji realni brojevi tipa long double
unsigned - neke cjelobrojne varijable ne mogu nikada poprimiti negativnu vrijednost pa ih možemo deklarirati kao:
unsigned int
unsigned long
Zašto uopće postoji deklaracija varijabli? Prevoditelj će varijable pohranjivati u memoriju prema prigodnim pravilima
Prevoditelj će znati kako provoditi operacije nad varijablama
Pridruživanje vrijednosti objektima
(inicijalizacija) Pridruživanjem vrijednosti objektu se mijenja njegova vrijednost, a tip ostaje isti:
objekt = vrijednost;
Na primjer:
Cijena = 25.65;
Ako su objekt i vrijednost različitog tipa onda se vrijednost svodi na tip objekta prema definiranim pravilima pretvorbe (pravila pretvorbe →)
Deklaracija i pridruživanje vrijednosti mogu se obaviti u istom retku:
int i = 5;
S desne strane pridruživanja se mogu nalaziti konstante i varijable:
int i = 5;
i = i + 3;
k = m + n;
Realni brojevi Realni brojevi (Floating-point) – brojevi s pomičnom
decimalnom točkom Deklariraju se riječju float:
float pi = 3.1415926;
Realni brojevi tipa double ili long double ako nam raspon i točnost broja float nije dovoljan
Svaki prevoditelj ima svoja ograničenja na raspone vrijednosti brojeva
Ako postoji mogućnost numeričkog preljeva (pojave broja većeg od predviđenog maksimuma): treba koristiti dulji tip jer se program može ponašati
nepredvidljivo
Provjera veličine pojedinih tipova #include <iostream>
#include <conio.h>
#include <climits>
#include <cfloat>
using namespace std;
int main()
{
cout << "Najmanji broj tipa short int: " << SHRT_MIN << endl;
cout << "Najveci broj tipa short int: " << SHRT_MAX << endl;
cout << "Najmanji broj tipa int: " << INT_MIN << endl;
cout << "Najveci broj tipa int: " << INT_MAX << endl;
cout << "Najmanji broj tipa long int: " << LONG_MIN << endl;
cout << "Najveci broj tipa long int: " << LONG_MAX << endl;
cout << "Najmanji broj tipa long long int: " << LLONG_MIN << endl;
cout << "Najveci broj tipa long long int: " << LLONG_MAX << endl;
cout << "Najmanji broj tipa float: " << FLT_MIN << endl;
cout << "Najveci broj tipa float: " << FLT_MAX << endl;
cout << "Najmanji broj tipa double: " << DBL_MIN << endl;
cout << "Najveci broj tipa double: " << DBL_MAX << endl;
cout << "Najmanji broj tipa long double: " << LDBL_MIN << endl;
cout << "Najveci broj tipa long double: " << LDBL_MAX << endl;
getch();
return 0;
}
Rezultat prethodnog programa
Aritmetički operatori Binarni operatori:
x + y – zbrajanje
x - y – oduzimanje
x * y – množenje
x / y – dijeljenje
x % y – modulo (ostatak dijeljenja cijelih brojeva)
Unarni operatori:
+x i -x – unarni plus i minus (mijenjanju predznak broju (+ nije obavezan))
x++ – uvećaj nakon (dohvaća vrijednost od x i onda je uveća za 1)
++x – uvećaj prije (uveća vrijednost od x za 1 i onda je dohvaća)
x-- – umanji nakon (dohvaća vrijednost od x i onda je umanji za 1)
--x – umanji prije (umanji vrijednost od x za 1 i onda je dohvaća)
Aritmetički operatori - potenciranje C++ nema automatski ugrađen operator za potenciranje
Potrebno je koristiti funkciju pow iz standardne matematičke biblioteke deklarirane u datoteci zaglavlja cmath:
// Potenciranje – ispisuje broj 3 na 5
#include <iostream> #include <cmath> using namespace std; int main() { cout << pow(3,5); return 0; }
Pravila provjere i pravila pretvorbe
Postoje dvije važne grupe pravila za rad s
tipovima podataka i operatorima:
Pravila provjere (eng. Type-checking rules) –
uočavaju neispravne operacije nad objektima
Pravila pretvorbe (eng. Conversion rules) –
određuju što će se dogoditi ako neka operacija
očekuje jedan tip podataka, a pojavi se drugi tip
podataka
Pravila pretvorbe odnosno: - Kako se ponašaju binarne operacije nad dva broja različitog tipa -
Ako su operandi različitih tipova tada se oni prije operacije svode na zajednički tip (to je obično složeniji tip)
Ova pravila su inače u programskom jeziku C++ vrlo precizno opisana ali mi ih opisujemo samo načelno i djelomično
Na primjer:
1. Ako je jedan broj tipa long double tada se i drugi broj pretvara u tip long double
long double x;
float y;
cout << x+y;
2. Ako je jedan broj tipa float tada se i drugi broj pretvara u tip float:
int a;
float b;
float c;
a=5;
b=7.36;
c=a+b;
cout << c;
Pažnja! Ako napišemo:
float x = 3 / 2;
… prevoditelj će brojeve 3 i 2 shvatiti kao cijele jer ne sadrže decimalnu točku
Zato će primjeniti cjelobrojno dijeljenje i rezultat će biti broj 1 Rješenje 1:
float x = 3. / 2.;
Rješenje 2:
float x = static_cast<float>(3)/static_cast<float>(2)
Naredbom static_cast <Tip> (Izraz) se izrazu Izraz privremeno dodjeljuje tip Tip
Pažnja! U slučaju kada baratamo varijablama, a ne konstantama, rješenje 1 nije moguće jer iza
naziva varijable ne možemo dodati točku (prevoditelj bi javio grešku)
Potrebno je upotrijebiti naredbu static_cast:
#include <iostream>
using namespace std;
int main()
{
int brojnik;
int nazivnik;
cin >> brojnik;
cin >> nazivnik;
float decimalan_broj = static_cast<float>(brojnik)/static_cast<float>(nazivnik);
cout << endl << decimalan_broj << endl;
return 0;
}
Gubitak podataka U slučaju kada varijablu inicijaliziramo znakom "="
moguće je izgubiti dio podataka zbog implicitnih
pretvorbi koje se dogadjaju
Npr, naredbom:
int a = 3.14;
se cjelobrojnoj varijabli pridružuje decimalan broj
Decimalan broj će se pretvoriti u cijeli odn. decimalne
znamenke će biti odbačene
Prevoditelj neće javiti grešku
Neki prevoditelji će javiti upozorenje da je moguć
gubitak podataka
Gubitak podataka
Inicijalizacija listom inicijalizatora U Standardu C++ 11 (uvedenom 2011) je uvedena
nova dodatna sintaksa za inicijalizaciju
Vrijednosti kojima se objekt inicijalizira se mogu
navesti u listi inicijalizatora unutar vitičastih zagrada: int a{2};
U slučaju kada je potrebno provesti sužavajuću
pretvorbu, prevoditelj u Code::Blocks će javiti
upozorenje:
int a{3.14};
(u slučaju int a = 3.14; nije javio niti
upozorenje)
Inicijalizacija listom inicijalizatora
Inicijalizacija listom inicijalizatora
Ako objektu proslijedimo praznu listu
inicijalizatora:
int a{};
tada će biti inicijaliziran na podrazumijevanu
vrijednost
U slučaju brojčanih tipova podrazumijevana
vrijednost je nula:
int a{};
cout << a << endl;
ispisuje nulu
Simboličke konstante Nekim veličinama ne želimo tijekom programa promijeniti
vrijednost
Da bismo to izbjegli, možemo upotrijebiti naredbu const:
const float povrsina = pow(r,2)*3.1415926;
Ako bismo nakon ovoga napisali:
povrsina = povrsina+1;
onda bi prevoditelj javio slijedeću grešku:
error: assignment of read-only variable 'povrsina'
Pobrojenja Ako u programu želimo koristiti elemente pojmovnih
skupova tada možemo koristiti takozvane pobrojane tipove (eng. Enumerated types):
enum Dani {Ponedjeljak,Utorak,Srijeda,Cetvrtak,Petak,Subota,Nedjelja};
Dani su tip podataka
Ponedjeljak, Utorak, ..., Nedjelja su identifikatori
Također, C++ prvom identifikatoru automatski dodjeljuje vrijednost 0, drugom vrijednost 1, itd
Pobrojenja omogućavaju da u kôdu umjesto brojčanih vrijednosti koristimo razumljivije simboličke nazive
Pobrojenja Vrijednost varijablama možemo pridružiti ovako:
#include <iostream> #include <conio.h> using namespace std; int main() { enum Dani {Ponedjeljak, Utorak, Srijeda, Cetvrtak,
Petak, Subota, Nedjelja}; Dani PosljednjiDanTjedna = Petak; getch(); return 0; }
Pobrojenja Ako želimo da niz počinje nekim drugim brojem (umjesto
nule) tada to moramo eksplicitno reći:
enum Dani {Ponedjeljak=1,Utorak,Srijeda,Cetvrtak,Petak,Subota,Nedjelja};
Eksplicitna dodjeljivanja vrijednosti možemo raditi svakako:
enum Likovi {Trokut = 3,
Cetverokut = 4,
Kvadrat = 4,
Peterokut,
Sesterokut,
Sedmerokut,
Osmerokut,
Oktagon = Osmerokut};
Još jedan primjer - šahovska ploča -
enum stupci {a = 1, b, c, d, e, f, g, h};
Pobrojenja
Pobrojanim tipovima se ne može baratati kao
cjelobrojnim vrijednostima u aritmetičkim
operacijama
Na primjer, slijedeći izraz će javiti grešku:
Dani PosljednjiDanTjedna = Petak;
Dani PrviDanVikenda = PosljednjiDanTjedna + 1;
Gornji problem se može riješiti ovako:
Dani PrviDanVikenda = static_cast <Dani> (PosljednjiDanTjedna + 1);
Poredbeni operatori
x < y - manje
x <= y - manje ili jednako
x > y - veće
x >= y - veće ili jednako
x == y - jednako
x != y - različito
Znakovne konstante tipa char Pišu se kao jedan znak unutar jednostrukih znakova navodnika:
char slovo_a = 'a';
cout << 'b' << endl;
Znakovne konstante i varijable se mogu uspoređivati:
// Uspoređivanje znakova
#include <iostream>
using namespace std;
int main()
{
cout << ('a' < 'b') << endl;
return 0;
}
Gornji kôd će ispisati broj 1 (koji označava true) jer je slovo a ispred slova b
Pseudonimi tipova Ponekad je čitljivije umjesto oznaka ugrađenih tipova
upotrebljavati sinonime čiji naziv preciznije opisuje sam objekt
U tu svrhu možemo koristiti ključnu riječ using: using NoviNazivTipa = IzvorniNazivTipa:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
using Koordinate = float;
Koordinate X;
Koordinate Y;
cin >> X;
cin >> Y;
float UdaljenostTockeOdIshodista=sqrt(pow(X,2)+pow(Y,2));
cout << endl << UdaljenostTockeOdIshodista << endl;
return 0;
}
Pseudonimi tipova Posebno je korisno upotrebljavati pseudonime tipova u
slučaju opisivanja vrlo složenih korisničkih tipova
Na primjer:
using Vektor3D = vector<vector<vector<double> > >;
Prije nego što je u C++ uvedena deklaracija pseudonima pomoću ključne riječi using, novo ime za već postojeći tip moglo se uvesti isključivo korištenjem ključne riječi typedef:
typedef double broj; // Vidimo da je redoslijed obrnut
Deklaracija pomoću typedef je i dalje podržana
Operator sizeof Unarni operator koji kao rezultat daje broj bajtova što ih operand zauzima u memoriji računala:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout << setw(13) << "char: " << sizeof(char) << endl;
cout << setw(13) << "short: " << sizeof(short) << endl;
cout << setw(13) << "int: " << sizeof(int) << endl;
cout << setw(13) << "long: " << sizeof(long) << endl;
cout << setw(13) << "long long: " << sizeof(long long) << endl;
cout << setw(13) << "float: " << sizeof(float) << endl;
cout << setw(13) << "double: " << sizeof(double) << endl;
cout << setw(13) << "long double: " << sizeof(long double) << endl;
return 0;
}
Operator sizeof
Operator sizeof Operator sizeof se može primijeniti i na izraze, pokazivače, reference, polja, korisnički
definirane tipove i objekte, …
Primjer:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int x;
cout << "Duljina od x u bajtovima: " << sizeof(x) << endl;
double f;
cout << "Duljina od f u bajtovima: " << sizeof(f) << endl;
cout << "Duljina od f*x u bajtovima: " << sizeof(f*x) << endl;
return 0;
}
Operator sizeof
Hijerarhija i redoslijed izvođenja operatora U matematici:
Podrazumijevani slijed operacija je slijeva na desno Međutim, ako se dvije operacije različitog prioriteta nađu jedna
do druge, prvo se izvodi operacija s višim prioritetom Na primjer:
U matematičkom izrazu: a+b∙c/d se prvo izvodi množenje b∙c, onda se rezultat dijeli sa d, i tek na kraju se rezultat pribraja broju a
Jednako funkcionira i C++ kôd: y=a+b*c/d Okruglim zagradama se može zaobići ugrađena hijerarhija
operatora Npr: Možda baš želimo izračunati y=(a+b)*c/d
U knjizi “Demistificirani C++” je u tablici 3.15 na strani 97 navedena hijerarhija i redoslijed izvođenja operatora Tablica u knjizi je vrlo široka jer sadrži sve operatore koji se
koriste u programskom jeziku C++ Za ovaj kolegij nam ta tablica nije potrebna