You are on page 1of 15

5 OPERATORI I IZRAZI

Sadržaj
• klasifikacija operatora
• pregled operatora
• konverzija
• niz izraza
• veličina podatka
• redosled primene operatora
• bibliotečke funkcije

• C ima preko 40 operatora na 15 nivoa prioriteta


• indeksiranje i selektor kod strukture i unije su
operatori; dodela je takođe operator; svaki poziv
funkcije sa n argumenata tretira se kao n+1-arni
operator (n+1-vi operand je ime funkcije)
• ima ih unarnih, binarnih i jedan ternarni
• operatori na istom nivou prioriteta podrazumevano
se izvršavaju s leva u desno, ali neki se izvršavaju s
desna u levo (ovo se zove smer grupisanja)
• svi operatori generišu rezultat

3
Klasifikacija operatora
(približno opadajući nivo prioriteta)
• adresni operatori
• aritmetički operatori
• relacioni operatori
• bit-operatori
• logički operatori
• operatori dodele
• operator , (zapeta)

Binarni aritmetički operatori


+ sabiranje
- oduzimanje
* množenje
/ deljenje
% ostatak pri deljenju (za celobrojne operande)
Deljenje: ako su oba operanda celobrojna, znak /
predstavlja celobrojno deljenje (razlomljeni deo se
odseca); u suprotnom radi se o običnom deljenju
5.0/2 daje 2.5
5/2 daje 2
9999/10000 daje 0

Unarni operatori + i -
• unarni operator – predstavlja promenu
predznaka
• unarni operator + je potvrda predznaka (nema
dejstvo)
Ako je x bilo jednako 10 tada je rezultat –x
jednak -10, a +x jednako je 10

6
Bočni efekat
• operator ima bočni efekat ako menja vrednost
operanda
• operand koji menja vrednost mora posedovati
lokaciju u memoriji; takve vrednosti nose
naziv LVALUE (LVREDNOST)
• LVALUE su promenljive, indeksirani izrazi,
selektovana polja, dereferencirani pokazivači i
kombinacije:
LVALUE: promenljiva [] . *

Operatori inkrementa i dekrementa


• unarni aritmetički operatori sa bočnim efektom
• dakle, generišu rezultat i menjaju vrednost operanda
• operand može biti bilo kojeg baznog tipa (uključujući i
realni), a može biti i tzv. pokazivač
• označavaju se sa ++ (inkrement) i -- (dekrement)
• pišu se ili ispred operanda (prefiksna forma) ili iza
operanda (postfiksna forma)

Neka je k neka int promenljiva i neka ima


trenutnu vrednost 10.
prefiksni inkrement je ++k
postfiksni inkrement je k++
U oba slučaja bočni efekat je povećanje
vrednosti k za 1; rezultat je k+1 kod prefiksnog
ili k kod postfiksnog
(k=10)
++k rezultat je 11; k postaje 11
k++ rezultat je 10; k postaje 11
9
• pažnja:
x = x + 1; //izrazito los stil programiranja u C-u
x++; odnosno ++x; //u C-u se pise ovako!

10

• dekrement -- ponaša se analogno, samo što


se ovde dešava umanjenje za 1
(k=10)
--k rezultat je 9; k postaje 9
k-- rezultat je 10; k postaje 9

11

Primeri
x = 1; y = 5;
x--+y++ //rezultat: 6, x=0, y=6

p = 10; q = 20;
++q-p-- //rezultat: 11, p=9, q=21

r = 2; s = 4;
r+++++s //rezultat: 7, r=3, s=5

12
Relacioni operatori

• standardnih 6:
== (jednako) != (nejednako)
< (manje) <= (manje ili jednako)
> (veće) >= (veće ili jednako)

rezultat je 0 ili 1!

13

Primeri
a = 1; b = 5;
4*(a < b) //rezultat: 4

p = 10; q = 20;
p == q //rezultat: 0

x = 0.3; y = 0.5; z = 0.7;


x < y < z //oprez!

14

• ako je x=0.3, y=0.5, z=0.7 rezultat izraza


=1 =0.7
x < y <z

neće biti 1 nego 0!

• zato je sigurnije pisati onako kako se piše i u


drugim programskim jezicima
(x < y) && (y < z)
gde je && operator konjunkcije

15
Logički operatori
&& konjunkcija
|| disjunkcija
! negacija
• rezultat je 0 (u ulozi F) ili 1 (u ulozi T)
• operandi su izrazi baznog tipa; vrednost operanada:
=0 (u ulozi F) ≠0 (u ulozi T)
a = 5; b = 0; c = -3.8
a && b //rezultat je 0
b || c //rezultat je 1
!c //rezultat je 0

16

optimizacija
• računanje konjunkcije i disjunkcije je uvek
optimizovano; ako je kod konjunkcije jedan
operand =0 drugi se možda neće izračunavati
jer je rezultat sigurno 0; kod disjunkcije isto,
samo za vrednost 1; da li će optimizacija biti
primenjena ili neće zavisi od konkretnog
slučaja i programer to ne zna!

