You are on page 1of 25

PROGRAMIRANJE I – USMENI ISPIT

ELEKTROTEHNIČKI FAKULTET BANJALUKA


TEORIJSKI DIJELOVI ISPITA – PROGRAMIRANJE I (GODINA 2017)

Rok 10.02.2017
1. Što je alfabet brojnog sistema?
Brojevni sustav jest sustav s kojim se predstavljaju brojevi. Najpoznatiji je decimalni(10),
hex(16), bin(2), okt(8).
2. Neka je dat razlomljeni broj S u brojevnom sistemu sa bazom b. Navesti formulu za
izračunavanje dekadskog ekvivalenta broja Sb.
𝑆𝑛 𝑏𝑛 + 𝑆𝑛−1 𝑏𝑛−1 + ⋯ + 𝑆0 𝑏0 + 𝑆−1 𝑏−1 + ⋯ + 𝑆−𝑘 𝑏−𝑘 = 𝑆𝑏𝑖𝑛𝑎𝑟𝑦
3. Šta ispisuje sljedeći kôd?
printf("%o",-1>>1);
Ispis: 37777777777
Int je vrijednosti 4 byte-a, broj -1 kad se šiftuje u desno, pošto je negativan, neće promijeniti
njegovu vrijednost. 1 byte ima 8 bita, 4*8=32, dakle -1 u ovom slučaju ima 32 jedinice.
Konverzijom u oktalni (uzimanjem po tri bita od desna), konvertira se u oktalni i dobije se
ispis.
4. Šta ispisuje sljedeći kôd (koristi se LE konvencija)?
union _u {float f; int i;} u={8};
printf("%d", (u.i>>23)-127);
Ispis: 3
Unija: Posebna vrsta podatka u C-u koja omogućava skladištenje više različitih varijabli na istu
memorijsku lokaciju. Može se definirati unija sa više različitih članova, međutim samo jedan od tih
članova može imati vrijednost u datom trenutku.
Primjer:
union Data {
int i;
float f;
char str[20];
} data;

Sada, varijabla Data može pohraniti jedan cijeli broj, razl. podatak float ili niz charova.
Memorija koju unija zauzme bit će dovoljno velika da pohrani najveći element koji se nalazi u istoj. U
ovom slučaju Data tip zauzet će 20 byte-a, zato što je to najveći prostor koji može da bude zauzeto
od karakter stringa. Pri pristupu podacima iz unije, koristi se točka.
Primjer ispisa kodova:

union Data data;

data.i = 10;
data.f = 220.5;
strcpy( data.str, "C Programming");

printf( "data.i : %d\n", data.i);


printf( "data.f : %f\n", data.f);
printf( "data.str : %s\n", data.str);
PROGRAMIRANJE I – USMENI ISPIT

Ispis ovog koda je sljedeći:

data.i : 1917853763
data.f : 4122360580327794860452759994368.000000
data.str : C Programming
Vrijednosti i i f su se pokvarile iz razloga što posljednja vrijednost koja je dodjeljena varijabli je
okupirala memorijsku lokaciju i iz tog razloga ispis str-a je ispravan.
Sljedeći primjer:

union Data data;

data.i = 10;
printf( "data.i : %d\n", data.i);

data.f = 220.5;
printf( "data.f : %f\n", data.f);

strcpy( data.str, "C Programming");


printf( "data.str : %s\n", data.str);

Ispis ovog koda je sljedeći:


data.i : 10
data.f : 220.500000
data.str : C Programming

Ovdje je ispis uredan zato što je svaki član korišten na vrijeme.


U prethodnom zadatku ispis je 3 iz razloga što je uniji dodijeljena vrijednost 8, a ta vrijednost se
pohranila u varijablu float f. Kako u uniji podaci dijele memoriju i vrijednost, u varijablu tipa int će se
također pohraniti jednaka vrijendost kao i u float, međutim ta vrijednost će biti garbage value kad se
pretvori u int. Stoga vrijednost 8 koja je dodijeljena uniji bit će zapravo podatak u IEEE obliku.
Postupak je slijedeći:
8DEC = 1000BIN
S=0
E=1,000 * 2^3 =>127+3=130
1302 =10000010 10
IEEE će biti 0100 0001 0000 0000 0000 0000 0000 0000
Kad se šiftuje za 23 mjesta u desno bit će 0100 0001 = 130
130 - 127 = 3

5. Šta ispisuje sljedeći kôd?


int a=100, b=10; a+++b;
printf("%d %d", a, b);
Ispis: 101 10
Samo varijabla a se inkrementira, operacija a+++b u ovom slučaju nema nikakvog efekta, osim ako
nije dodijeljena nekoj varijabli, kao npr. da je bilo
int a=100, b=10, c;
c=a+++b;
printf(“%d %d %d”, a, b ,c);
Ispis: 101 10 110
PROGRAMIRANJE I – USMENI ISPIT

6. Definisati enumeraciju RIM koja reprezentuje sljedeće rimske brojeve: I,V,X,L,C,D,M.


Elementi u enumeraciji treba da imaju odgovarajuće cjelobrojne vrijednosti (1, 5, ...).

Enumeracija se koristi za definiranje konstantnih vrijednosti imenom. Enumeriran tip se


predstavlja korištenjem riječi enum.
enum ime {
enumeration list }

Ime- predstavlja ime enumeracija


Enumeration list- predstavlja identifikatore odvojene zarezom
enum Days { ponedjeljak, utorak, srijeda, cetvrtak, petak, subota, nedjjelja };
Dodijela vrijednosti kod varijabli:
enum suit {
club = 0,
diamonds = 10,
hearts = 20,
spades = 3
} card;

Enum varijable uvijek ima jednu vrijednost, od svih koje su moguće. Dokaz:
card = club;
printf("Size of enum variable = %d bytes", sizeof(card));

Izlaz:

Size of enum variable = 4 bytes

U slučaju da NISU navedene vrijednosti članova, svaka je za 1 VEĆA od prethodnog,


vrijednost početnog člana je 0, mada im vrijednosti mogu biti negativne. Također, mogu
imati i iste vrijednosti.
Prema ovom, riješenje zadatka je sljedeće:
Enum RIM{
I = 1; V=5; X=10; L=50; C=100; D=500; M=1000;}rim;

