Download as pdf or txt
Download as pdf or txt
You are on page 1of 40

PROGRAMIRANJE

Korisnički definisani tipovi

3. predavanje (drugi deo)

Doc. dr Ivona Brajević

1
Korisnički definisani tipovi

SADRŽAJ PREZENTACIJE:
I Strukture

I Unije

I Nabrojivi tipovi

I Deklaracija typedef

I Polja bitova

2
Korisnički definisani tipovi

Uvod u koričnicki definisane tipove


Osnovni tipovi jezika C uglavnom nisu dovoljni za pogodno opisivanje svih podataka
u programu.

Iz tog razloga u programskom jeziku C postoji nekoliko načina za izgradnju korisničkih


tipova podataka.

Korisnički definisani tipovi podataka su pogodni za bolju organizaciju, predstavljanje, i


naravno čuvanje informacija o sličnim objektima.

Korisnički tipovi podataka u jeziku C su:


I Strukture

I Unije

I Polja bitova

I Nabrojivi tipovi

3
Korisnički definisani tipovi

Strukture
Struktura je skup jedne ili više promenljih, koje mogu biti različitih tipova,
grupisanih zajedno radi lakše manipulacije.

Definisanjem strukture uvodi se novi tip podataka i nakon toga mogu da se koriste
promenljive tog novog tipa, na isti način kao i za druge tipove.

Korišćenje struktura opisaćemo na primeru primeru razlomka:

U jeziku C ne postoji tip koji opisuje razlomke, ali može se definisati struktura koja
opisuje razlomke.

Razlomak može da bude opisan parom koji čine brojilac i imenilac, na primer, celobro-
jnog tipa.

Strukturu razlomak definišemo na sledeći način:

struct razlomak {
int brojilac ;
int imenilac ;
};

4
Korisnički definisani tipovi

Kako definišemo strukture?


Ključna reč struct započinje definiciju strukture.

Nakon nje, navodi se ime strukture.

Zatim se izmedu vitičastih zagrada navodi opis članova (ili polja) strukture.

Imena članova strukture se ne mogu koristiti kao samostalne promenljive, one postoje
samo kao deo složenijeg objekta.

Napomena
Prethodnom definicijom strukture razlomak uveden je novi tip podataka pod imenom
struct razlomak.

Promenljive ovog tipa još uvek nismo uveli.

5
Korisnički definisani tipovi

Razlog korišćenja struktura


Ukoliko se neki podatak sastoji iz više delova ovi delovi se mogu čuvati nezavisno u
zasebnim promenljivim.

Ovi programi su nedovoljno jasni i teški za održavanje, pa je pogodnije koristiti strukture.

Strukture omogućavaju da se povezane vrednosti (ne nužno istog tipa) tretiraju kao
jedna celina.

Na taj nacin one pomažu pri organizaciji i obradi kompleksnih podataka, posebno u
velikim programima.

Strukture mogu da sadrže promenljive proizvoljnog tipa


Dat je primer definicije strukture pod imenom struct student:

struct student {
char ime [40];
float prosek ;
};
U ovoj strukturi student je opisan pomoću dva atributa: ime i prosek.

6
Korisnički definisani tipovi

Članovi struktura mogu biti druge strukture


Dat je primer definicije strukture pod imenom struct dvojniRazlomak:

struct dvojniRazlomak {
struct razlomakGore ;
struct razlomakDole ;
};
Na ovaj način vidimo da strukture mogu biti ugnježdene.

Navodenje definicije strukture


Definicijom strukture uvodi se novi tip podataka koji se nakon definicije koristi kao i
bilo koji drugi tip.

Ova definicija se obično navodi van svih funkcija.

Ukoliko je navedena u okviru funkcije, ona može da se koristi samo u okviru te funkcije.

7
Korisnički definisani tipovi

Deklarisanje promenljivih tipa strukture


Prilikom deklarisanja promenljivih tipa strukture, kao deo imena tipa, neophodno je
korišćenje ključne reči struct.

Primer deklaracije konkretnih razlomaka:

struct razlomak a, b, c;
Definicijom strukture je opisano da se razlomci sastoje od brojioca i imenioca.

Navedenom deklaracijom uvode se tri konkretna razlomka koja se nazivaju a, b i c.

Moguća je i deklaracija sa inicijalizacijom, pri čemu se inicijalne vrednosti za članove


strukture navode izmedu vitičastih zagrada:

struct razlomak a = { 1, 2 };

8
Korisnički definisani tipovi

Komentar
Redosled navodenja inicijalizatora odgovara redosledu navodenja članova strukture.

