File: Stare vježbe/vjezbe11/69b__studenti.c

  1. /*
  2.   69b__studenti.c
  3.   Dinamicka alokacija polja struktura. Dinamicka alokacija elemenata
  4.   strukture.
  5.   -----
  6.   Program radi isto sto i 69a__studenti.c pazeci da alocira tocno onoliko
  7.   memorije koliko treba.
  8.   Prilikom kopiranja strukture (polje[broj_studenata]=polje[0]) javlja se
  9.   nepredvidjena(?) nuspojava -- za ispravak vidi 69c__studenti.c
  10.  
  11.   (kod unosa neka se 1. student ne zove Mirko i neka nema 5 iz C-a)
  12. */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <malloc.h>
  17. #include <string.h>
  18.  
  19. struct __student {
  20. char *ime, *prezime, jmbag[11];
  21. int ocjena_iz_c_a;
  22. };
  23.  
  24. typedef struct __student student;
  25.  
  26. double prosjek (student polje[], int broj_studenata)
  27. {
  28. double rez=0;
  29. int i;
  30.  
  31. for (i=0; i<broj_studenata; i++)
  32. rez+=polje[i].ocjena_iz_c_a;
  33.  
  34. return rez/broj_studenata;
  35. }
  36.  
  37. void preimenuj (student *stud, char *novo_ime, int nova_ocjena)
  38. {
  39. stud->ocjena_iz_c_a=nova_ocjena;
  40. strcpy (stud->ime, novo_ime);
  41. }
  42.  
  43. int main ( void )
  44. {
  45. student *polje;
  46. int broj_studenata, i;
  47.  
  48. /* ispisimo koliko sad memorije zauzima struktura */
  49. printf ("[sizeof(student)=%d]\n\n", sizeof(student));
  50.  
  51. printf ("Koliko ce biti studenata: ");
  52. scanf ("%d", &broj_studenata);
  53.  
  54. /* alociramo memoriju za podatke -- uzet cemo mjesta za 1 studenta vise */
  55. if ((polje=(student *) malloc ((broj_studenata+1)*sizeof(student)))==NULL)
  56. {
  57. printf ("Greska u alokaciji memorije.\n");
  58. exit(1);
  59. }
  60.  
  61. /* inicijaliziramo polje (tj. elemente strukture koji su pokazivaci) */
  62. for (i=0; i<broj_studenata+1; i++)
  63. polje[i].ime=polje[i].prezime=NULL;
  64.  
  65. /* ucitavamo redom podatke o studentima */
  66. for (i=0; i<broj_studenata; i++)
  67. {
  68. char s[100];
  69.  
  70. printf ("--- %d. student ---\n", i+1);
  71. printf ("Ime: ");
  72. scanf ("%s", s);
  73. /* alociramo tocno onoliko memorije koliko treba da se spremi ime */
  74. /* (uocimo strlen(s)+1 zbog dodatnog znaka '\0') */
  75. if ((polje[i].ime=(char *) malloc ((strlen(s)+1)*sizeof(char)))==NULL)
  76. {
  77. printf ("Greska prilikom alokacije memorije.\n");
  78. exit(1);
  79. }
  80. strcpy (polje[i].ime, s);
  81.  
  82. printf ("Prezime: ");
  83. scanf ("%s", s);
  84. if ((polje[i].prezime=(char *) malloc ((strlen(s)+1)*sizeof(char)))
  85. ==NULL)
  86. {
  87. printf ("Greska prilikom alokacije memorije.\n");
  88. exit(1);
  89. }
  90. strcpy (polje[i].prezime, s);
  91.  
  92. printf ("JMBAG: ");
  93. scanf ("%s", &polje[i].jmbag); /* jmbag ima 10 znakova */
  94.  
  95. printf ("Ocjena iz C-a: ");
  96. scanf ("%d", &polje[i].ocjena_iz_c_a);
  97. }
  98.  
  99. /* kloniramo prvog studenta i promjenimo mu ime u Mirko i ocjenu u 5
  100.   ova operacija ce iskopirati bit po bit sve iz polje[0] u
  101.   polje[broj_studenata] -- pa tako i __adrese__ u memoriji gdje su
  102.   spremljeni ime i prezime */
  103. polje[broj_studenata]=polje[0];
  104. preimenuj (&polje[broj_studenata], "Mirko", 5);
  105.  
  106. /* preimenovanje uzrokuje promjenu imena i zadnjeg i prvog studenta!!!
  107.   To je zato sto se ime "Mirko" zapisuje na adresu koja pise u
  108.   polje[broj_studenata].ime, a ona je nakon kopiranja ista kao
  109.   polje[0].ime gdje pise ime prvog studenta */
  110.  
  111. /* ispisemo podatke o svim studentima */
  112. printf ("\n\n");
  113. for (i=0; i<=broj_studenata; i++)
  114. printf ("%d. %s %s: JMBAG=%s, ocjena iz c-a=%d\n",
  115. i+1, polje[i].ime, polje[i].prezime,
  116. polje[i].jmbag, polje[i].ocjena_iz_c_a);
  117.  
  118. /* izracunamo prosjek ocjena iz C-a */
  119. printf ("Prosjek ocjena iz C-a: %f\n", prosjek(polje, broj_studenata+1));
  120.  
  121. /* oslobadjamo memoriju: prvo za sve stringove */
  122. for (i=0; i<=broj_studenata; i++)
  123. free(polje[i].ime), free(polje[i].prezime);
  124.  
  125. /* pa onda i za samo polje */
  126. free (polje);
  127.  
  128. return 0;
  129. }
  130.