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}

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:

  1. korišćenjem kombinacije * i . operatora

  2. korišć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.