7. Šta ispisuje sljedeći kôd?


double niz[5], *p=&niz[3];
printf("%d", niz-p);

Ispis: -3
U varijabli *p nalazi se memorijska adresa trećeg člana datog niza. Budući da niz označava
početnu adresu tog niza, onda slijedi: POČETNA ADRESA NIZA (niz) minus ADRESA
TREĆEG ELEMENTA jednako je minus 3.

8. Napisati funkciju koja u dinamičkoj zoni memorije alocira segment veličine 1


kibibajt. Prototip funkcije je:
void *alokacija();
PROGRAMIRANJE I – USMENI ISPIT

Jedan kibibyte jeste podatak veličine 1024 byte-a.


Shodno tome slijedi 1 Mebibyte = 1024 KiB. Sljedeće veće jedinice su Gibibyte, Tebibyte…
Jedan Kilobyte ima 1000byte-a, 1MB = 1000KB i tako dalje.
void *alokacija()
{ return calloc(1024, sizeof(char));}

9. U kojem memorijskom segmentu se nalazi "Hello world" prilikom navedenog


poziva? printf("Hello world");
Elementi funkcije printf imaju statički životni vijek, dakle nalaze se u Data Segmentu.

10. Šta ispisuje sljedeći kôd?


struct X {short s; char c;} x;
printf("%d", sizeof(x));
Ispis: 4
Razlog ovoga je slijedeći:

Short i char respektivno(onako kako mi mislimo da će biti smješteno u memoriji)

1b 1b

1b

Međutim, procesor na sljedeći način smješta podatke u memoriju kod struktura

1b 1b

1b Dodatni 1b
Pod pretpostavkom da je sizeof(&int)=4 potrebno je dodati padding byte, pošto
procesor na taj način smješta podatke kod struktura.

1. Šta ispisuje sljedeći kôd?


printf("%d", -1<1u ? -1+1u : -1-1u);

Ternarni operatori “?” i “:”


Rezultat = (slucaj) ? ispunjeno : neispunjeno;
Imaju isto značenje kao i sljedeći kod
if(slucaj)
{ rezultat = ispunjeno;
}
PROGRAMIRANJE I – USMENI ISPIT

else
rezultat = neispunjeno;

Ispis koda iz zadatka: -2


Prilikom poređenja, oba broja se kastuju u unsigned.
-1 kad se kastuje u unsigned dobije se inf vrijednost, odnosno nevažeća vrijednost.
Kako ta inf vrijednost nije manja od 1, ispis je -2. Pozitivni brojevi prilikom kastovanja u
unsigned ostat će isti, međutim negativni će prijeći u neki veći pozitivan broj. Razlog tome
jeste to što se prilikom poređenja dva tipa niži tip uvijek kastuje u širi, a ukoliko se porede
označeni i neoznačeni podaci, označeni se uvijek kastuju u neoznačene.

12. Koliko ima varijabli sa dinamičkim životnim vijekom u sljedećem programu? int
x,*p;
int main() { extern int x,*p; } //0 varijabli
Životni vijek varijable je dio vremena izvršavanja programa u kojem se garantira da je za tu
varijablu rezerviran dio memorije i da se ta varijabla može koristiti. Postojanje varijabli koje
postoje samo pojedinačno tijekom izvršavanja neke funkcije znatno štedi memoriju, a
postojanje varijabli tijekom čitavog izvršavanja programa omogućava da se preko njih vrši
komunikacija između različitih funkcija. U C-u, postoje sljedeće vrste životnog vijeka:
● Statički (static) životni vijek koji znači da objekt dostupan tijekom cijelog izvršavanja
programa
● Automatski (automatic) najčešće imaju varijable koje se automatski stvaraju i
uklanjaju prilikom pozivanja funkcija
● Dinamički (dynamic) imaju varijable koje se alociraju i dealociraju na eksplicitan
zahtjev programera
Životni vijek se određuje na osnovu pozicije u kodu na kojoj je objekt uveden i na osnovu
eksplicitnog korištenja nekog od kvalifikatora auto (automatski životni vijek) ili static
(statički životni vijek).
Lokalne varijable podrazumijevano su automatskog životnog vijeka (osim ako je na njih
primjenjen kvalifikator static ili kvalifikator extern). Početna vrijednost lokalnih
automatskih varijabli nije određena.
Na lokalne automatske varijable i parametre funkcija moguće je primjeniti i kvalifikator
register.
Globalne varijable deklarirane su van svih funkcija i njihov doseg je razine (nivoa) datoteke,
tj. mogu se koristiti od točke uvođenja, u svim funkcijama datoteke.
Životni vijek ovih varijabli je UVIJEK statički, tj. prostor za ove varijable rezerviran je od
samog početka izvršavanja, sve do kraja. Prostor za ove varijable osigurava se u DATA
SEGMENT-u. Podrazumijevano se inicijaliziraju na vrijednost 0, ukoliko se ne izvrši
eksplicitna inicijalizacija.
U nekim slučajevima poželjno je čuvati informaciju između različitih poziva funkcije (npr
brojati koliko puta je pozvana neka funkcija). Jedno rješenje bilo ni uvođenje globalne
varijable, statičkog životnog vijeka, međutim, zbog globalnog dosega tu varijablu bilo bi
moguće koristiti i promijeniti iz drugih funkcija, što je nepoželjno.
PROGRAMIRANJE I – USMENI ISPIT

Zato je poželjna mogućnost definiranja varijabli koje bi bile statičkog životnog vijeka (da bi
čuvale vrijednost tijekom cijelog izvršavanja programa), ali i lokalnog dosega (da bi se mogle
koristiti i mijenjati samo u jednoj funkciji). U deklaraciji lokalne varijable može se primjeniti i
kvalifikator static i u tom slučaju ona ima statički životni vijek - kreira se na početku
izvršavanja programa, i oslobađa se prilikom završetka rada programa. Tako modificirana
varijabla NE čuva se u stack okviru svoje funkcije, već u Data Segmentu.
Ukoliko se vrijednost statičke lokalne varijable promijeni tijekom izvršavanja funkcije, ta
vrijednost ostaje sačuvana i za sljedeći poziv iste. Ukoliko inicijalna vrijednost statičke
varijable nije navedena, podrazumijevana je 0.
Statičke varijable se inicijaliziraju samo jednom, konstantnim izrazom, na početku izvršavanja
programa tj. prilikom njegovog učitavanja u memoriju. Doseg ovih varijabli i dalje je razine
bloka, tj. varijable su i dalje lokalne, što daje željene osobine.
Example:
void f() {
int a=0; printf(“f: %d “, a); a++;}
void g() {
static int a=0; printf(“g: %d “, a); a++;}
int main() {
f(); f(); g(); g(); }
Ispis: f: 0 f: 0 g: 0 g: 0