17

oprez!
• ako neki operand ima bočnih efekata treba
biti oprezan bočni efekat

(a-b) && (c+d++)


ako je a-b=0 i ako se a-b računa prvo, bočni
efekat neće biti izveden i d neće promeniti
vrednost; ako se prvo računa c+d++ bočni efekat
biće izveden! Rešenje je:
x = d++;
(a-b) && (c+x)
18
Bit - operatori
• operatori koji se izvode nad pojedinačnim bitovima
celobrojnih operanada
• služe za rad sa memorijskim registrima na nivou bita
& bit-konjunkcija
| bit-disjunkcija
^ bit-ekskluzivna disjunkcija
~ bit-negacija (komplementiranje)
<< šift ulevo
>> šift udesno

19

• bit-konjunkcija, disjunkcija i ekskluzivna


disjunkcija izvode se, međusobno nezavisno
nad odgovarajućim parovima bitova
operanada
x 0110 1100
y 1101 0110
x&y 0100 0100

• komplementiranje: unarni operator; svaka 0


pretvara se u 1 i svaka 1 u 0
• u opštem slučaju
x&y ≠ x&&y x|y ≠ x||y !x ≠ ~x
20

Šiftovanje (pomeranje)
• bitovi levog operanda pomeraju se ulevo ili
udesno za broj pozicija naznačen desnim
operandom
• kod šifta ulevo << upražnjene pozicije
popunjavaju se nulama
• kod šifta udesno upražnjene pozicije
popunjavaju se nulama ako je levi operand
unsigned, odn. bitom predznaka ako je levi
operand signed

21
• neka je unsigned x = 0011 1101; tada
x << 2 daje rezultat 1111 0100
x >> 2 daje rezultat 0000 1111
• uočiti da šift ulevo za n pozicija ima isti efekat
kao množenje sa 2n, a šift udesno za n pozicija
isti efekat kao celobrojno deljenje sa 2n

22

Uslovni operator
• ternarni operator (ima 3 operanda)
• opšti oblik
izraz1 ? izraz2 : izraz3
• rezultat je jednak izraz2 ako je izraz1≠0
odnosno izraz3 ako je izraz1=0
• primer:
(a>b) ? a : b
daće za rezultat veću od vrednosti a odnosno b

23

Operatori dodele
• dodela je u C-u operator
• postoji ukupno 11 operatora dodele: tzv.
osnovni operator dodele i još 10 posebnih
• svi imaju smer grupisanja s desna u levo
• svi imaju bočni efekat

24
Osnovni operator dodele
• opšti oblik
LVALUE = izraz
• bočni efekat je dodela vrednosti izraza
objektu LVALUE
• rezultat je vrednost LVALUE (tj. levog
operanda) posle dodele

25

Primeri
x = 5 //x dobija vrednost 5; rezultat je 5
y = 2*z // y dobija vrednost 2*z i to je rezultat
a = b = c = d = 1 //a,b,c,d su 1; rezultat je 1
tzv. višestruka dodela
a = b++*(1-x)+(d=c<<3)
++s||(t=3*p)

26

Ostali operatori dodele


• svi imaju istu strukturu i ponašanje
LVALUE op= izraz
• sa značenjem
LVALUE = LVALUE op izraz
gde oznaka op predstavlja jedan od operatora
+ - * / % & | ^ << >>
Dakle, operatori su
+= -= *= /= %= &= |= ^= <<= >>=
27
x += y  x = x+y
p[i] *= (k=j+1)  p[i] = p[i]*(k=j+1)
t -= q += 3  t = t-(q=q+3)
• smatra se vrlo lošim stilom programiranja
pisati npr. a=a+b umesto a+=b, iako je efekat
isti; dakle,
p -= 3  p = p-3

28

Konverzija
• C dozvoljava gotovo potpuno mešanje tipova u
binarnim izrazima, tj. u izrazu α op β podizrazi α i β
mogu biti ma kojeg baznog tipa
• direktno izvršavanje operacija nad različitim tipovima
nije moguće zbog ograničenja računara
• u toku izvođenja operacije op tipovi operanada
moraju se izjednačiti (bez uticaja na same operande!)
• takvo izjednačavanje nosi naziv konverzija

29

Vrste konverzije
• konverzija može biti:
– implicitna (na bazi ugrađenih pravila obezbeđuje
je kompajler) ili
– eksplicitna (na zahtev programera, posredstvom
posebnih operatora); eksplicitna konverzija zove
se još i kast (od type cast)

30
Implicitna konverzija
• dva pravila: jedno za sve operatore osim dodele i drugo za
operatore dodele
• svi operatori osim dodele: koristi se tzv. tablica složenosti,
pri čemu se manje složen tip konvertuje u složeniji;
1. long double
2. double
3. float
4. (promocija) char, short i enum u int (jedan ili oba operanda)
5. long
6. int
• unsigned varijanta je složenija od signed

31

int i,j; double d; char c1,c2; long double ld;