Dakle, navedenom deklaracijom je uveden razlomak a čiji je brojilac 1, a imenilac 2.

Istovremeno definisanje strukture i deklarisanje i inicijalizacija promenljivih

struct razlomak {
int brojilac ;
int imenilac ;
} a = {1, 2}, b, c;

9
Korisnički definisani tipovi

Pristupanje članu strukture i ispis promenljive tipa strukture


Članu strukture se pristupa preko imena promenljive čiji je tip struktura iza koga se
navodi tačka, a onda ime člana.

a. imenilac
Ispis promenljive a tipa struct razlomak:

printf ("%d %d ", a.brojilac , a. imenilac );

Konflikti imena polja strukture i istoimenih promenljivih ne postoje


Naredni kod je korektan:

int brojilac = 5;
int imenilac = 3;
a. brojilac = brojilac ;
a. imenilac = imenilac ;

10
Korisnički definisani tipovi

Operacije nad promenljivim tipa strukture


Nad promenljivama tipa strukture dozvoljene su operacije dodele.

Nisu dozvoljeni aritmetički i relacijski operatori.

Operator sizeof se može primeniti i na ime strukturnog tipa i na promenljive tog tipa.

U oba slučaja dobija se broj bajtova koje struktura zauzima u memoriji.

Ovaj broj nekada moze da bude i veći od zbira veličina pojedinačnih polja strukture.

11
Korisnički definisani tipovi

Primer koji ilustruje korišćenje struktura

#include <string .h>


#include <stdio.h>
struct Knjiga
{
char naslov [50];
char autor [50];
int knjiga_id ;
};
int main( )
{
/* deklarisanje promenljive tipa struct Knjiga */
struct Knjiga knjiga1 ;
//Ne mozemo dodeliti vrednost nizu , npr. knjiga1 . naslov = " Misliti na
Javi ";
strcpy ( knjiga1 . naslov , " Misliti na jeziku C++");
strcpy ( knjiga1 .autor , " Bruce Eckel ");
knjiga1 . knjiga_id = 10;
/* Ispis informacija o knjizi */
printf ( " Naslov knjige : %s\n", knjiga1 . naslov );
printf ( " Author : %s\n", knjiga1 . autor);
printf ( "Redni broj knjige : %d\n", knjiga1 . knjiga_id );
return 0;
}

12
Korisnički definisani tipovi

Ispis iz programa
Naslov knjige: Misliti na jeziku C++

Author: Bruce Eckel

Redni broj knjige: 10

Komentar
U programu je korišćena funkcija strcpy(s,t) kopira string t u string s.

Kao što je rečeno, promenljivim knjiga1.autor ili knjiga1.naslov ne možemo dodeliti


vrednost jer su promenljive tipa niz.

13
Korisnički definisani tipovi
Nizovi struktura
Umesto da povezana skupina složenih podataka čuva u nezavisnim nizovima bolje je
koristiti nizove struktura.
Primer nizova struktura:
Potrebno imati podatke o imenima i broju dana meseci u godini.
Moguće je te podatke čuvati u nizu sa brojevima dana i u (nezavisnom) nizu imena
meseci.
Bolje je na sledeći način opisati strukturu koja sadrži broj dana i ime:

struct opis_meseca {
char ime [10];
int broj_dana ;
};
i koristiti niz ovakvih struktura:

struct opis_meseca meseci [13];

Napomena
Deklarisan je niz dužine 13 da bi se meseci mogli referisati po svojim rednim brojevima,
pri čemu se početni elelement ne koristi.
14
Korisnički definisani tipovi

Deklaracija niza strukture sa inicijalizacijom - primer

struct opis_meseca meseci [] = {


{ "" ,0 },
{ " januar " ,31 },
{ " februar " ,28 },
{ "mart" ,31 },
...
{ " decembar " ,31 }
};
Vitičaste zagrade se mogu izostaviti:

struct opis_meseca meseci [] = {


"" ,0 ,
" januar " ,31,
" februar " ,28,
"mart" ,31,
...
" decembar " ,31
};

15
Korisnički definisani tipovi

Komentar
Nakon navedene deklaracije:

Ime prvog meseca u godini se može dobiti sa meseci[1].ime;

Broj dana prvog meseca u godini se može dobiti sa meseci[1].broj dana.

Na sličan način se dobijaju i imena, odnosno broj dana ostalih meseci.

Broj elemenata ovako inicijalizovanog niza može se izračunati na sledeći način:

sizeof(meseci)/sizeof(struct opis meseca)

16
Korisnički definisani tipovi

Unije
Unije su slične strukturama, takodje objedinjuju nekoliko promenljivih koje ne
moraju imati isti tip.