Povezanost identifikatora: u vezi je sa dijeljenjem podataka između različitih jedinica


prevođenja i daje mogućnost korištenja zajedničkih varijabli i funkcija u različitim jedinicama
prevođenja(modulima), ali i mogućnost sakrivanja nekih varijabli tako da im se ne može
pristupiti iz drugih jedinica prevođenja.
Jezik C razlikuje sljedeće identifikatore:
● Bez povezanosti (no linkage)
● Identifikatore sa vanjskom povezanošću (external linkage)
● Identifikatore sa unutrašnjom povezanošću (internal linkage)
Bez povezanosti su najčešće lokalne varijable (bez obzira da li su automatskog ili statičkog
životnog vijeka), parametri funkcija, korisnički definirani tipovi, labele…
Int f{ int g1(int i) { struct i{int a;}
int i; static int j;}
….} int g2() { static int i,j;..}
Vanjska povezanost identifikatora omogućava da se isti objekt koristi u više jedinica
prevođenja.
Sve deklaracije identifikatora sa vanjskom povezanošću u sklupu jedinica prevođenja
određuju jedan isti objekt (tj. sve pojave ovakvog identifikatora u različitim jedinicama
prevođenja odnose se na jedan isti objekt), dok u cijelom programu mora da postoji točno
jedna definicija tog objekta.
Tako se jedan identifikator koristi za isti objekt u okviru više jedinica prevođenja.
PROGRAMIRANJE I – USMENI ISPIT

Kvalifikator extern najčešće se koristi isključivo kod programa koji se sastoje od više
jedinica prevođenja i služi da naglasi da se neki identifikator ima neku vanjsku povezanost.
Jedino deklaracije mogu biti okvalificirane kvalifikatorom extern.
Samim tim, nakon njegovog navođenja nije moguće navoditi inicijalizaciju varijabli niti tijelo
funkcije (što ima smisla samo prilikom definiranja).
Pošto extern deklaracije nisu definicije, njima se ne rezervira nikakva memorija u
programu već se samo naglašava da se očekuje negdje (najčešće u drugim jedinicama
prevođenja) postoji definicija objekta koji se sa extern deklaracijom deklariše (i time
uvodi u odgovarajući doseg).
Ipak, postoje slučajevi kada se vanjska povezanost podrazumijeva i nije neophodno
eksplicitno upotrijebiti deklaraciju extern.
Sve globalne varijable i funkcije podrazumijevano imaju vanjsku povezanost (osim ako na njih
nije primjenjen kvalifikator static kada je povezanost unutarnja).

13. Koliko ima varijabli sa dosegom nivoa bloka u programu iz prethodnog zadatka?
Odgovor je 0, zato što su externalni povezani s globalnim varijablama.

Doseg identifikatora (scope) određuje da li se neka imena mogu koristiti u čitavim


jedinicama prevođenje ili samo u njihovim manjim dijelovima (najčešće funkcijama ili užim
blokovima)
Postojanje varijabli čija je upotreba ograničena na samo određene uske dijelove izvornog
koda olakđšava razumijevanje programa i smanjuje mogućnost grešaka i smanjuje međusobnu
zavisnost između raznih dijelova programa.
● Doseg razine (nivoa) datoteke - (file level scope) koji podrazumijeva da ime važi od
točke uvođenje do kraja datoteke;
● Doseg razine bloka (block level scope) koji podrazumijeva da ime važi od točke
uvođenja do kraja bloka u kojem je uvedeno;
● Doseg razine funkcije (function level scope) koji podrazumijeva da ime važi u cijeloj
funkciji u kojoj je uvedeno; ovaj doseg imaju jedino labele koji se koriste uz goto
naredbu;
● Doseg razine prototipa funkcije (function prototype scope) koji podrazumijeva da
ime važi u okviru prototipa (deklaracije) funkcije; a.
Najznačajnije razine dosega su doseg nivoa datoteke i doseg nivoa bloka.
Identifikatori koji imaju doseg nivoa datoteke najčešće se nazivaju vanjski ili globalni.
Identifikatori koji imaju ostale nivoe dosega (najčešće doseg nivoa bloka) nazivaju se
unutrašnji ili lokalni

int a; //a je globalna promjenjiva -doseg nivoa datoteke

void f(int c) { //f je glob. funkcija -doseg nivoa datoteke


//c je lokalna promj. - doseg nivoa bloka (tijela
funkcije f)
int d; //d je lok. promj. -doseg nivoa bloka (tijela f-e f)

Type text here


PROGRAMIRANJE I – USMENI ISPIT

void g() {printf(“Hello”);}


// g je lokalna f-a - doseg nivoa bloka(tijela f-e f)

for(d=0; d<3; i++) {


int e; // e je lok. promj.- doseg nivoa bloka(tijela petlje)
…}
kraj: //labela kraj-doseg nivoa funkcije
}
//h je globalna funkcija - doseg nivoa datoteke
void h(int b); //b-doseg nivoa prototipa f-e
Example:
void f() {
int a=3, i;
for (i=0; i<4; i++) {
int a=5;
printf(“%d”, a);}}
14. Šta ispisuje sljedeći kôd?
switch (1)
{
case '0': printf("B"); break;
case '1':
printf("L");
break;
default: printf("BL");
}
Ispis: BL
Prototip switch naredbe:
switch (n)
{
case constant1:
// code to be executed if n is equal to constant1;
break;

case constant2:
// code to be executed if n is equal to constant2;
break;
.
.
.
default:
// code to be executed if n doesn't match any constant
}
PROGRAMIRANJE I – USMENI ISPIT

