/*
69b__studenti.c
Dinamicka alokacija polja struktura. Dinamicka alokacija elemenata
strukture.
-----
Program radi isto sto i 69a__studenti.c pazeci da alocira tocno onoliko
memorije koliko treba.
Prilikom kopiranja strukture (polje[broj_studenata]=polje[0]) javlja se
nepredvidjena(?) nuspojava -- za ispravak vidi 69c__studenti.c
(kod unosa neka se 1. student ne zove Mirko i neka nema 5 iz C-a)
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct __student {
char *ime, *prezime, jmbag[11];
int ocjena_iz_c_a;
};
typedef struct __student student;
double prosjek (student polje[], int broj_studenata)
{
double rez=0;
int i;
for (i=0; i<broj_studenata; i++)
rez+=polje[i].ocjena_iz_c_a;
return rez/broj_studenata;
}
void preimenuj (student *stud, char *novo_ime, int nova_ocjena)
{
stud->ocjena_iz_c_a=nova_ocjena;
strcpy (stud->ime, novo_ime);
}
int main ( void )
{
student *polje;
int broj_studenata, i;
/* ispisimo koliko sad memorije zauzima struktura */
printf ("[sizeof(student)=%d]\n\n",
sizeof(student
));
printf ("Koliko ce biti studenata: ");
scanf ("%d", &broj_studenata);
/* alociramo memoriju za podatke -- uzet cemo mjesta za 1 studenta vise */
if ((polje=(student *) malloc ((broj_studenata+1)*sizeof(student)))==NULL)
{
printf ("Greska u alokaciji memorije.\n");
exit(1);
}
/* inicijaliziramo polje (tj. elemente strukture koji su pokazivaci) */
for (i=0; i<broj_studenata+1; i++)
polje[i].ime=polje[i].prezime=NULL;
/* ucitavamo redom podatke o studentima */
for (i=0; i<broj_studenata; i++)
{
char s[100];
printf ("--- %d. student ---\n", i
+1);
scanf ("%s", s);
/* alociramo tocno onoliko memorije koliko treba da se spremi ime */
/* (uocimo strlen(s)+1 zbog dodatnog znaka '\0') */
if ((polje[i].ime=(char *) malloc ((strlen(s)+1)*sizeof(char)))==NULL)
{
printf ("Greska prilikom alokacije memorije.\n");
exit(1);
}
strcpy (polje[i].ime, s);
scanf ("%s", s);
if ((polje[i].prezime=(char *) malloc ((strlen(s)+1)*sizeof(char)))
==NULL)
{
printf ("Greska prilikom alokacije memorije.\n");
exit(1);
}
strcpy (polje[i].prezime, s);
scanf ("%s", &polje[i].jmbag); /* jmbag ima 10 znakova */
scanf ("%d", &polje[i].ocjena_iz_c_a);
}
/* kloniramo prvog studenta i promjenimo mu ime u Mirko i ocjenu u 5
ova operacija ce iskopirati bit po bit sve iz polje[0] u
polje[broj_studenata] -- pa tako i __adrese__ u memoriji gdje su
spremljeni ime i prezime */
polje[broj_studenata]=polje[0];
preimenuj (&polje[broj_studenata], "Mirko", 5);
/* preimenovanje uzrokuje promjenu imena i zadnjeg i prvog studenta!!!
To je zato sto se ime "Mirko" zapisuje na adresu koja pise u
polje[broj_studenata].ime, a ona je nakon kopiranja ista kao
polje[0].ime gdje pise ime prvog studenta */
/* ispisemo podatke o svim studentima */
for (i=0; i<=broj_studenata; i++)
printf ("%d. %s %s: JMBAG=%s, ocjena iz c-a=%d\n",
i+1, polje[i].ime, polje[i].prezime,
polje[i].jmbag, polje[i].ocjena_iz_c_a);
/* izracunamo prosjek ocjena iz C-a */
printf ("Prosjek ocjena iz C-a: %f\n", prosjek
(polje, broj_studenata
+1));
/* oslobadjamo memoriju: prvo za sve stringove */
for (i=0; i<=broj_studenata; i++)
free(polje[i].ime), free(polje[i].prezime);
/* pa onda i za samo polje */
free (polje);
return 0;
}