Kod struktura se sva polja istovremeno popunjavaju i sva se mogu istovremeno ko-
ristiti.

Kod unije se u jednom trenutku može koristiti samo jedno polje.

Osnovna svrha unije je ušteda memorije.

Veličina unije odgovara veličini njenog najvećeg polja.

Sa druge strane, veličina strukture odgovara zbiru veličina njenih polja.

Skoro sva sintaksička pravila koja se odnose na strukutre se prenose i na unije.

Jedina razlika je da se umesto ključne reči struct koristi ključna reč union.

17
Korisnički definisani tipovi

Primer unije
Naredna unija omogućava korisniku da izabere da li će vreme da pamti kao ceo broj
sekundi ili kao razlomljen broj.

Oba polja ne mogu da se koriste istovremeno.

union vreme {
int obicno ;
float precizno ;
};
Nakon definisanja tipa unije, moguće je definisati i promenljive ovog tipa, na primer:

union vreme a;
a. obicno = 12;

18
Korisnički definisani tipovi

Primer računanja veličine unije

#include <stdio.h>

union Data
{
int i;
float f;
char str [20];
};
int main( )
{
union Data data;
printf ( " Velicina unije union Data: %d\n", sizeof (data));
return 0;
}
Ispis iz programa: Velicina unije union Data: 20

19
Korisnički definisani tipovi

Primer programa koji detaljnije opisuje upotrebu unije

#include <stdio.h>
#include <string .h>
union Data
{
int i;
float f;
char str [20];
};

int main( )
{
union Data data;

data.i = 10;
data.f = 220.5;
strcpy ( data.str , "C Programming ");

printf ( "data.i : %d\n", data.i);


printf ( "data.f : %f\n", data.f);
printf ( "data.str : %s\n", data.str);

return 0;
}

20
Korisnički definisani tipovi

Komentar
Rezultat prethodnog programa je:

data.i : 1917853763

data.f : 4122360580327794860452759994368.000000

data.str : C Programming

Možemo videti da su vrednosti članica i i f nedostupni, jer je poslednja operacija dodele


pomocu strcpy zauzela memorijsku lokaciju za uniju pa je stoga vidljiv samo član str
koji je i odštampan kako treba.

21
Korisnički definisani tipovi

Izmenjen program koji detaljnije opisuje upotrebu unije

#include <stdio.h>
#include <string .h>

union Data
{
int i;
float f;
char str [20];
};

int main( )
{
union Data data;
data.i = 10;
printf ( "data.i : %d\n", data.i);

data.f = 220.5;
printf ( "data.f : %f\n", data.f);

strcpy ( data.str , "C Programming ");


printf ( "data.str : %s\n", data.str);
}

22
Korisnički definisani tipovi

Komentar
Rezultat izmenjenog programa je:

data.i : 10

data.f : 220.500000

data.str : C Programming

U izmenjenom programu svaka promenljiva se koristi u različitim vremenskim


trenucima što je i svrha korišćenja unija u programu.

23
Korisnički definisani tipovi

Unije mogu da se koriste kao članovi struktura


Unije se mogu koristiti i kao članovi struktura.

Na primer, u programu se čuvaju i obradjuju informacije o studetima i zaposlenima na


nekom fakultetu.

Za svakoga se čuva ime, prezime i matični broj.

Za zaposlene se još čuva i koeficijent za platu, dok se za studente čuva broj indeksa:

struct akademac {
char ime_i_prezime [50];
char jmbg [14];
char vrsta;
union {
double plata;
char indeks [7];
} dodatno ;
};

24
Korisnički definisani tipovi

Unije mogu da se koriste kao članovi struktura


U ovom slučaju poslednji član strukture (dodatno) je unijskog tipa (sam tip unije nije
imenovan).

Član strukture vrsta tipa char sadrži informaciju o tome da li se radi o zaposlenom (na
primer, vrednost z) ili o studentu (na primer, vrednost s).

Promenljive plata i indeks dele zajednički memorijski prostor i podrazumeva se da


se u jednom trenutku koristi samo jedan podatak u uniji.

int main () {
struct akademac pera = {"Pera Peric", " 0101970810001 ", ’z’};
pera. dodatno .plata = 56789.5;
printf ("%f\n", pera. dodatno .plata);
struct akademac ana = {"Ana Anic", " 1212992750501 ", ’s’};
strcpy (ana. dodatno .indeks , " 12/123 ");
printf ("%s\n", ana. dodatno . indeks );
return 0;
}

25
Korisnički definisani tipovi

Nabrojivi tipovi (enum)


Nabrojivi tipovi – korisnicki definisani tip podataka koji sadrši celobrojne konstante.