U zadatku, ispis će biti po defaultu zato što se unutar switch naredbe nalazi int, međutim
konstante case-ove su charovi (case ‘0’:, case ‘1’:...), zbog toga se neće ispisati
onako kako je očekivano.

15. Dijagramom toka predstaviti sljedeći kôd.


do
{P;
if (R) continue;
S;}
while (T);

(NA PAPIRU)

17. Objasniti grešku(e) u sljedećem kodu:


char s[5],*p; p=s="STRING";
Na statički string s ne može se dodjeliti nikakva vrijednost poslije inicijalizacije. Pored toga,
u njemu nema dovoljno mjesta za skladištenje stringa “STRING” iz razloga što je potrebno
još jedno mjesto za terminator stringa. Na statički string može se dodjeljivati vrijednost i na
ovaj način:
char string[5] = {‘S’, ‘T’, ‘R’,...}
Dodjela vrijednosti statičkog dinamičkom stringu je moguća, ali nepoželjna.

18. Jednostavnim primjerom koda ilustrirati curenje iz memorije, naznačiti u


odgovarajućem komentaru mjesto i razlog curenja memorije.

U računarskoj tehnologiji, curenje memorije je tip curenja resursa koji se dogodi kada
program neispravno upravlja memorijskim alokacijama, na taj način da memorija koja više
nije potrebna nije oslobođena. U objektno orjentiranom programiranju , curenje memorije
može se dogoditi kad je objekt sačuvan u memoriji, ali mu se ne može pristupiti pokretnim
kodom.
U sljedećem kodu predstavljeno je curenje memorije, u kojoj nakon alokacije memorije,
program ne oslobađa preostali prostor.
void function_which_allocates(void) {
/* alokacija niza od 45 podataka tipa float */
float *a = malloc(sizeof(float) * 45);
PROGRAMIRANJE I – USMENI ISPIT

/* dodatni kod korištenja 'a' */

/* vraćanje u main, zaboravljajuci osloboditi memoriju koju smo m’allocirali */


}

int main(void) {
function_which_allocates();

/* pokazivac 'a' vise ne postoji, svakako ne moze biti oslobodjen,


ali memorija je i dalje alocirana. Dakle, doslo je do curenja. */
}

19. Navesti dvije različite primjene pokazivača.

20. Šta ispisuje sljedeći kôd (koristi se LE konvencija)?


char *c="54";
short *pc=(short*)c;
printf("%x", *pc);

Ispis: 3435
Svaki karakter u charu nosi svoju ASCII vrijednost. Budući da je u ovom slučaju pokazivač na
char kastovan na pokazivač na short, short* je nositelj njegove ASCII vrijednosti.
U ASCII tabeli, poželjno je znati sljedeće:
Brojevi se nalaze u intervalu od 3016-3916 , u dekadskom sistemu od 48-57;
Velika slova su u intervalu od 4116 - 5A16 , odnosno 65-90;
Velika slova su u intervalu od 6116-7A16, odnosno 97-122;
PROGRAMIRANJE I – USMENI ISPIT

Usmeni ispit iz programiranja I


Rok 23.02.2017.g.

1. Šta ispisuje sljedeći kôd (koristi se LE konvencija)?


union U {double d; long long i;} u={1.5};
printf("%d", u.i>>52);
Ispis: 1023

2. Što karakterizira svaki tip podataka?


Kao i u većini drugih programskih jezika, u jeziku C podaci su organizirani u tipove. To
omogućava da se u programima ne radi samo nad pojedinačnim bitovima i bajtovima, već i
nad skupovima bitova, koji su, pogodnosti radi, organizirani u složenije podatke (npr. cijele
brojeve ili brojeve u pokretnom zarezu). Jedan tip karakterizira: vrsta podataka koje opisuje,
način reprezentacije, skup operacija koje se mogu primjeniti nad podacima tog tipa, kao i
broj bitova koji se koriste za reprezentaciju (odakle slijedi opseg mogućih vrijednosti).

3. Navesti sve zvanične standarde programskog jezika C. Za svaki standard navesti i


godinu usvajanja.

K&R C. Brian Kerninghan i Dennis Ritchie objavili su 1978. godine prvo izdanje knjige
Programski jezik C (The C Programming Language). Ova knjiga, među programerima poznata
je kao K&R ili kao white book, godinama je služila kao neformalna specifikacija jezika. Čak i
poslije pojave novih standarda, K&R je dugo vremena služio kao “najmanji zajednički
nazivnik”, koji je korišten kada je bilo potrebno postići visok stupanj prenosivosti.
ANSI C i ISO C. - tijekom 1980.-ih javila se potreba za standardizacijom. Godine 1989.
američki institut za standardizaciju (ANSI), objavio je standard pod nazivom ANSI X3.159-
1989 “Programming Language C”. Međunarodna organizacija za standardizaciju (ISO) 1990.
usvaja ovaj dokument.
C99 - usvojen je 1999. Uvodi sitne izmjene, uglavnom se proširuje.
C11 (nekada C1X) - 2007. god započet je rad na novom standardu koji je dovšen 2011.god.

4. Deklarisati označenu znakovnu varijablu pod imenom c i inicijalizovati je kodom


znaka Y.

signed char c = ‘Y’;

5. Navesti prototip standardne funkcije realloc.

void *realloc(void *memblock, size_t size);


Parametar memblock je pokazivač na prethodno alocirani blok memorije, a parametar
size je nova veličina u bajtovima. Funkcija realloc vraća pokazivač tipa void* na
realociran blok memorije, a NULL u slučaju da zahtjev ne može biti ispunjen. Zahtjev za
PROGRAMIRANJE I – USMENI ISPIT

smanjivanje veličine memorijskog bloka uvijek uspijeva. U slučaju zahtjeva za povećanje


