III Äas - Ncd.matf.bg.ac.rs
III Äas - Ncd.matf.bg.ac.rs
III Äas - Ncd.matf.bg.ac.rs
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Programiranje II<br />
Beleške sa vežbi<br />
Smer Informatika<br />
Matematički fakultet, Beograd<br />
Sana Stojanović<br />
1
Sadržaj<br />
1 Pokazivači - ponavljanje 3<br />
2 Pokazivači - veza sa nizovima 5<br />
2
1 Pokazivači - ponavljanje<br />
1. /* Pokaziv<strong>ac</strong>i - osnovni pojam */<br />
#include <br />
main()<br />
{<br />
int x = 3;<br />
/* Adresu promenjive x zapamticemo u novoj promeljivoj.<br />
Nova promenljiva je tipa pokaziv<strong>ac</strong>a na int (int*) */<br />
int* px;<br />
printf("Adresa promenljive x je : %p\n", &x);<br />
printf("Vrednost promenljive x je : %d\n", x);<br />
px = &x;<br />
printf("Vrednost promenljive px je (tj. px) : %p\n", px);<br />
printf("Vrednost promenljive na koju ukazuje px (tj. *px) je : %d\n", *px);<br />
/* Menjamo vrednost promenljive na koju ukazuje px */<br />
*px = 6;<br />
printf("Vrednost promenljive na koju ukazuje px (tj. *px) je : %d\n", *px);<br />
/* Posto px sadrzi adresu promenljive x, ona ukazuje na x tako da je<br />
posredno promenjena i vrednost promenljive x */<br />
printf("Vrednost promenljive x je : %d\n", x);<br />
}<br />
2. (DOMAĆI) Popuniti sledeću tabelu:<br />
A B C P1 P2<br />
Init 1 2 3 &A &C<br />
*P1 = (*P2)++<br />
P1 = P2<br />
P1 = &B<br />
*P1 = *P1 - *P2<br />
3. /* swap : Demonstr<strong>ac</strong>ija prenosa argumenata preko pokaziv<strong>ac</strong>a */<br />
#include <br />
/* Pogresna verzija funkcije swap. Zbog prenosa po vrednosti, funkcija<br />
razmenjuje kopije promenljivih iz main-a, a ne samih promenljivih */<br />
void swap_wrong(int x, int y)<br />
3
{<br />
int tmp;<br />
printf("swap_wrong: ");<br />
printf("Funkcija menja vrednosti promenljivim na adresama : \n");<br />
printf("x : %p\n", &x);<br />
printf("y : %p\n", &y);<br />
}<br />
tmp = x;<br />
x = y;<br />
y = tmp;<br />
/* Resenje je prenos argumenata preko pokaziv<strong>ac</strong>a */<br />
void swap(int* px, int* py)<br />
{<br />
int tmp;<br />
printf("swap : Funkcija menja vrednosti promenljivim na adresama : \n");<br />
printf("px = %p\n", px);<br />
printf("py = %p\n", py);<br />
}<br />
tmp = *px;<br />
*px = *py;<br />
*py = tmp;<br />
main()<br />
{<br />
int x = 3, y = 5;<br />
printf("Adresa promenljive x je %p\n", &x);<br />
printf("Vrednost promenljive x je %d\n", x);<br />
printf("Adresa promenljive y je %p\n", &y);<br />
printf("Vrednost promenljive y je %d\n", y);<br />
/* Pokusavamo zamenu koristeci pogresnu verziju funkcije */<br />
swap_wrong(x, y);<br />
printf("Posle swap_wrong:\n");<br />
printf("Vrednost promenljive x je %d\n", x);<br />
printf("Vrednost promenljive y je %d\n", y);<br />
/* V<strong>rs</strong>imo ispravnu zamenu. Funkciji swap saljemo adrese promenljvih<br />
x i y, a ne njihove vrednosti */<br />
swap(&x, &y);<br />
4
}<br />
printf("Posle swap:\n");<br />
printf("Vrednost promenljive x je %d\n", x);<br />
printf("Vrednost promenljive y je %d\n", y);<br />
2 Pokazivači - veza sa nizovima<br />
1. /* Pokaziv<strong>ac</strong>ka aritmetika */<br />
#include <br />
main()<br />
{<br />
char s[] = "abcde";<br />
int t[] = {1, 2, 3, 4, 5};<br />
/* Inicijalizujmo pokaziv<strong>ac</strong>e ps i pt na pocetke nizova s i t */<br />
char* ps = &s[0];<br />
int* pt = &t[0];<br />
/* Pokaziv<strong>ac</strong>e je moguce sabirati sa celim brojevima i<br />
od njih je moguce oduzimati cele brojeve*/<br />
/* Ispisimo vrednosti pokaziv<strong>ac</strong>a */<br />
printf("ps = %p\n", ps);<br />
printf("ps+1 = %p\n", ps+1);<br />
printf("ps+2 = %p\n", ps+2);<br />
printf("ps-1 = %p\n", ps-1);<br />
printf("ps-2 = %p\n", ps-2);<br />
/* Prilikom sabiranja pokaziv<strong>ac</strong>a i celih brojeva,<br />
dodaje se velicina odgovarajuceg tipa. */<br />
printf("pt = %p\n", pt);<br />
printf("pt+1 = %p\n", pt+1);<br />
printf("pt+2 = %p\n", pt+2);<br />
printf("pt-1 = %p\n", pt-1);<br />
printf("pt-2 = %p\n", pt-2);<br />
/* Na pokaziv<strong>ac</strong>e je moguce primenjivati i operatore ++ i -- */<br />
for (ps = s; *ps; ps++)<br />
putchar(*ps);<br />
putchar(’\n’);<br />
5
* Slicno, dva pokaziv<strong>ac</strong>a istog tipa se mogu oduzimati. Prilikom sr<strong>ac</strong>unavanja<br />
rezultata, uzima se u obzir velicina tipa. */<br />
ps = &s[3];<br />
printf("s = %p\n", s);<br />
printf("ps = %p\n", ps);<br />
printf("ps - s = %d\n", ps - s);<br />
pt = &t[3];<br />
printf("t = %p\n", t);<br />
printf("pt = %p\n", pt);<br />
printf("pt - t = %d\n", pt - t);<br />
}<br />
2. /* Veza izmedju pokaziv<strong>ac</strong>a i nizova */<br />
#include <br />
void print_array(int* pa, int n);<br />
main()<br />
{<br />
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};<br />
int num_of_elements = sizeof(a)/sizeof(int);<br />
int* pa;<br />
/* Niz je isto sto i adresa prvog elementa */<br />
printf("Niz a : %p\n", a);<br />
printf("Adresa prvog elementa niza a (&a[0]) : %p\n", &a[0]);<br />
/* Moguce je dodeliti niz pokaziv<strong>ac</strong>u odgovarajuceg tipa */<br />
pa = a;<br />
printf("Pokaziv<strong>ac</strong> pa ukazuje na adresu : %p\n", pa);<br />
/* Nizu nije moguce dodeliti pokaziv<strong>ac</strong>ku promenljivu<br />
(nizove mozemo smatrati KONSTANTNIM pokaziv<strong>ac</strong>ima na prvi element) */<br />
/* a = pa; */<br />
/* Niz je moguce koristiti kao pokaziv<strong>ac</strong> tj. vaze pravila pokaziv<strong>ac</strong>ke aritmetike<br />
printf("a + 3 = %p\n", a + 3);<br />
/* Vazi da je<br />
a + i =<br />
odnosno<br />
&a[i]<br />
6
*(a + i) = a[i]<br />
*/<br />
printf("&a[3] = %p\n", &a[3]);<br />
/* Identiteti<br />
a + i = &a[i]<br />
odnosno<br />
*(a + i) = a[i]<br />
vazi i za pokaziv<strong>ac</strong>e i za nizove */<br />
/* Pokaziv<strong>ac</strong>e je na osnovu prethodnog moguce indeksirati kao nizove */<br />
printf("pa[5] = %d\n", pa[5]);<br />
printf("*(pa + 5) = %d\n", *(pa+5));<br />
/* Medjutim, sizeof(pa) je samo velicina pokaziv<strong>ac</strong>a, a ne niza */<br />
printf("sizeof(a) = %d\n", sizeof(a));<br />
printf("sizeof(pa) = %d\n", sizeof(pa));<br />
}<br />
/* Pozivamo funkciju za stampanje niza i saljemo joj niz */<br />
print_array(a, num_of_elements);<br />
/* Pozivamo funkciju za stampanje niza i saljemo joj pokaziv<strong>ac</strong> na pocetak niza *<br />
print_array(pa, num_of_elements);<br />
/* Proslednjivanje niza u funkciju<br />
void print_array(int pa[], int n);<br />
je ekvivalentno prosledjivanju pokaziv<strong>ac</strong>a u funkciju<br />
void print_array(int* pa, int n);<br />
Izmedju ovih konstrukcija nema nikakve razlike.<br />
*/<br />
void print_array(int* pa, int n)<br />
{<br />
int i;<br />
for (i = 0; i
* Izr<strong>ac</strong>unava duzinu stringa */<br />
int string_length(char *s)<br />
{<br />
char* t;<br />
for (t = s; *t; t++)<br />
;<br />
return t - s;<br />
}<br />
/* Kopira string src u string dest. Pretpostavlja da u dest ima dovoljno prostora. *<br />
void string_copy(char *dest, char *src)<br />
{<br />
/* Kopira karakter po karakter, sve dok nije iskopiran karakter ’\0’ */<br />
while(*dest++ = *src++)<br />
;<br />
}<br />
/* Nadovezuje string t na kraj stringa s. Pretpostavlja da u s ima dovoljno prostora<br />
void string_concatenate(char *s, char *t)<br />
{<br />
/* Pronalazimo kraj stringa s */<br />
while (*s)<br />
s++;<br />
}<br />
/* V<strong>rs</strong>i se kopiranje, slicno funkciji string_copy */<br />
while (*s++ = *t++)<br />
;<br />
/* V<strong>rs</strong>i leksikografsko poredjenje dva stringa.<br />
Vr<strong>ac</strong>a :<br />
0 - ukoliko su stringovi jednaki<br />
0 - ukoliko je s leksikografski iza t<br />
*/<br />
int string_compare(char *s, char *t)<br />
{<br />
/* Petlja tece sve dok ne naidjemo na prvi razliciti karakter */<br />
for (; *s == *t; s++, t++)<br />
if (*s == ’\0’) /* Naisli smo na kraj oba stringa, a nismo nasli razliku */<br />
return 0;<br />
/* *s i *t su prvi karakteri u kojima se niske razlikuju.<br />
8
}<br />
Na osnovu njihovog odnosa, odredjuje se odnos stringova */<br />
return *s - *t;<br />
/* Pronalazi prvu poziciju karaktera c u stringu s, i vr<strong>ac</strong>a pokaziv<strong>ac</strong> na nju,<br />
odnosno NULL ukoliko s ne sadrzi c */<br />
char* string_char(char *s, char c)<br />
{<br />
for (; *s; s++)<br />
if (*s == c)<br />
return s;<br />
}<br />
/* Nije nadjeno */<br />
return NULL;<br />
/* Pronalazi poslednju poziciju karaktera c u stringu s, i vr<strong>ac</strong>a pokaziv<strong>ac</strong> na nju,<br />
odnosno NULL ukoliko s ne sadrzi c */<br />
char* string_last_char(char *s, char c)<br />
{<br />
char *t = s;<br />
/* Pronalazimo kraj stringa s */<br />
while (*t++)<br />
;<br />
}<br />
/* Krecemo od kraja i trazimo c unazad */<br />
for (t--; t >= s; t--)<br />
if (*t == c)<br />
return t;<br />
/* Nije nadjeno */<br />
return NULL;<br />
/* Proverava da li string str sadrzi string sub.<br />
Vr<strong>ac</strong>a poziciju na kojoj sub pocinje, odnosno -1 ukoliko ga nema<br />
*/<br />
char* string_string(char *str, char *sub)<br />
{<br />
char *s, *t;<br />
/* Proveravamo da li sub pocinje na svakoj poziciji i */<br />
for (; *str; str++)<br />
/* Poredimo sub sa str pocevsi od poziciji i sve dok ne naidjemo na razliku<br />
for (s = str, t = sub; *s == *t; s++, t++)<br />
/* Nismo naisli na razliku a ispitali smo sve karaktere niske sub */<br />
9
}<br />
if (*(t+1) == ’\0’)<br />
return str;<br />
/* Nije nadjeno */<br />
return NULL;<br />
main()<br />
{<br />
char s[100];<br />
char t[] = "Zdravo";<br />
char u[] = " svima";<br />
char r[] = "r<strong>ac</strong>unari";<br />
string_copy(s, t);<br />
printf("%s\n", s);<br />
string_concatenate(s, u);<br />
printf("%s\n", s);<br />
printf("%d\n",string_char(r, ’n’) - r);<br />
printf("%d\n",string_last_char(r, ’a’) - r);<br />
printf("%d\n",string_string(r, "r<strong>ac</strong>") - r);<br />
printf("%d\n",string_string(r, "ari") - r);<br />
printf("%d\n",string_string(r, "cun") - r);<br />
printf("%p\n",string_string(r, "cna"));<br />
}<br />
10