9. Strukture¶
Podeli svoje utiske o poglavlju na anketi OVDE.
Preduslovi za rad:
Poznavanje tipova podataka
Poznavanje nizova
Poznavanje stringova
Poznavanje funkcija
Predstavljaju složene tipove podataka koji se prave kombinovanjem više primitivnih tipova i/ili ranije formiranih složenih tipova.
Koriste se kada imamo vrednosti različitih tipova podataka koje su međusobno povezane. Na primer, student je opisan imenom,
prezimenom, prosekom, i brojem indeksa. Navedena obeležja predstavlja podatke o studentu koji su međusobno povezani i mogu se
predstaviti strukturom student. Knjiga je opisana nazivom, izdavačem i brojem stranica, pa se tako ona može predstaviti strukturom
knjiga koja sadrži sva navedena obeležja. Struktura se definiše se upotrebom reči struct
koju prate vitičaste zagrade i ;
Osnovna forma strukture je:
struct ime_strukture
{
tip promenljiva_1;
tip promenljiva_2;
...
};
gde je tip
bilo koji od osnovnih ili složenih tipova podataka, dok je novokreirani tip podatka struct ime_strukture
.
Napomena:
Struktura se definiše iznad main funkcije, na početku programa, posle include i define sekcija. Kada se struktura definiše,
ne zauzima se nikakva memorija za nju. Da bi program zauzeo memoriju strukture potrebnog tipa, neophodno je deklarisati
promenljivu koja je tog tipa i raditi sa tom promenljivom.
Primer strukture:
#define MAX_MARKA 51
#define MAX_MODEL 51
struct automobil
{
char marka[MAX_MARKA];
char model[MAX_MODEL];
int kubikaza;
int godiste;
float cena;
};
U primeru je data struktura automobil sa poljima marka i model koju su char
tipa, dužine 50 karaktera, kubikaža i godište koji
su int
tipa i cena koja je float
tip podatka. Tip ove strukture je struct automobil
.
9.1. Primer unosa podataka u strukturu¶
Dat je primer programa u kome se unose podaci o automobilima koji se nakon toga ispišu na terminal:
1#include <stdio.h>
2
3#define MAX_MARKA 51
4#define MAX_MODEL 51
5
6struct automobil
7{
8 char marka[MAX_MARKA];
9 char model[MAX_MODEL];
10 int kubikaza;
11 int godiste;
12 float cena;
13};
14
15int main()
16{
17
18 struct automobil a;
19
20 printf("Unesite marku: ");
21 scanf("%s", a.marka);
22 printf("Unesite model: ");
23 scanf("%s", a.model);
24 printf("Unesite kubikazu: ");
25 scanf("%d", &a.kubikaza);
26 printf("Unesite godiste: ");
27 scanf("%d", &a.godiste);
28 printf("Unesite cenu: ");
29 scanf("%f", &a.cena);
30
31 printf("\nModel autmobila %s marke %s sa kubikazom %d proizveden %d. godine je cene %.2f\n", a.model, a.marka, a.kubikaza, a.godiste, a.cena);
32
33 return 0;
34}
U primeru iznad je deklarisana promenljiva tipa struct automobil
koja se zove a
. Da bi se unele vrednosti svih polja ove strukture, neophodno
je svaku vrednost smestiti u odgovarajuće polje. Za pristup poljima strukture koristi se .
, pa se tako za pristup polju kubikaza
strukture a
tipa struct automobil
mora navesti a.kubikaza
ukoliko je potrebna vrednost promenljive, dok se za korišćenje adrese mora navesti &a.kubikaza
. Isto
se odnosi i na ostala polja strukture, s tim da se sa stringom radi bez korišćenja &
operatora za pristup adresi.
Ispis programa:
Unesite marku: Ford
Unesite model: Fiesta
Unesite kubikazu: 1599
Unesite godiste: 2023
Unesite cenu: 20345.92
Unesite marku: Citroen
Unesite model: C3
Unesite kubikazu: 1650
Unesite godiste: 2022
Unesite cenu: 19827.38
Model autmobila Fiesta marke Ford sa kubikazom 1599 proizveden 2023. godine je cene 20345.92
Model autmobila C3 marke Citroen sa kubikazom 1650 proizveden 2022. godine je cene 19827.38
9.2. Typedef¶
Ključna reč typedef
se koristi za preimenovanje tipa (pravljenje aliasa) za određeni tip podatka. U slučaju strukture, zgodna nam je za korišćenje
kako bi pojednostavili sintaksu.
Osnovna forma ovakve strukture je:
typedef struct ime_strukture
{
tip promenljiva_1;
tip promenljiva_2;
...
} NOVO_IME;
gde je novokreirani tip podatka NOVO_IME
umesto struct ime_strukture
.
9.3. Primer unosa podataka strukture kroz funkciju¶
1#include <stdio.h>
2
3#define MAX_MARKA 51
4#define MAX_MODEL 51
5
6struct automobil
7{
8 char marka[MAX_MARKA];
9 char model[MAX_MODEL];
10 int kubikaza;
11 int godiste;
12 float cena;
13};
14
15void unos_automobila(struct automobil *);
16void ispis_automobila(struct automobil);
17
18int main()
19{
20
21 struct automobil a1;
22 struct automobil a2;
23 unos_automobila(&a1);
24 printf("\n");
25 unos_automobila(&a2);
26
27 ispis_automobila(a1);
28 ispis_automobila(a2);
29
30 return 0;
31}
32
33
34void unos_automobila(struct automobil *a)
35{
36 printf("Unesite marku: ");
37 scanf("%s", a->marka);
38 printf("Unesite model: ");
39 scanf("%s", (*a).model);
40 printf("Unesite kubikazu: ");
41 scanf("%d", &(a->kubikaza));
42 printf("Unesite godiste: ");
43 scanf("%d", &((*a).godiste));
44 printf("Unesite cenu: ");
45 scanf("%f", &(a->cena));
46}
47
48void ispis_automobila(struct automobil a)
49{
50 printf("\nModel autmobila %s marke %s sa kubikazom %d proizveden %d. godine je cene %.2f\n", a.model, a.marka, a.kubikaza, a.godiste, a.cena);
51}
1#include <stdio.h>
2
3#define MAX_MARKA 51
4#define MAX_MODEL 51
5
6typedef struct automobil
7{
8 char marka[MAX_MARKA];
9 char model[MAX_MODEL];
10 int kubikaza;
11 int godiste;
12 float cena;
13} AUTO;
14
15void unos_automobila(AUTO *);
16void ispis_automobila(AUTO);
17
18int main()
19{
20
21 AUTO a1, a2;
22 unos_automobila(&a1);
23 printf("\n");
24 unos_automobila(&a2);
25
26 ispis_automobila(a1);
27 ispis_automobila(a2);
28
29 return 0;
30}
31
32
33void unos_automobila(AUTO *a)
34{
35 printf("Unesite marku: ");
36 scanf("%s", a->marka);
37 printf("Unesite model: ");
38 scanf("%s", (*a).model);
39 printf("Unesite kubikazu: ");
40 scanf("%d", &(a->kubikaza));
41 printf("Unesite godiste: ");
42 scanf("%d", &((*a).godiste));
43 printf("Unesite cenu: ");
44 scanf("%f", &(a->cena));
45}
46
47void ispis_automobila(AUTO a)
48{
49 printf("\nModel autmobila %s marke %s sa kubikazom %d proizveden %d. godine je cene %.2f\n", a.model, a.marka, a.kubikaza, a.godiste, a.cena);
50}
U oba primeru iznad deklarisane su 2 promenljive. U primeru bez typedef
, promenljive su tipa struct automobil
i zovu se
a1
i a2
, dok su u primeru sa typedef
promenljive takođe tipa struct automobil
, ali se umesto ovog tipa može koristiti alias
AUTO
. Prvo se poziva funkcija unos_automobila
za a1
kroz koju se unose vrednosti
svih polja, pa se isto ponavlja i za a2
. Nakon toga se poziva funkcija ispis_automobila
za a1
, pa za a2
. Funkciji
unos_automobila
se struktura prosleđuje po pokazivaču, pa je pristup poljima strukture drugačiji nego u prvom primeru.
Pristup strukturi prosleđenoj po pokazivaču je moguć na 2 načina:
korišćenjem kombinacije
*
i.
operatorakorišćenjem
->
operatora
Napomena:
Oba načina rade istu stvar, prvo je neophodno dereferencirati celu strukturu, pa tek onda pristupiti traženom polju.
Iako je kombinacija dereferenciranja i tačke moguća, uvek se koristi operator -> zbog konciznosti programa.
Obe varijante primera daju isti ispis programa:
Unesite marku: Ford
Unesite model: Fiesta
Unesite kubikazu: 1599
Unesite godiste: 2023
Unesite cenu: 20345.92
Unesite marku: Citroen
Unesite model: C3
Unesite kubikazu: 1650
Unesite godiste: 2022
Unesite cenu: 19827.38
Model autmobila Fiesta marke Ford sa kubikazom 1599 proizveden 2023. godine je cene 20345.92
Model autmobila C3 marke Citroen sa kubikazom 1650 proizveden 2022. godine je cene 19827.38
9.4. Primer rada sa nizovima struktura¶
1#include <stdio.h>
2
3#define MAX_SIZE 20
4#define MAX_MARKA 51
5#define MAX_MODEL 51
6
7typedef struct automobil
8{
9 char marka[MAX_MARKA];
10 char model[MAX_MODEL];
11 int kubikaza;
12 int godiste;
13 float cena;
14} AUTO;
15void unos(AUTO *, int *);
16void ispis(AUTO *, int);
17
18int main()
19{
20
21 AUTO niz[MAX_SIZE];
22 int n;
23 unos(niz, &n);
24
25 ispis(niz, n);
26
27 return 0;
28}
29
30void unos(AUTO *automobili, int *n)
31{
32 do
33 {
34 printf("Unesite broj automobila: ");
35 scanf("%d", n);
36 } while(*n <= 0 || *n > MAX_SIZE);
37
38 for (int i = 0; i < *n; i++)
39 {
40 printf("\nUnesite marku: ");
41 scanf("%s", automobili[i].marka);
42 printf("Unesite model: ");
43 scanf("%s", automobili[i].model);
44 printf("Unesite kubikazu: ");
45 scanf("%d", &automobili[i].kubikaza);
46 printf("Unesite godiste: ");
47 scanf("%d", &automobili[i].godiste);
48 printf("Unesite cenu: ");
49 scanf("%f", &automobili[i].cena);
50 }
51}
52
53
54void ispis(AUTO *automobili, int n)
55{
56 for (int i = 0; i < n; i++)
57 {
58 printf("\nModel autmobila %s marke %s sa kubikazom %d proizveden %d. godine je cene %.2f\n", automobili[i].model, automobili[i].marka, automobili[i].kubikaza, automobili[i].godiste, automobili[i].cena);
59 }
60}
U primeru iznad je definisana struktura struct automobil
kojoj je dodeljen alias AUTO
koji se u daljem radu programa koristi.
Prvo se poziva funkcija unos
kroz koju se unosi broj automobila, a zatim i vrednosti svih polja za svaki automobil. Kada se unesu
svi automobili, poziva se funkcija ispis
koja ispisuje podatke o svakom pojedinačnom automobilu.
Ispis programa:
Unesite broj automobila: 3
Unesite marku: Ford
Unesite model: Fiesta
Unesite kubikazu: 1599
Unesite godiste: 2023
Unesite cenu: 20345.92
Unesite marku: Citroen
Unesite model: C3
Unesite kubikazu: 1650
Unesite godiste: 2022
Unesite cenu: 19827.38
Unesite marku: Renault
Unesite model: Clio
Unesite kubikazu: 1499
Unesite godiste: 2021
Unesite cenu: 15672.38
Model autmobila Fiesta marke Ford sa kubikazom 1599 proizveden 2023. godine je cene 20345.92
Model autmobila C3 marke Citroen sa kubikazom 1650 proizveden 2022. godine je cene 19827.38
Model autmobila Clio marke Renault sa kubikazom 1499 proizveden 2021. godine je cene 15672.38
9.5. Učitavanje podataka u program¶
Podatke smo do sada učitavali u program kroz standardni ulaz (terminal). Podaci se mogu programu proslediti i kroz drugi izvor,
na primer datoteku. Jedan od načina učitavanja podataka iz datoteke u program jeste preusmeravanjem sadržaja datoteke u program.
Kada se sadržaj datoteke preusmeri u program, onda program taj sadržaj tretira kao da je učitan kroz standardni ulaz (terminal).
Sadržaj datoteke se programu preusmerava korišćenjem operatora "preusmeravanja unosa" <
u terminalu. Tada primer poziva programa
izgleda drugačije:
./a.out < ime_datoteke
gde je ime_datoteke
naziv prethodno kreirane datoteke sa podacima koji će se programu proslediti.
9.6. Primer rada niza sa preusmeravanjem unosa¶
Kod je isti kao primer rada sa nizovima struktura iznad, dok su podaci zapisani u ulaznoj datoteci podaci.txt
, čiji je sadržaj:
3
Ford
Fiesta
1599
2023
20345.92
Citroen
C3
1650
2022
19827.38
Renault
Clio
1499
2021
15672.38
Program se poziva sada tako što mu se preusmeri datoteka podaci.txt
umesto da ih ručno kucamo na terminalu:
./a.out < podaci.txt
Ispis programa:
Unesite broj automobila:
Unesite marku: Unesite model: Unesite kubikazu: Unesite godiste: Unesite cenu:
Unesite marku: Unesite model: Unesite kubikazu: Unesite godiste: Unesite cenu:
Unesite marku: Unesite model: Unesite kubikazu: Unesite godiste: Unesite cenu:
Model autmobila Fiesta marke Ford sa kubikazom 1599 proizveden 2023. godine je cene 20345.92
Model autmobila C3 marke Citroen sa kubikazom 1650 proizveden 2022. godine je cene 19827.38
Model autmobila Clio marke Renault sa kubikazom 1499 proizveden 2021. godine je cene 15672.38
Napomena:
Uneti podaci se ne vide i to je u redu, pošto ih program preuzima. Podaci su uspešno preusmereni u program što se vidi po ispisu detalja svakog automobila.