veličine alociranog bloka memorije, pri čemu iza postojećeg bloka postoji dovoljno prostora,
taj prostor se koristi jednostavno za proširivanje. Međutim, ukoliko iza postojećeg bloka ne
postoji dovoljno slobodnog prostora, onda se u memoriji traži drugo mjesto dovoljno da
prihvati prošireni blok i, ako se nađe, sadržaj postojećeg bloka se kopira na to novo mjesto i
zatim se stari blok memorije oslobađa.
Vrijedi navesti i ostale prototipove za dinamičku alokaciju memorije:
void *malloc(size_t n);
Ona alocira blok memorije (niz uzastopnih bajtova) veličine n bajtova, i vraća adresu
alociranog bloka u vidu generičkog pokazivača (tipa void*). U slučaju da zahtjev za
memorijom nije moguće ispuniti (npr. nema dovoljno na raspolaganju), ova funkcija vraća
NULL. Memorija na koju funkcija malloc vrati pokazivač nije inicijaliziran, i njen sadržaj
je nedefiniran (tj. ovisi od podataka koji su bili čuvani u tom dijelu memorije).
Funkcija malloc očekuje argument tipa size_t. Ovo je nenegativni cjelobrojni
tip za čije je vrijednosti rezervirano najmanje dva bajta.
void *calloc(size_t n, size_t size)
Ona vraća pokazivač na blok memorije veličine n objekata navedene veličine size.
U slučaju neispunjenja zahtjeva, vraća NULL. Za razliku od malloc, alocirana memorija
je inicijalizirana na nulu.
Dinamički objekti alocirani navedenim funkcijama su neimenovani i bitno su različiti od
varijabli. Ipak, dinamički alociranim blokovima se pristupa kao i nizovima.
void free(void* p);
Poziv free(p) oslobađa memoriju na koju ukazuje pokazivač p (a ne memorijski
prostor koji sadrži sam pokazivač p), pri čemu je neophodno da p pokazuje na blok
memorije koji je alociran pozivom funkcije malloc i calloc.
Redoslijed oslobađanja ne mora odgovarati redoslijedu alociranja.

6. U kojem memorijskom segmentu će se nalaziti p tokom izvršavanja sljedeće


funkcije i koliko bajtova će zauzimati?
void f()
{
char *p[]={"A","U","T","O"};
}
Charovi A,U,T,O nalazit će se u Data segmentu, dok će se p nalaziti u stacku. Zauzimat
će 4 byte-a. Nešto više o segmentima memorije:

Načini organiziranja i korištenja memorije u fazi izvršavanja programa može se razlikovati od


jednog do drugog operacijskog sustava.
Kada se izvršni program učita u radnu memoriju računala, dodjeljuje mu se određena
memorija i započinje njegovo izvršavanje.
Dodijeljena memorija organizirana je u nekoliko dijelova koje zovemo segmenti ili zone:
PROGRAMIRANJE I – USMENI ISPIT

● Segment koda (code segment ili text segment)


● Segment podataka (data segment)
● Stack segment
● Heap segment

Von Neumannova arhitektura računala predviđa da su memoriji čuvaju podaci i programi


● Segment koda - u ovom segmentu nalazi se sam izvršni kod programa, ukoliko se
pokrene više instanci jednog programa, ovaj segment može da bude zajednički za sve
instance (zavisi od OS-a)
● Segment podataka - u ovom segmentu čuvaju se određene vrste varijabli koje su
zajedničke za cijeli program: globalne varijable, varijable sa statičkim životnim
vijekom, kao i konstante (najčešće niske); ukoliko se pokrene više instanci jednog
programa, svaka instanca ima svoj zaseban segment podataka.
● Heap segment - nalaze se dinamički alocirani podaci
● Stack segment - čuva sve podatke koji karakteriziraju izvršavanje funkcija
Podaci koji odgovaraju jednoj instanci funkcije organizirani su u tzv. stack okvir.
Stack okvir jedne instance funkcije, između ostalog, sadrži:
❏ Argumente funkcije;
❏ Lokalne varijable (deklarisane unutar funkcije);
❏ Međurezultate izračunavanja;
❏ Povratnu adresu (ukazuje odakle treba nastaviti izvršavanje programa nakon
povratka iz funkcije);
❏ Adresu stack okvira funkcije pozivatelja.
Veličina stack segmenta obično je ograničena. Stack poziva je struktura LIFO tipa - stack
okvir može se dodati samo na vrh stack-a i sa stack-a se može ukloniti samo okvir koji je na
vrhu.
Stack okvir za instancu se kreira onda kada funkcija treba da se izvrši i taj stack okvir se
oslobađa (smatra se nepostojećim) onda kada se završi izvršavanje funkcije.
Ako izvršavanje programa počinje sa funkcijom main, prvi stack frame se kreira za ovu
funkciju. Ako funkcija main poziva neku funkciju f, na vrhu stack-a, iznad stack frame-a
funkcije main, kreira se novi stack okvir za ovu funkciju. Ukoliko funkcija f poziva neku treću
funkciju, onda će za nju biti kreiran stack okvir na novom vrhu stacka. Kada se završi
izvršavanje funkcije f, onda se vrh stack-a vraća u prethodno stanje i prostor koji je zauzimao
stack frame za f se smatra slobodnim.

7. Šta ispisuje sljedeći kôd?


printf("%d",printf("B""L""O""K"));

Ispis: BLOK4
PROGRAMIRANJE I – USMENI ISPIT

Printf kao funkcija vraća broj elemenata koje ispisuje, tako da će se u ovom slučaju prvo
izvršiti podfunkcija, te će ispisati BLOK, bez navodnika. Ispis bi bio isti da smo deklarisali
na sljedeći način:
printf(“%d”, printf(“BLOK”));
Nakon ispisa stringa, funkcija također ispisuje i broj elemenata koliko je ispisala.

8. Šta ispisuje sljedeći kôd?


void f()
{ printf("BL"); }
int main() {
void f(); f; return 1; }
Kod ne ispisuje ništa. Kompajler će izbaciti grešku. Funkcija f iz maina nije ispravno pozvana i
samim tim ništa se ne događa.

9. Korištenjem petlje while izraziti sljedeću petlju:


do { A; } while (B);

A;
while(B)
A;
Potrebno je naglasiti da će se naredbe do-while petlje UVIJEK izvršiti barem jednom.
TRANSFORMACIJA while U do-while

while(A)
B;

if(A) {
do {
B; }while(A);
}
10.(prošli rok)

11. Pretpostaviti da se za reprezentaciju podataka u memoriji koristi LE konvencija


