O strukturama, funkcijama i nizovima
Strukture
Ranije smo videli da je niz koncept koji nam omogućava da napravimo kolekciju podataka istog tipa. Strukture u C-u nam omogućavaju da napravimo nove tipove podataka koji predstavljaju kolekciju podataka različitog tipa. Sintaksa kojom se kreira struktura je
struct [oznaka_strukture]{
definicija jednog člana strukture;
definicija jednog člana strukture;
...
} ;
Imamo rezervisanu reč struct iza koje se može (a ne mora, uglaste zagrade predstavljaju oznaku da neki deo deklaracije može, ali ne mora da se navede) navesti oznaka strukure, odnosno naziv tipa podataka koji označava struktura. Zatim se u vitičastim zagradama navodi niz definicija elemenata strukture, koja se sastoji od tipa i naziva.
Primer jedne definicije strukture:
struct Ucenik{
char ime[50];
char prezime[50];
int razred;
};
Ovde je definisana struktura Ucenik koji sadrži tri podatka: ime, prezime i broj poena. Prva dva podatka su stringovi, a treći je broj.
Strukture se najčešće definišu na početku, pre funckije main, i koriste se u funkciji main i u drugim funkcijama. Svaka struktura je poseban tip podataka i mogu se deklarisati promenljive tipa strukture (strukturne promenljive) i u okviru tih promenljivih može se pristupati pojedinačnim elementima strukture, mogu im se dodeljivati, čitati i menjati vrednosti i mogu se koristiti u izrazima.
Na primer: struct Ucenik u1 = {"Pera", "Peric", 3}; - deklariše novu promenljivu tipa strukture Ucenik i dodeljuje vrednosti redom za svaki element strukture.
Pojedinačnim elementima strukture pristupa se korišćenjem tačke, na sledeći način:
nazivPromenljive.nazivElementa
Na primer:
u1.razred = 5;
gets(s1.ime);
printf("%s %s %d", s1.ime, s1.prezime, s1.brojPoena);
Definicija tipa - typedef
Strukture se često koriste zajedno sa oznakom za definiciju tipa typedef. Reč typedef se koristi u C-u za definisanje novih tipova na osnovu postojećih i preimenovanje tipa, na primer:
typedef int ceo_broj;
uvodi novo ime ceo_broj za tip podataka int. Posle ovakve definicije možemo da deklarišemo promenljivu na sledeći način:
ceo_broj br;
Ako se koristi sa strukturom, reč typedef uvodi novi tip podataka strukture. Sledećom naredbom uvodi se novi tip podataka Ucenik:
typedef struct{
char ime[50];
char prezime[50];
int brojPoena;
}Ucenik;
Posle ovoga deklaracija promenljivih tipa Ucenik se navodi bez reči struct, primer:
Ucenik u1,u2;
Struktura u strukturi
Elementi strukture mogu biti nove strukture, na primer ako hoćemo da učeniku dodamo adresu koja će imati poseban podatak o ulici, broju i mestu, to bismo uradili na sledeći način:
struct Adresa{
char ulica[200];
char broj[10];
char mesto[100];
};
struct Ucenik{
char ime[50];
char prezime[50];
int brojPoena;
struct Adresa adr1;
};
Jedan od elemenata strukture Ucenik je nova struktura adr1. Pristup elementima adrese (unutrašnje strukture) implementira se sa s1.adr1.broj.
Strukture i funkcije
Strukture se mogu prosleđivati kao argumenti funkcije i mogu biti povratne vrednosti funkcija. Na sledećem listingu prikazan je primer programa u kome imamo definisan tip strukture pod imenom Ucenik i dve funkcije. Funkcija ispis kao parametar prima tip Ucenik i ispisuje vrednosti svih elemenata strukture. Funkcija kreiraj vraća povratnu vrednost tipa Ucenik, a kao argumente uzima pojedinačne vrednosti elemenata strukture.
#include<stdio.h> #include <string.h> typedef struct{ char ime[50]; char prezime[50]; int razred; }Ucenik; void ispis(Ucenik s); Ucenik kreiraj(char ime[], char prezime[], int razred); int main(void) { Ucenik s1, s2; strcpy(s1.ime, "Petar"); strcpy(s1.prezime, "Peric"); s1.razred = 3; printf("Ucenik 1:\n"); ispis(s1); s2 = kreiraj("Bojan","Milosevic",4); printf("Ucenik 2:\n"); ispis(s2); return 0; } void ispis(Ucenik s){ printf("Ime ucenika: %s\n",s.ime); printf("Prezime ucenika: %s\n", s.prezime); printf("Razred %d\n", s.razred); } Ucenik kreiraj(char ime[50], char prezime[50], int razred){ Ucenik s; strcpy(s.ime, ime); strcpy(s.prezime, prezime); s.razred = razred; return s; }
Strukture i pokazivači
Mogu se definisati pokazivači na strukture, na isti način kao pokazivači na bilo koji drugi tip promenljive. Na primer, sledećom naredbom definisana je promenljiva ucenik_pok koja predstavlja pokazivač na podatak koji je tipa strukture Ucenik:
Ucenik *ucenik_pok;
Pokazivaču na strukturu može se dodeliti vrednost adrese neke promenljive koja je tipa Ucenik:
Ucenik s1; ucenik_pok = &s1;
Elementima strukture se može prisupiti preko pokazivača korišćenjem operatora -> na sledeći način:
ucenik_pok->ime
Drugi način za pristup elementu strukture preko pokazivača je (*ucenik_pok).ime, ali ovaj način se mnogo ređe koristi.
Na sledećem listingu prikazan je primer programa koji koristi pokazivač na tip strukture Student.
#include<stdio.h> #include <string.h> typedef struct { char ime[50]; char prezime[50]; int razred; }Ucenik; int main(void) { Ucenik *ucenik_pok; Ucenik s1; strcpy(s1.ime, "Petar"); strcpy(s1.prezime, "Peric"); s1.razred = 3; ucenik_pok = &s1; printf("%s %s %d", ucenik_pok->ime, ucenik_pok->prezime, ucenik_pok->razred); return 0; }
Elementi strukture mogu biti pokazivači, na primer istu strukturu Ucenik možemo deklarisati na sledeći način:
typedef struct {
char *ime;
char *prezime;
int razred;
} Ucenik;
Strukture i nizovi
Mogu se definisati nizovi čiji su elementi tipa strukture, na primer:
Ucenik odeljenje[10];
Dodela vrednosti prvom elementu niza vrši se na sledeći način:
strcpy(odeljenje[0].ime, "Petar"); strcpy(odeljenje[0].prezime, "Petrovic"); odeljenje[0].razred = 3;
Elementima niza možemo dodeliti vrednosti i korišćenjem pokazivača na sledeći način, navedeni primer dodeljuje vrednost drugom elementu niza studenti:
strcpy((odeljenje+1)->ime, "Milica"); strcpy((odeljenje+1)->prezime, "Pavlovic"); (odeljenje+1)->razred = 5;