Ovi tipovi se koriste da zamene konkretne brojeve u programu. Njihovim korišćenjem


čitljivost programa se može poboljšati. Definišu se korišćenjem ključne reči enum, na
primer:

enum znak_karte {
KARO ,
PIK ,
HERC ,
TREF
};
Nakon navedene definicije u programu se imena KARO, TREF, PIK i HERC mogu
koristiti umesto nekih konkretnih konstantnih brojeva.

Podrazumevane vrednosti konstanti su : KARO ima vrednost 0, PIK vrednost 1, HERC


vrednost 2 i TREF vrednost 3.

26
Korisnički definisani tipovi

Vrednosti pridružene imenima nabrojivih tipova


Obično nije važno koje su konkretne vrednosti pridružene imenima KARO, PIK, HERC,
TREF, već je dovoljno znati da su one sigurno medjusobno različite i celobrojne.

Moguće je i eksplicitno navodenje celobrojnih vrednosti.

Na primer:

enum znak_karte {
KARO = 1,
PIK = 2,
HERC = 4,
TREF = 8
};
Vrednosti nabrojivih tipova nisu promenljive i njima se ne može menjati vrednost.

27
Korisnički definisani tipovi

Promenljive nabrojivih tipova


Promenljive nabrojivih tipova se deklarišu uz obavezno ponovno korišcenje ključne reči
enum.

Na primer:

enum znak_karte znak;


Takodje, uz definiciju nabrojivog tipa moguće je odmah deklarisati i promenljive:

enum znak_karte {
KARO = 1,
PIK = 2,
HERC = 4,
TREF = 8
} znak;

28
Korisnički definisani tipovi

Nabrojivi tipova mogu da učestvuju u izgradnji drugih složenih tipova


Na primer:

struct karta {
unsigned char broj;
enum znak_karte znak;
} osam_herc = {8, HERC };

Primeri definicija nabrojivih tipova

enum boolean {NO , YES };


enum sedmica { NEDELJA , PONEDELJAK , UTORAK , SREDA , CETVRTAK ,
PETAK , SUBOTA };
enum meseci {JAN , FEB , MAR , APR , MAJ , JUN , JUL , AVG , SEP , OKT ,
NOV , DEC };
enum boje {CRVENA , ZELENA , PLAVA , LJUBICASTA , ZUTA , CRNA };
enum return_type {OK , FileError , TimeOut };

29
Korisnički definisani tipovi

Program u kome se koristi nabrojivi tip – primer 1

#include <stdio.h>

enum sedmica { NEDELJA , PONEDELJAK , UTORAK , SREDA , CETVRTAK ,


PETAK , SUBOTA };

int main ()
{
/* Deklaracija promenljive tipa enum sedmica */
enum sedmica today ;
danas = SREDA;
printf ("Dan %d",today +1);
return 0;
}
Ispis iz programa: Dan 4

30
Korisnički definisani tipovi

Ispis veličine promenljive nabrojivog tipa – primer 2

#include <stdio.h>
/* Definicija tipa nabrojivog tipa enum boolean i deklaracija
promenljive ovog tipa */
enum boolean {NE , DA} odgovor ;
int main ()
{
/* Promenljiva nabrojivog tipa moze da ima samo jednu
konstantnu vrednost .*/
odgovor = NE;
printf (" Velicina enum promenljve je %d bajta", sizeof ( odgovor
));
return 0;
}
Ispis iz programa: Velicina enum promenljve je 4 bajta

Veličina ove promenljive je jednaka veličini tipa int.

31
Korisnički definisani tipovi

Menjanje vrednosti celobrojnih konstanti u nabrojivom tipu – primer 3

#include <stdio.h>
enum boje {CRVENA , ZELENA = 3, PLAVA , LJUBICASTA , ZUTA , CRNA };
int main ()
{
/* Promenljiva nabrojivog tipa ima samo jednu konstantnu
vrednost .*/
enum boje b = ZELENA ;
printf ("Boja je: %d ", b);
b = PLAVA;
printf ("Boja je: %d ", b);
b = CRNA;
printf ("Boja je: %d ", b);
/* b = 3; -Greska jer se promenljivoj nabrojivog tipa ne moze
dodeliti ceo broj.*/
return 0;
}
Ispis iz programa: Velicina enum promenljve je 4 bajta

Veličina ove promenljive je jednaka veličini tipa int.

32
Korisnički definisani tipovi

Ispis iz programa
Na primer:

Boja je: 3
Boja je: 4
Boja je: 7

Nabrojivi tipovi mogu da učestvuju u izgradnji složenih tipova