pa heksadecimalno prikazati sadržaj memorijskih lokacija na kojima je smještena
varijabla f koja je definisana na sljedeći način:
float f = 1.0/0.0;
Realne brojeve, odnosno brojeve u pokretnom zarezu opisuju tipovi float, double i
long double. Tip float opisuje brojeve u pokretnom zarezu osnovne preciznosti, tip
double dvostruke preciznosti, a tip long double proširene preciznosti. Sa podacima
sa ovim tipovima mogu se primjenjivati uobičajene aritmetičke operacije (osim operacije
računanja ostatka pri dijeljenju %) i relacije.
Brojevi u pokretnom zarezu kod modernih računala najčešće se zapisuju u skladu sa IEEE754
standardom. Ovaj standard omogućava mogućnost zapisa specijalnih vrijednosti (-inf, +inf,
PROGRAMIRANJE I – USMENI ISPIT

Nan). Npr. vrijednost izraza 1.0/0.0 je +inf za razliku od cjelobrojnog izraza 1/0
čije izračunavanje dovodi do greške. Obično se pri cjelobrojnom dijeljenju sa nulom
prijavljuje samo upozorenje od strane kompajlera, a ukoliko dođe to izvršavanja dijeljenja,
prekida se program.
Vrijednost izraza 0.0/0.0 je NaN i ta vrijednost se koristi da označi matematički
nedefinirane vrijednosti. Na primjer, ako se na izraz čija je vrijednost +beskonačno doda
neka konstantna vrijednost, ponovno se dobiva vrijednost +beskonačno, ali vrijednost izraza
1.0/+beskonačno jednaka je 0.0. S druge strane, svi izrazi u kojima sudjeluje
vrijednost NaN ponovno imaju istu vrijednost NaN.

Nula, beskonačno i NaN su reprezentirani pomoći IEEE754 standarda na sljedeći način:


Plus beskonačno: svi elementi eksponenta su jedinice, bit znaka je 0, svi biti
mantise su nule.
32-bitna preciznost: 0x7F80 0000 64-bitna: 0x7FF0 0000 0000 0000
Minus beskonačno: eksponent jedinice, bit znaka 1, biti kod mantise su nule
32-bit: 0xFF80 0000 64-bitna: 0xFFF0 0000 0000 0000
NaN: biti eksponenta su 1, znak je 0, bar jedan bit mantise je setovan
32-bit: 0x7FC0 0000 64-bitna:0x7FF8 0000 0000 0000
Pozitivna nula: svi biti su nule;
Negativna nula: svi biti su nule sem bita znaka;

Rješenje zadatka je sljedeće:

7 F

8 0

0 0

0 0

12. Šta ispisuje sljedeći kôd?


int a[]={7,8,9}, *p=a; printf("%d", sizeof(p));
Ispis: zavisno od sistema, 32-bit=4; 64bit=8
Veličina pokazivača, ma kojeg tipa, je UVIJEK: na 16bitnim sistemima veličine 2 bajta, na 32-
bitnim veličine 4 bajta, a na 64bitnim 8 bajta.
Kompajler po defaultu radi na 32-bit arhitekturi.

13. Ako je kao argument u pozivu funkcije navedeno ime niza, šta se prenosi u
funkciju?

Prenosi se početna adresa tog niza.


PROGRAMIRANJE I – USMENI ISPIT

14. Za koliko se mijenja vrijednost varijable p tipa T*, nakon izvršavanja naredbe
p+=sizeof(T)?
Mijenja se za sizeof(t)+sizeof(t)

15. Navesti naredbe za nasilnu kontrolu toka u programskom jeziku C.


U nekim situacijama pogodno je napustiti petlju, ne zbog toga što nije ispunjen uslov, već iz
nekog drugog razloga. To je moguće naredbom break kojom se izlazi iz tekuće petlje. Kod
koji koristi naredbu break uvijek se može napisati bez nje.
Naredbom continue se prelazi na sljedeću iteraciju u petlji. U slučaju ugnježdenih petlji
naredbe break i continue imaju utjecaj samo na unutarnju petlju.
Pored navedenih naredbi, postoji još i naredba goto koja omogućava neuvjetni skok od
goto naredbe to navedene uvjetovane naredbe. Kao i kod prethodnih, svaki program
može se napisati i bez ove narebe. Sintaksa je sljedeća:
goto label;
..
.
label: statement
Ovdje label može biti bilo koja riječ i može stajati bilo gdje iznad ili ispod naredbe
goto.

16. Koji izrazi (A, B, C i/ili D) će se izvršiti ako je X=0 i Y=1? I


f (X) A, if (Y) B; else C, D;
Izvršit će se izraz B.

17. Ukoliko je na globalnu varijablu primijenjen kvalifikator static, kakvi su njeni: a)


doseg? b) povezanost? c) životni vijek?
Doseg statičke varijable je nivoa datoteke, unutrašnju povezanost i statički životni vijek.
PROGRAMIRANJE I – USMENI ISPIT

Rok 12.05.2017.

1. Šta ispisuje sljedeći kôd (koristi se LE konvencija)?


float f = 2.0/0.0;
printf("%x", *(int*)&f);

Ispis: plus beskonačno zapisano u heksadecimalnom obliku. 7F80


0000

2. ,3., 4. (prethodni rokovi)

5. Odrediti koliko u sljedećem kodu


char a,b,c; c=a+b; ima:
a) promocija?
b) democija?
Oblik konverzije koji predstavlja konverzija vrijednosti “nižeg tipa” u vrijednost “višeg tipa”
(na primjer short u long, int u float ili float u double) u kom slučaju
najčešće ne dolazi do gubitka informacije. Konverzija tog oblika ponekad se naziva
promocija (ili napredovanje). Do gubitka informacije može da dođe, kao na primjer:
float f = 16777217;
printf(“%f\n”, f);
na većini OS-ova ispis će biti:
16777216.00000
Jer se zadana vrijednost ne može zapisati u obliku IEEE754FP.
Drugi oblik konverzije predstavlja konverzija vrijednosti višeg tipa u vrijednost nižeg tipa (na
primjer long u short, double u int). Ovaj oblik konverzije ponekad se naziva
democija (nazadovanje). Prilikom ove konverzije, moguće je da dođe do gubitka informacije
(u slučaju da se polazna vrijednost ne može predstaviti u okviru novog tipa). Tada kompajler
šalje upozorenja, ali ipak kompajlira.
Example:
int b = 7.0f //7.0f je float pa se vrsi konverzija u 7
int c = 7.7f //7.7f je float pa se konvertuje u 7, pri cemu
dolazi do gubitka informacija
unsigned char d=256; //d dobiva vrijednost 0
Rješenje zadatka: Desit će se DVIJE promocije i JEDNA democija. Prilikom zbrajanja charovi
a i b konvertirat će se u int, to su dvije promocije, zatim će se ta dobivena vrijednost
konvertirat u char (democija) i dodijeliti istom.