d+j //j u double; rezultat double
ld-i //i u long double; rezultat long double
c1+c2 //c1 i c2 u int; rezultat int
(d+c1)*(i/j)+ld //krajnji rezultat long double
double int

double long double

long double

32

konverzija kod dodele


• za njih važi posebno pravilo: tip desnog
operanda prilagođava se tipu levog operanda
(zbog bočnog efekta operatora dodele)

int j; double d;
j = 3.8 //j = rezultat = 3; decimale se seku
d = 23 //d = rezultat = 23.0
j = 1e12 // j i rezultat su slucajni! 1e12 preveliko
33
eksplicitna konverzija (kast)
• primenom posebnih unarnih operatora
vrednost izraza se konvertuje u ciljni tip, bez
obzira na to kakav je tip vrednosti
• oblik svih operatora kasta je
(tip)
gde je tip ciljni tip u koji se konvertuje
• operatori se primenjuju na izraze; vrednosti
samih izraza ostaju nepromenjene!
• primeri: (int) (long double) (long) (float)
34

double x=3.5; int k=10;

(long)k //rezultat je 10L


(long double)(x+k) //rezultat je 13.5L
(unsigned)k //rezultat je 10U

35

Niz izraza
• niz izraza je sredstvo za objedinjavanje više
izraza u jedan; to se postiže primenom
operatora ,
• opšti oblik:
izraz1,izraz2,...,izrazn
• izrazi se računaju s leva u desno, a vrednost
celog niza jednaka je rezultatu krajnjeg desnog
izraza (izrazn) vrednost celog niza izraza

x=10 , y+=x , z*=y , y-- , t=++z


36
Veličina podatka
• u određenim slučajevima neophodno je odrediti
koliko bajtova zauzima neki podatak
• standardi ne garantuju skoro ništa (npr. int može da
zauzima 2 bajta ili 4 bajta)
• veličina se dobija operatorom sizeof, koji može da se
primeni na tip ili na vrednost
• sizeof(tip) daje veličinu podataka datog tipa;
primenjuje se na bazne tipove i sve tipove definisane
sa typedef
• (sizeof)izraz daje veličinu u bajtovima vrednosti
izraza

37

typedef struct {double a; int b;} MyRecord;


int a; MyRecord rec;

sizeof(double) //velicina double podataka


sizeof(MyRecord) //velicina MyRecord

sizeof a //velicina promenljive a (tj. velicina int)


sizeof rec //velicina promenljive rec
sizeof (a+1.5) //velicina izraza a+1.5 (tj. velicina double)

38

Redosled primene operatora


• redosled primene susednih operatora
regulisan je prioritetom i upotrebom zagrada
• redosled primene nesusednih operatora nije
regulisan nikakvim pravilima
nesusedni operatori
• primer:
a*b + c/d
sigurno je da će množenje i deljenje biti
izvedeno pre sabiranja; ne zna se da li će prvo
biti izvedeno množenje, a zatim deljenje ili
obrnuto
39
• ovo važi u svim programskim jezicima, ali
može da stvori problem samo tamo gde ima
bočnih efekata
a*b + b++
ne zna se kojom vrednošću b će biti pomnoženo
a: originalnom ili uvećanom za 1
• situacija se prepoznaje po tome što se
nesusedni operatori primenjuju na istu
promenljivu, a bar jedan ima bočni efekat

40

• rešenje je uvesti pomoćne izraze


x = b; ili x = b+1; //zavisi od toga sta programer hoće
a*x + b++

41

Bibliotečke funkcije
• gotovi potprogrami (tipa sin, printf itd.) raspoređeni
su u biblioteke, prema srodnosti poslova koje
obavljaju
• imena svih standardnih funkcija pišu se isključivo
malim slovima
• pre prve upotrebe bilo koje standardne funkcije
mora se, direktivom #include naznačiti zaglavlje
biblioteke u kojoj se funkcija nalazi:
#include <zaglavlje.h>
• pored funkcija, u bibliotekama se nalaze i drugi
elementi C-a: simboličke konstante, gotovi tipovi itd.

42
zaglavlja standardnih biblioteka
• stdio.h - funkcije za ulaz-izlaz
• math.h - matematičke funkcije
• string.h - rad sa stringovima
• stdlib.h - razne funkcije, uključujući i one za
rad sa pokazivačima
• u praksi se pojavljuju još neke biblioteke, pa
uvek treba proveriti skup i sadržaj biblioteka
koje nudi konkretan C-ov sistem

43

Rezime
• klasifikacija operatora: adresni, aritmetički, relacioni,
logički, bit-operatori, dodele, uslovni, operator ,
• pregled operatora
• konverzija se vrši prilikom izračunavanja mešovitih
izraza
• niz izraza služi za grupisanje izraza u jedan
• veličina podatka nije garantovana
• redosled primene operatora za nesusedne operatore
nije unapred određen
• bibliotečke funkcije su gotovi potprogrami i deo su C-a

44

You might also like