Na primer:

struct karta {
unsigned char broj;
enum znak_karte znak;
} osam_herc = {8, HERC };

33
Korisnički definisani tipovi

Ključna reč typedef


U jeziku C ključna reč typedef se koristi da bi se kreirala nova imena postojećih tipova.

Na primer, deklaracija:

typedef int Length ;


uvodi ime Length kao sinonim za tip int.

Ime tipa Length se onda može koristiti u deklaracijama, eksplicitnim konverzijama i


slično, na isti način kao što se koristi ime int:

Length len , maxlen ;


Obično se novouvedena imena tipova pišu velikim početnim slovima da bi se istakla.

Deklaracijom typedef se ne kreira novi tip vec se samo uvodi novo ime za potojeci
tip.

Staro ime za taj tip se može koristiti i dalje.

34
Korisnički definisani tipovi

Korišćenje deklaracije typedef


Deklaracije typedef se često koristi u kombinaciji sa strukturama da bi se izbegla
upotreba ključne reči struct pri svakom korišcenju promenljive ovog tipa. Na primer,
deklaracija:

struct point {
int x, y;
};
typedef struct point Point;
Point a, b;
Definicija strukture i pridruživanje novog imena se mogu uraditi istovremeno. Na
primer:

typedef struct point {


int x, y;
} Point ;
Point a, b;

35
Korisnički definisani tipovi

Svrha upotrebe ključne reči typedef


I Estetskih razlozi.

I Parametrizovanje tipova u programu da bi se dobilo na njegovoj prenosivosti.


Ukoliko se typedef koristi za uvodenje novih imena za tipove koji su mašinski
zavisni, u slučaju da se program prenosi na drugu mašinu, potrebno je promeniti
samo typedef deklaracije.
I Poboljšanje čitljivosti programa.

Napomena
Jedan od primera je upotrebe typedef je za imenovanje celobrojnog tipa, i zatim odabir
short, int i long u zavisnosti od mašine.

36
Korisnički definisani tipovi

Program koji ilustruje upotrebu typedef radi lakšeg rada

#include <stdio .h>


#include <math.h>

/* Deklaraciju strukture i typedef mozemo spojiti */


typedef struct point
{
int x;
int y;
} POINT;

int main ()
{
/* Definisemo promenljivu tipa tacke.
Umesto struct point mozemo koristiti POINT */
POINT a;
/* Postavljamo vrednosti koordinata tacke a*/
a.x = 3; a.y = 4;
/* Ispisujemo velicinu strukture tacka */
printf (" sizeof ( struct point) = %d\n", sizeof (POINT));
/* Ispisujemo vrednosti koordinata tacaka */
printf ("x koordinata tacke a je %d\n", a.x);
printf ("y koordinata tacke a je %d\n", a.y);
return 0;

37
Korisnički definisani tipovi

Ispis iz prethodnog programa


sizeof(struct point) = 8

x koordinata tacke a je 3

y koordinata tacke a je 4

Deklaracija typedef i direktiva #define


Deklaracija typedef je slicna pretprocesorskoj direktivi define, s tim što nju obradjuje
kompilator (a ne pretprocesor).

38
Korisnički definisani tipovi

Polja bitova
Pored unije, jedan od načina uštede memorije u C programima su polja bitova (engl. bit
fields).

Definisanjem polja bitova moguce je deo memorije iscepkati u individualne grupe


kojima se posle može pristupiti preko imena.

Primer:

Želimo da predstavimo grafičke karakteristike pravougaonika u nekom programu za


crtanje.

Neka je dopušteno samo 4 boje (crvena, plava, zelena, i crna) koje mogu da se predstave
pomocu 2 bita.

Vrsta okvira (pun, isprekidan) moze da se predstavi sa jednim bitom.

Na kraju, da li pravougaonik treba ili ne treba popunjavati mozemo predstaviti sa jednim


bitom.

39
Korisnički definisani tipovi

Polja bitova (2)


Ove podatke mozemo da upotrebimo da bismo definisali naredno polje bitova:

struct osobine_pravougaonika {
unsigned char popunjen : 1;
unsigned char boja : 2;
unsigned char vrsta_okvira : 1;
};
Iza svake promenljive naveden je broj bitova koji je potrebno odvojiti za tu promenljivu.

Veličina ovako definisanog polja bitova (vrednost izraza sizeof (struct os-
obine pravougaonika)) je samo 1 bajt. Iako je potrebno samo 4 bita, svaki podatak
mora da zauzima ceo broj bajtova).

Obična struktura bi zauzimala 3 bajta.

Polje bitova se nadalje koristi kao obična struktura.

40

You might also like