6. Odrediti koliko promocija ima u sljedećem kodu?


short int a, b;
float c = a + b;
Imaju 3 promocije. Short int ide u int, i na kraju dobivena vrijednost ide u float.
PROGRAMIRANJE I – USMENI ISPIT

7. Ako je niz dniz tipa double inicijalizovan u okviru deklaracije i njegova dimenzija
nije navedena, kako se ona može izračunati?
Rješenje: Dimenzija se računa na osnovu broja inicijaliziranih elemenata u inicijalizatoru.
dimension=sizeofniz/nizeof(niz[0]
8. Šta ispisuje sljedeći kôd, uz uobičajene postavke programskog prevodioca?
struct s { int i; char c; } niz[10]; printf("%d",
sizeof(niz));
Rješenje: Po 64/32-bitnoj arhitekturi (koju koristi većina online kompajlera) rezultat je 80.

9. Šta ispisuje sljedeći kôd?


enum X {A, B=-1, C, D=-1, E};
printf("1:%x\n", A+B+C+D+E);
printf("2:%d\n", sizeof(X));
Rješenje: 1:ffff fffe
2:4

10. Dijagramom toka predstaviti sljedeći kôd:


for (;;);

?????? vrijednost izraz2 je uvijek točno


11. Napisati funkciju koja u dinamičkoj zoni memorije alocira segment veličine 1
mebibajt. Prototip funkcije je: void *alokacija();
Rješenje: return malloc(1024*1024*sizeof(char));

12. Šta ispisuje sljedeći kôd?


char c[]="45";
short *pc=(short*)c;
printf("%x", *pc&0xF0F);
Ispis: 504
U short se pohranjuje ASCII vrijednost charova u c-u po LE konvenciji.
PROGRAMIRANJE I – USMENI ISPIT

Poslije se porede operatorom &. Taj operator radi na način da moraju oba uvjeta biti
ispunjena da bi izlaz bio jedan.

13. Šta ispisuje sljedeći kôd?


unsigned char c=010;
printf("%x", c=c<<0x4|c>>0x4);
Rješenje:
c=0000 0010 << 0x04 = 0010 0000 = 8016
c=0010 >> 0x04 = 0
80 = 10 0000
0 = 00 0000 |
10 0000 = 80
Kod bitskog “ili” izlaz je jednak stanju logičke jedinice ako je ispunjen samo jedan ili oba
uvjeta.

14. Odrediti X u izrazu: X4=1.18


X = 01.02 1

15. Šematski prikazati Von Neumannovu arhitekturu i navesti njen značaj za razvoj
programiranja.


Kontrolna ALJ
jedinica

registri

magistrala

Mem. Ul. uređaji I. uređaji


Važne karakteristike procesora danas su broj jezgara (1, 2 ili 4), širina riječi (32bit ili 64bit) i
radni takt (obično nekoliko GHz)- veći radni takt omogućava izvršavanje većeg broja
operacija u jedinici vremena.
Rok 23.06.2017

1. Šta ispisuje sljedeći kôd (koristi se LE konvencija)?


float f = 5e-1;
printf("%x", *(int*)&f);
Ispis: 3F00 0000
5e-1 = 0.5
PROGRAMIRANJE I – USMENI ISPIT

0.510 = 0,12
E=1.0 * E-1 = 127-1= 126= 0111 1110
S=0
M=000 *E20→0011 1111 0000 0000 0000 0000 0000 0000→3F00 0000

2. Šta ispisuje sljedeći kôd?


static int i;
printf("1:%d\n", i --> 0);
printf("2:%x", i);
Ispis: 1:0
2:ffff ffff
Vrijednost varijable i po defaultu jednaka je nuli ukoliko joj se ne dodijeli nikakva vrijednost
prilikom inicijalizacije. U prvom printfu vrsi se provjera da li je i post-dekrementirano vece
od nule (u ovoj liniji koda i je jos uvijek jednak nuli). Kako operatori poredjenja vracaju 0
ako uslov nije ispunjen i 1 ako je uslov ispunjen, ocigledno je da 0>0 svakako nije ispunjeno
prema tome ispis ce biti 0 u prvom printfu.
Sto se tice drugog printfa tu se ispisuje vrijednost dekrementiranog i koji u
heksadecimalnom br sistemu ima vrijednost ffff ffff.

3. Odrediti koliko u sljedećem kodu


short int a,b,c; c = a + b; ima:
a) promocija?
b) democija?
Rješenje: 2 promocije, 1 democija.

4. Šta ispisuje sljedeći kôd?


signed char c=0x10;
printf("%x", c<<0x4|c>>0x4);
Rješenje: c=0001 0000
0001 0000<<4 =0001 0000 0000 = 100
0001 0000>>4 = 0001 = 1

0001 0000 0000


0000 0000 0001 |
0001 0000 0001= 101

5. Za varijablu x u sljedećem kodu


int main() {
char x[]="45";
return 0;
} treba odrediti:
a) doseg?
b) povezanost?
PROGRAMIRANJE I – USMENI ISPIT

c) životni vijek?
Rješenje: Doseg ove lokalne varijable je nivoa bloka, nije okarakterisana nikakvim vanjskim
identifikatorom, dakle nepovezana je, kako nije naglašeno ima automatski životni vijek.

6. Šta ispisuje sljedeći kôd, uz uobičajene postavke programskog prevodioca?


struct s { int i; short c; } niz[10][2];
printf("%d", sizeof(niz));
Rješenje: 160

