ELEKTROTEHNIČKI FAKULTET UNIVERZITETA U BEOGRADU BEOGRAD, 02.07.2019. Ispit iz Programiranja 2 Ispit traje 135 minuta Napomene: a) Pažljivo proučite Uputstvo pre popunjavanja Obrasca za odgovore. b) Vrednost odgovora: tačan = 5; netačan = -1.25; nevažeći (nula ili više zacrnjenih kružića) = 0. c) Na pitanjima se može osvojiti najviše 20 poena. Prvi zadatak nosi 20 poena, dok drugi nosi 25 poena. I ZADACI 1)Napisati program na programskom jeziku C koji određuje gde će se iznajmiti biciklovi. Raspored bicikala se zadaje kao matrica nenegativnih brojeva, gde svaki broj označava koliko ima biciklova na tom polju matrice. Program prvo učitava sa standardnog ulaza dimenzije matrice i samu matricu. Učitavanje realizovati u funkciji void read_matrix(int ***matrix, int *m, int *n). Nakon toga sa standardnog ulaza se učitava na kom polju se nalazi onaj koji želi da iznajmi biciklove i broj biciklova koji želi da iznajmi. Program treba da pronađe i ispiše najbliže polje u odnosu na trenutnu poziciju onog koji iznajmljuje biciklove, koje sadrži dovoljan broj biciklova. Ako postoji više polja koja zadovoljavaju uslov, ispisati bilo koje, u suprotnom -1. Pretragu i ispis rezultata realizovati kao zasebne funkcije. Razdaljina između dva polja se računa kao broj polja koje je potrebno preći od jednog do drugog, gde je dozvoljeno horizontalno i vertikalno kretanje, ali nije dozvoljeno dijagonalno. Voditi računa o ispravnom korišćenju dinamičke memorije. 2)Napisati program na programskom jeziku C koji određuje prosečnu cenu različitih vrsta pice po gradovima. Jedan red ulazne datoteke cenapice.txt sadrži podatke o ceni pice po sledećem formatu: dvoslovna skraćenica grada (tačno dva slova), cena pice (realan broj) i naziv pice (string od najviše 256 znakova koji može sadržati blanko znake). Svi podaci su razdvojeni jednim blanko znakom. Broj redova u datoteci je nepoznat. Smatrati da broj različitih gradova nije veći od 100. Program treba da pročita podatke iz ulazne datoteke, a zatim na standardnom izlazu ispiše podatke o prosečnim cenama pice po gradovima u sledećem formatu: naziv vrste pice, prosečna cena, nazivi gradova u kojima se prodaje. Svi podaci treba da budu razdvojeni jednim blanko znakom. Voditi računa o ispravnom korišćenju dinamičke memorije. Datoteka cenapice.txt: BG 420.0 Napolitana NS 520.0 Capricciosa NS 480.0 Napolitana BG 560.0 Quattro fromaggio NI 350.0 Diavolo BG 650.0 Diavolo II PITANJA Primer izlaza: Napolitana 450.0 BG NS Capricciosa 520.0 NS Quattro fromaggio 560.0 BG Diavolo 500.0 NI BG 1)Koje od ponuđenih tvrdnji su tačne za programski jezik C; A) Ako su date definicije float *p; int *x; tada je izraz x = p + 10; ispravan. (B) Ako su data definicije double x = 3, *p = &x; int i; tada je izraz i = *(int*)p << 2 ispravan; C) Ako su date definicije char *s = "String", *p, *q; tada p i q imaju istu vrednost nakon izvršavanja izraza p = s + strlen(s); i q = s; while(*q++); 2)Šta ispisuje sledeći program napisan na programskom jeziku C? int f3 ( int a[] ) { typedef int (*FP)(int*); a[0] += a[1] + a[-1]; int f1 ( int *a ) { return 1; ++*a; return 2; int main ( ) { int a[] = { 1, 2, 3, 4, 5, 6, next = 0; int f2 ( int *a ) { int n = sizeof ( a ) / sizeof ( int ); int x = a[0]; FP f[] = { f1, f2, f3 ; a[0] = a[-1]; for ( int i = 0; i < n; i++ ) next = f[next](a+i); a[-1] = x; for ( int i = 0; i < n; i++ ) printf ( "%d ", a[i] ); (A) 2 3 7 5 6 16 B) 2 3 7 5 16 6 C) 2 7 3 5 6 16 3)Šta ispisuje sledeći program napisan na programskom jeziku C? Program je pokrenut sledećom komandom:./program.exe avgust septembar oktobar oktobar2 strcat(s1, argv[2]); *s1 += 'A'-'a' ; #include <string.h> s1[strlen(argv[4])] = '\0'; int main(int argc, char *argv[]) { s2[strlen(s2)-1] += 'A'-'a'; char *s1 = malloc(20 * sizeof(char)); printf("%s %s\n", s1, s2); char *s2 = malloc(20 * sizeof(char)); strcpy(s1, argv[4]); strcpy(s2, argv[1]); (A) Oktobar2 avgust B) Oktobar2septembar avgust C) Oktobar2 avgust 4)Šta ispisuje sledeći program napisan na programskom jeziku C ukoliko se sa standardnog ulaza unosi tekst ispitp2? Smatrati da je podatak tipa short smešten na širini od 16 bitova, a da program pri izvršavanju niži bajt smešta na nižu adresu, a viši bajt na višu adresu, kao i da je ASCII kod slova A jednak 65, a slova a 97. #include <ctype.h> #define MAX 20 typedef union { struct { unsigned char a, b; s; short i; U; int main(void) { U arr[max]; int c = 0; while(c < MAX &&!isdigit(arr[c].s.a = getchar())) { if(islower(arr[c].s.a)) arr[c].i = (arr[c].i & ~('a' - 'A')) << 8; else arr[c].i = (arr[c].i ('a' - 'A')) << 8; c++; for(int i=0; i<c; i++) putchar(arr[i].s.b); (A) ISPITp B) ispitp C) ispitp 5)Šta ispisuje sledeći program na programskom jeziku C ukoliko su uneseni brojevi 1 1 1 3 4 4 5 2 1 3-1? Smatrati da funkcija release_memory ispravno vrši brisanje liste iz memorije. void release_memory(elem *head); void main() { typedef struct elem { int num,cnt; struct elem *next; elem *h = 0; elem; int num; void add(elem **head_ptr, int num){ while(1){ elem *curr = *head_ptr, *prev = 0; scanf("%d", &num); for(; curr!= 0 && curr->num < num; prev = curr, if(num <= 0) break; curr = curr->next); add(&h, num); if(curr && curr->num == num) curr->cnt++; else { elem *new_elem = malloc(sizeof(elem)); while(h){ new_elem->num = num; new_elem->cnt = 1; printf("%d%d",h->num,h->cnt); new_elem->next = curr; h = h->next; if(prev) prev->next = new_elem; else *head_ptr = new_elem; release_memory(h); (A) 1421324251 B) 5142322114 C) 515217314
13E111P2, Programiranje 2, jul 2018/2019. Rešenje zadataka i ključ za bodovanje Zadatak 1. Napisati program na programskom jeziku C koji određuje gde će se iznajmiti bicikli. Raspored bicikala se zadaje kao matrica nenegativnih brojeva, gde svaki broj označava koliko ima bicikala na tom polju matrice. Program prvo učitava sa standardnog ulaza dimenzije matrice i samu matricu. Učitavanje realizovati u funkciji void read_matrix(int ***matrix, int *m, int *n). Nakon toga sa standardnog ulaza se učitava na kom polju se nalazi onaj koji želi da iznajmi bicikle i broj bicikala koji želi da iznajmi. Program treba da pronađe i ispiše najbliže polje u odnosu na trenutnu poziciju onog koji iznajmljuje bicike, koje sadrži dovoljan broj bicikala. Ako postoji više polja koja zadovoljavaju uslov, ispisati bilo koje, u suprotnom -1. Pretragu i ispis rezultata realizovati kao zasebne funkcije. Razdaljina između dva polja se računa kao broj polja koje je potrebno preći od jednog do drugog, gde je dozvoljeno horizontalno i vertikalno kretanje, ali nije dozvoljeno dijagonalno. Voditi računa o ispravnom korišćenju dinamičke memorije. struct position { int x, y; ; void read_matrix(int ***matrix, int *pm, int *pn) { scanf("%d%d", pm, pn); int m = *pm, n = *pn; int **mat = malloc(m * sizeof(int*)); mat[i] = malloc(n * sizeof(int)); for (int j = 0; j < n; j++) { scanf("%d", &mat[i][j]); *matrix = mat; int distance(int i, int j, struct position pos) { return abs(pos.x - i) + abs(pos.y - j); struct position find_nearest(int **mat, int m, int n, struct position pos, int number) { struct position ret = {-1, -1; for (int j = 0; j < n; j++) { if (number > mat[i][j] (pos.x == i && pos.y == j)) { continue; if (ret.x == -1 distance(i, j, pos) < distance(ret.x, ret.y, pos)) { ret.x = i; ret.y = j; return ret; void print(struct position pos) { printf("%d %d\n", pos.x, pos.y);
void deallocate(int **matrix, int m) { free(matrix[i]); free(matrix); int main() { int m, n, **matrix; read_matrix(&matrix, &m, &n); struct position pos; int bikes; scanf("%d%d%d", &pos.x, &pos.y, &bikes); struct position res = find_nearest(matrix, m, n, pos, bikes); print(res); deallocate(matrix, m);
Zadatak 2. Napisati program na programskom jeziku C koji određuje prosečnu cenu različitih vrsta pice po gradovima. Jedan red ulazne datoteke cenapice.txt sadrži podatke o ceni pice po sledećem formatu: dvoslovna skraćenica grada, cena pice (realan broj) i naziv pice (string od najviše 256 znakova koji može sadržati blanko znake). Svi podaci su razdvojeni jednim blanko znakom. Broj redova u datoteci je nepoznat. Smatrati da broj različitih gradova nije veći od 100, a da je cena jedne vrste pice za jedan grad jedinstvena. Program treba da pročita podatke iz ulazne datoteke, a zatim na standardnom izlazu ispiše podatke o prosečnim cenama pice po gradovima u sledećem formatu: naziv vrste pice, prosečna cena, nazivi gradova u kojima se prodaje. Svi podaci treba da budu razdvojeni jednim blanko znakom. Voditi računa o ispravnom korišćenju dinamičke memorije. Datoteka cenapice.txt: BG 420.0 Napolitana NS 520.0 Capricciosa NS 480.0 Napolitana BG 560.0 Quattro fromaggio NI 350.0 Diavolo BG 650.0 Diavolo #include <string.h> #define PIZZA_NAME_LEN 256 #define PLACE_NAME_LEN 2 #define PLACES_MAX 10 #define MALLOCATE(ptr, type){\ ptr = (type*)malloc(sizeof(type));\ if(ptr == 0) {\ perror(0);\ exit(1);\ \ typedef struct pizza_info { float price; char name[pizza_name_len + 1]; char place[places_max][place_name_len + 1]; int places_cnt; struct pizza_info *next; pizza_info; pizza_info* read_data(const char*); void print_data(pizza_info*); void release_memory(pizza_info*); int main(int argc, char **argv) { pizza_info *head = read_data("cenapice.txt"); print_data(head); release_memory(head); system("pause"); Primer izlaza: Napolitana 450.0 BG NS Capricciosa 520.0 NS Quattro fromaggio 560.0 BG Diavolo 500.0 NI BG pizza_info* read_data(const char* filename) { pizza_info *head = 0, *tail = 0, *new_pizza = 0, *curr; FILE* fp = fopen(filename, "r"); if (fp == 0) { perror("file error: "); while (1) { MALLOCATE(new_pizza, pizza_info); if (fscanf(fp, "%s %f %[^\n]", new_pizza->place[0], &new_pizza->price, new_pizza- >name)!= 3) { free(new_pizza); break;
new_pizza->places_cnt = 1; new_pizza->next = 0; // check if this is new or existing pizza for (curr = head; curr!= 0; curr = curr->next) if (strcmp(curr->name, new_pizza->name) == 0) break; // add new pizza if (curr == 0) { if (tail) tail->next = new_pizza; else head = new_pizza; tail = new_pizza; // add existing pizza else { strcpy(curr->place[curr->places_cnt], new_pizza->place[0]); curr->places_cnt++; curr->price += new_pizza->price; free(new_pizza); fclose(fp); return head; void print_data(pizza_info* head) { for (pizza_info *curr = head; curr; curr = curr->next) { printf("%s %.1f ", curr->name, curr->price / curr->places_cnt); for (int i = 0; i < curr->places_cnt; i++) printf("%s ", curr->place[i]); putchar('\n'); void release_memory(pizza_info* head) { pizza_info *old; while (head) { old = head; head = head->next; free(old);