04/10/23 1
Nizovi
• Niz je ograničen uređen skup promenljivih istog tipa, koje se nazivaju komponente. Tip komponenti se naziva bazni tip. Vrednostima pojedinih komponenti može se pristupiti pomoću indeksa, koji ukazuje koju komponentu treba obrađivati.Pri definisanju nizova treba voditi računa o dve stvari:
Treba ukazati na broj komponenti i način referisanja na komponente.
Treba ukazati na tip vrednosti koje se u njemu čuvaju.
04/10/23 2
Opis niza
• Niz se opisuje kao i ostali podaci, samo što se dodaju kvadratne zagrade iza imena niza. Unutar zagrada se navodi broj koji pokazuje broj elemenata u nizu.
• Int broj [1000] ;• Ovom deklaracijom se uvodi niz broj koji se
sastoji iz 1000 celobrojnih promenljivih sa imenima broj [0], broj [1] ... broj [999]. Indeksiranje elemenata niza je od 0. Svaka promenljiva pošto je celobrojna zauzima dva bajta.
04/10/23 3
Example No 18
• Izracunati srednju vrednost niza od n elemenata(n<50)• main()• {• int n,i;• float x[50];• printf(“Uneti broj elemenata niza”);• scanf(“%d”,&n);
for(suma=0,i=0; i<n; i++) { printf(“%3d.broj x=”,i);
• scanf(“%f”,&x[i]); suma+= x[i];
}• printf(“\Srednja vrednost je %f\n”,suma/n);• }
04/10/23 4
Example No 19• Izracunati maksimalnu vrednost u nizu od n elemenata(n<50)• main()• {• int n,i;• float x[50],xmax;• printf(“Uneti broj elemenata niza”);• scanf(“%d”,&n);
for(I=0;i<n;i++) { printf(“%3d.broj x=”,I);
• scanf(“%f”,&x[I]) }
/*Izracunava maksimalnu vrednost niza*/
• xmax=x[0];• for (I=1;I<n;I++)• if (x[I]>xmax)• xmax=x[I];• printf(“\nMaksimalna vrednost je %f\n”,xmax);• }
04/10/23 5
Example No 20• Izracunati indeks najveceg elemenata niza x od n elemenata (n<50)• main()• {• int n,i,imax;• float x[50],xmax;• printf(“Uneti broj elemenata niza”);• scanf(“%d”,&n);
for(i=0;i<n;i++) { printf(“%3d.broj x=”,i);
• scanf(“%f”,&x[i]);• {
/*Izracunava indeks maksimalne vrednosti u nizu*/ xmax=x[0];/*pretpostavljajuci da je x[0] najveca vrednost*/ imax=0;/*sacuvamo njen indeks*/ for(i=1;i<n;i++) if(x[i]>xmax)/*kada se naidje na element veci od xmax*/ {/*zamenjuje se vrednost xmax I imax*/ xmax=x[i];/*sa x[i] I indeksom i*/ imax=i; } printf(“\nIndeks maksimalne vrednosti je %d\n”,imax); }
04/10/23 6
Example No20a
DRUGO RESENJE ISKLJUCUJE UPOTREBU PROMENLJIVE XMAX:
imax=0; for(i=1;i<n;i++) if(x[i]>x[imax]) imax=i;
04/10/23 7
Inicijalizacija Nizovova• Nizovima je u C jeziku moguce dodeljivati pocetne
vrednosti. Ako se inicijalizacija ne zadaje eksplicitno niz se inicijalizuje nulom, Medjutim ako je potrebno da se niz inicijalizuje vrednostima razlicitim od nule potrebno je da se pri deklaraciji niza izmedju viticastih zagrada navedu zeljene vrednosti razdvijene zarezom.
• Int dani [12]= {31,28,31,30,31,30,31,31,30,31,30,31}• main()• {• int i;• extern int dani[ ]; /*neobavezna deklaracija*/• for (i=0; i<12; i++)• print(“Mesec%d ima%dana.\n”,i+1,dani[i]);• }• Izvrsavanjem programa se ispisuje:• Mesec 1 ima 31 dana
04/10/23 8
Nizovi i pokazivači• Ime niza ekvivalntno je adresi njegovog nultog elementa
x =&x[0], jer se u oba dela jednakosti definišu adrese nultog elementa niza.
• Na primer ako je data deklaracija• int x[4],*pti;• Dodela pti=x i ako je niz smešten počev od adrese
56006 • (&x[0]), da bi se odredile lokacije i elementi niza na
koje pokazuju pti, pti+1 pti+2pti+3. Dodavanje jedinice pokazivaču automatski povećava adresu na koju on pokazuje za 2 jer se radi pokazivaču na int tip.
04/10/23 9
Nizovi i pokazivači• Oba dela jednakosti X= &x[0] definišu adresu
nultog elementa niza. Obe oznake su konstante pokazivačkog tipa i ne mogu se menjati. Prema tome njih možemo dodeljivati pokazivačkim promenljivim.
• X+2 ==&x[2] /*jer su im iste adrese*/• • *(x+2) == x[2] /*jer su im iste
vrednosti*/• Odavde se vidi da se pokazivači mogu koristiti
za adresiranje elemenata niza , kao i za dobijanje njihove vrednosti.
•
04/10/23 10
Nizovi i pokazivači
• Kada se navede X+2 to kompajler tretira kao adresu koja se dobija dodavanjem na adresu X ne 2, već 2 puta broj baytova koje zauzimaju komponente niza X.
• U suštini se radi o različitim oznakama za jedno te isto, jer kompajler pretvara oznake niza u pokazivače , pa je brzine radi, preporučljivo koristiti pokazivače.
04/10/23 11
Ilustracija pokazivača i adresa na koje ukazuju
»pti pti+1 pti+2 pti+3 • Adresa: 56006 56007 56008 56009 56010 56011 56012 56013
• Pokazivaci • pti, pti+1, pti+2 i pti+3 • redom pokazuju na adrese:• 56006, 56008, 56010 i 56012• i elemente niza:• x[0], x[1], x[2] i x[3],
X[0]
X[0] X[1] X[2] X[3]
04/10/23 12
POKAZIVAČI NA NIZOVE
int v[ ] = {1, 2, 3,4}; /*niz */
int* p1 = v; /*pokazivač na niz odnosno uvek na prvi element niza tj. p1=&v[0] */
int* p2 = &v[1]; /*pokazivač na prvi element niza */
int* p4 = &v[3]; /*pokazivač na poslednji element
niza */
1004
v[0]
1008
v[1]
1012
v[2 ]
1016
v[3]
1020
\0
.....
2010 1004 p1
1234
1004 p2 1020 p3 for (i = 0; i<4; i++)printf("%d ", a[i]);
for (i = 0; i<4; i++)printf("%d ", p1++);
Primer
Štampa zadatog niza
Sa indeksom Sa pokazivačem
04/10/23 13
Funkcije, nizovi, pokazivači, parametri, prenošenje argumenata ...
• • Prenošenja nizova kao argumenata može se
analizirati na problemu određivanja broja studenata koji su imali natprosečne rezultate na proveri znanja iz osnova programskog jezika C.
• Algoritam ovog problema se može razložiti na sledeće module
Učitavanje vrednosti elemenata niza Izračunavanje prosečnog rezultata Prebrojavanje natprosečnih rezultata Ispis izlaznog izveštaja
04/10/23 14
Example No ….• Main()• Int n,i,broj,ocena[50]; /*niz od 50 elemenata*/• Float prosek();• Print('\nUnesi broj takmicara:');• Scan(%d',&n);• /*ucitavanje elemenata niza*/• print('\nUnesi rezultate:\n');• for (i:=0;i<n;i++)• {• print('ocena[%d]+',i);• scan('%d”,&ocena[i])• }
• To be continue…
04/10/23 15
Contnue….• /*prebrojavanje natprosecnih rezultata*/• broj=0• for(i=0;i<n;i++)• if(ocena[i]>prosek(ocena,n))• broj++;• printf(''prosecan rezultat je:%f.\n'',prosek(ocena,n));• printf (''natprosecne rezultate je imalo:%d takmicara.\
n'',broj);• }• Float prosek(int x [],int n)• {• int i,suma;• suma=0;• for(i=0;i<n;suma+=x[i],i++);• return((float)suma/n);
04/10/23 16
Funkcije, nizovi, pokazivači, parametri, prenošenje argumenata ...
• Pri definiciji funkcije prosek() koja se poziva iz main () deklaracija Int x[]
• kreira, ne niz, već pokazivač na niz• Float prosek(int x [],int n)• {• int i,suma;• suma=0;• for(i=0;i<n;suma+=x[i],i++);• return((float)suma/n);• }
04/10/23 17
Funkcije, nizovi, pokazivači, parametri, prenošenje argumenata ...
• Poziv funkcije • Prosek (ocena,n) sadrži ime ocena koje
predstavlja adresu nultog elementa od najviše 50 elemenata.
• Time se pri pozivu funkcije predaje pokazivačka konstanta (adresa nultog elementa niza)
• Ocena = &ocena[0]• • To znači da je formalni parametar funkcije
pokazivačkog tipa pa se u funkciji prosek() može izvršiti deklaracija na sledeći način
• prosek(int *x,int n)
04/10/23 18
Funkcije, nizovi, pokazivači, parametri, prenošenje argumenata ...
• Operatori • Int x [];• Int*x;• Su ekvivalentni jer oba deklarišu promenljivu x kao
pokazivač na niz celih brojeva • ... Operatori koji u funkciji prosek () koriste pokazivač *X
rade sa nizom ocena koji se nalazi u telu funkcije main() Poziv funkcije inicijalizuje pokazivač X tako da pokazuje na ocena [0] Kada index i u funkciji prosek () uzme vrednost 4 tada je izraz x [4] ekvivalentan sa *(x+4).
04/10/23 19
Funkcije, nizovi, pokazivači, parametri, prenošenje argumenata ...
• Znači pošto (x+0) pokazuje na ocena [0] to x+4 pokazuje na ocena [4] Prenos jednodimenzionalnih nizova se ostvaruje navođenjem imena niza u pozivu funkcije bez ikakvog indeksa. Na ovaj način u funkciju se prenosi informacija (adresa ) o lokaciji niza u pozivajućoj funkciji.
04/10/23 20
Funkcije, nizovi, pokazivači, parametri, prenošenje argumenata ...
• Čak i deklaracija x [100] ima isto značenje kao i x [] jer C kompajler generiše kod koji funkciji predaje pokazivač tako da je beznačajna specificirana dužina niza.
• X== &x[0] • X +0== &x[0] • X+2 ==&x[2] /*jer su im iste adrese*/• *(x+2) == x[2] /*jer su im iste vrednosti*/• *(x+i) == x[i]• Prema tome jednodimenzionalni nizovi se prenose
isključivo po adresi
04/10/23 21
Sortiranje nizova• Program kojim se korišćenjem odgovarajuće
funkcije učitani niz sortira u monotono neopadajući poredak
• Example No 21• main()• {• int• float a[50];• void citaj();• void pisi();• void sort1();• printf(“\nUneti broj elemenata niza:”);• scanf(“%d”,&n);
printf(“\nUnesi elemente niza:\n”); citaj(a,n); sortl(a,n); printf(“Niz posle sortiranja je:\n”); pisi(a,n); }
04/10/23 22
void citaj(float x[],int n) { int I; for(I=0;I<n;I++) { printf(“x[%d]=“,I); scanf(“%f”,&x[I]); } } void pisi(float x[],int n) { int I; for(I=0;I<n;I++) printf(“x[%d]=%f\n,I,x[I]); }
04/10/23 23
void razmeni(float*a,float*b) { float pom; pom=*a;*a=*b;*b=pom; } void sort(float a[],int n) { int I,j; for(I=0;I<n-1;I++) for(j=i+1;j<n;j++) if(a[i]>a[j]) razmeni(&a[I],&a[j]); } ISTI ALGORITAM SE MOGAO PRIMENITI U FUNKCIJI KOJA KORISTI
POKAZIVACE: void sortl(float*a,int n) { int I,j; for(I=0;n-1;I++) for(j=I+1;j<n;j++) if(*(a+I)>*(a+j)) razmeni(a+I,a+j); }
04/10/23 24
Višedimenzionalni nizovi
• Dvodimenzionalni nizovi se se u memoriji registruju po vrstama zauzimajući susedne memorijske lokacije.ako se dvodimezionalni niz deklariše na sledeći način:
• int a[3][2] ; njegovi elementi će biti raspoređeni na sledeći način: a [0][0] a [0][1] a [1][0] a [1][1] a [2][0] a [2][1]
• Imajući ovo u vidu, ako definišemo pokazivač na int tip• int * poki, dodelom• poki = a;• definiše pokazivačka promenljiva na element u nultoj
vrsti i koloni jer važi jednakost• a =& a [0][0]
04/10/23 25
Višedimenzionalni nizovi• Prema navedenoj deklaraciji važi:• poki =& a [0][0]• Poki+1 =& a [0][1]• Poki+2 =& a [1][0]• Poki+3 =& a [1][1]• Poki+4 =& a [2][0]• Poki+5 =& a [2][1]• U ovom primeru a je ime dvodimenzionalnog niza a, a [0], a [1], a [2]• su imena jednodimenzionalnih nizova koje predstavljaju vrste matrice.• Ime niza je pokazivač na taj niz jer pokazuje na njegov prvi element, tako
da važi:• a [0] =& a [0][0]• a [1] =& a [1][0]• a [2] =& a [2][0]
• Ova osobina nam koristi da funkciju namenjenu za obradu jednodimenzionalnog niza koristimo pri obradi vrsta dvodimenzionalnog niza.
04/10/23 26
Example No 22• main()• {• static float a[3][4]={• {1.0,2.0,3.0,4.0}, • {11.5,22.4,33.3,44.2},• {10.1,20.2,30.3,40.4}• };• int I;• float sredina();• for (I=0;I 3;I++)• printf(“srednja vrednost vrste %d je %f\n”,I,sredina(a[I],4));• /*a[I] je jednodimenzionalni niz od Četirielementa*/• }• float sredina(float x[],int n)• {• int I;• float suma;• for (I=0,suma= 0;I n;I++)• suma+=x[I]• return suma/n• }
04/10/23 27
Example No 23
• main()• {• int I,n;• int x[10][10]• void citaj();• void pisi();• void sort1();• printf(“\nUneti broj vrsta matrice:”);• scanf(“%d”,&n);
printf(“\nUnesi elemente matrice po vrstama :\n); citaj(x,n); sortl(x[I],n); printf(“matrica posle sortiranja je:\n”); pisi(x,n); }
04/10/23 28
Example No 23 /*funkcija koja ucitava elemente matrice*/ void citaj(int x[][10],int n) {
int I,j; for(I=0;I<n;I++) for(j=0;j<n;j++) {
printf(“x[%d,%d]=“,I,j); scanf(“%d”,&x[I][j]); } }
/*funkcija koja ispisuje elemente matrice*/ void pisi(int x[][10],int n) {
int I,j; for(I=0;I<n;I++) {
for(j=0;j<n;j++) printf(“%3d”,x[I][j]); printf(“\n”); } }
04/10/23 29
Example No 23
void razmeni(int*a,int*b) { float pom; pom=*a;*a=*b;*b=pom; } void sort(int a[],int n) { int I,j; for(I=0;I<n-1;I++) for(j=I+1;j<n;j++) if(a[I]>a[j]) razmeni(&a[I],a[j]); }