7. Šta ispisuje sljedeći kôd, uz uobičajene postavke programskog prevodioca?


struct s { short c[3]; } x; printf("%d", sizeof(x));
Rješenje: 6

8. Koliko podataka tip unsigned int može da se smjesti u dinamički alociran


segment memorije veličine 2 kibibajta?
Rješenje: sizeof(unsigned int) = 4 B;
2 KiB = 2*1024 B= 2048B
2048 / 4 = 512

9. Dijagramom toka predstaviti sljedeći kôd:


if (a)
if (b)
c;
else d;
e;

10. Šta ispisuje sljedeći kôd?


int a=2, b=0; do { if (!a--) continue; b--; } while (a);
printf("%d", b);
Rješenje: -2
if(!a)==if(a==0)
PROGRAMIRANJE I – USMENI ISPIT

11. Modifikovati sljedeći kôd tako da pokazivač x ima vrijednost nula nakon poziva
funkcije reset.
void reset(T *p) { p=0; } int main() { T *x; reset(x); return
0; }

12. Šta ispisuje sljedeći kôd?


short x=03, y=02, z=01; printf("1:%d\n", sizeof(z=x+y));
printf("2:%d", z);
Rješenje: 1:2
2:1
13. Definisati funkciju sread koja sa standardnog ulaza učitava i kroz parametre
vraća učitani podatak sljedećeg tipa: struct S { int i; };
void func(struct S* name)
{
scanf(“%d”,&name->i);
}

14. Šta je l-value i šta sve može da bude l-value?


Rješenje: U dodjeljivanju vrijednosti, sa lijeve strane operatora dodjele može da se nalazi
varijabla, ili element niza ili memorijska lokacija. Ti objekti, objekti kojima može biti
dodijeljena vrijednost nazivaju se l-vrijednosti (l-value ili left-value)
PROGRAMIRANJE I – USMENI ISPIT

Rok 14. 07.2017

1. Pretpostavimo da je u funkciji data sljedeća definicija:


float f=5e1;
a) U kojem će memorijskom segmentu biti smještena varijabla f tokom izvršavanja
programa?
b) Šta ispisuje sljedeći kôd? printf("%06.2f", f);
c) Šta ispisuje sljedeći kôd?
unsigned int *p=(unsigned int *)&f; printf("%x", *p);
d) Heksadecimalno prikazati reprezentaciju varijable f u memoriji (pretpostaviti da je
&f=28ff1c), ako se koristi:
1) Little Endian konvencija
2) Big Endian konvencija

Rješenje:
a) Varijabla će biti smještena u stacku.
b) 050.00
c) Kastuje se adresa varijable tipa float u adresu unsigned int*-a
5010 = 1100102
E = 1,10010 * E5 = 127+5=132
132 = 1000 0100
Rezultat: 0100 0010 0100 1000 0000 0000 0000 0000 = 42480000
d) LE i BE konvencija - respektivno

28ff20

00 28ff1f

00 28ff1e

48 28ff1d

42 42 28ff1c

48 28ff1b

00 28ff1a

00 28ff19
PROGRAMIRANJE I – USMENI ISPIT

2. Pretpostavimo da su izvan svih funkcija date sljedeće definicije: const short*


p1; short const *p2;
a) U kojem će segmentu u memoriji bit smješteno p1, a u kojem p2, tokom
izvršavanja programa?
b) Šta predstavlja prva, a šta druga definicija?
c) Objasniti grešku u sljedećem kodu (ako postoji):
p1=p2;
d) Objasniti grešku u sljedećem kodu (ako postoji):
*p1=*p2;
e) Objasniti grešku u sljedećem kodu (ako postoji):
&p1=&p2;

Rješenje:
a) Tijekom izvršavanja programa, gdje će se navedene varijable smjestiti ovisi o tipu
kompajlera. GCC ih smješta u .text sekciju, ukoliko se ne naredi drugačije. Oblično
se pohranjuju na read-only data sekciju.
b) Prva definicija je pokazivač na konstantan short, a druga je konstantan pokazivač na
short.
c) Nema greške. Dodjela je moguča.
d) Nije moguće dodijeliti *p1 na *p2, iz razloga što se pokazivač na konstantan short
nalazi samo u read-only sekciji, i njegovu vrijednost NIJE moguće prepisivati.
e) Svaki pokazivač ima vlastitu adresu, i oni između sebe ne mogu razmijenjivati adrese.

3. Pretpostavimo da imamo sljedeću globalnu definiciju:


struct _s { struct _s *ps; short int s; };
a) Ako pretpostavimo uobičajena podešavanja programskog prevodioca, šta ispisuje
sljedeći kôd?
printf("%d", sizeof(struct _s));
b) Kako se uobičajeno naziva ovakva struktura (struktura koja sadrži pokazivač na
strukturu istog tipa)?
c) Definisati dvije varijable s1 i s2, koristeći datu definiciju strukture _s, pri čemu ih
treba inicijalizovati kao što je ilustrovano na slici:
d) Definisati niz od dva pokazivača i inicijalizovati ga tako da pokazivači redom
pokazuju varijable s1 i s2.
e) Definisati funkciju koja vraća jednu dinamički alociranu _s strukturu, pri čemu su
oba elementa strukture nula.
Rješenje:
a) 8;
b)
c) Jednostruko povezana ulančana lista.
DATO GRADIVO OBRAĐUJE SE U PROGRAMIRANJU II.
PROGRAMIRANJE I – USMENI ISPIT

4. Pretpostavimo sljedeću definiciju main funkcije:


int main() {
char *x="2";
for (char *x="45"; *x++<'5'; );
printf("%c", *x);
return 0; }
a) Šta će biti ispisano na standardnom izlazu kao rezultat izvršavanja date funkcije?
b) Ako za izraz c=a+b, prioritet operatora prikažemo u obliku:
1: + 2: =
kako bismo, analogno prethodnom, prikazali prioritet operatora za sljedeći izraz:
*x++<'5'
c) Za sve operatore iz prethodnog izraza treba navesti njihovu asocijativnost.

Rješenje:
a) 2
b) 1: ++ 2: <
c) ++ → zdesna na lijevo, < → slijeva na desno
huseinagicrahmo@gmail.com

You might also like