PROGRAMIRANJE I A 10 Pokazivai dr Draen Branin
PROGRAMIRANJE I A 10 – Pokazivači dr Dražen Brđanin Goran Banjac Danijela Zoran Igor Ševo Aleksandar Keleč (bdrazen@etfbl. net) (goran. banjac@etfbl. net) (danijela. zoran@etfbl. net) (igor. sevo@etfbl. net) (aleksandar. kelec@etfbl. net) 2014.
A 10 OPERATORI ZA RAD SA POKAZIVAČIMA Operatori za rad s pokazivačima #include <stdio. h> int main() i { short i = 10, j = 20, *p = &i; printf("Velicina: %d %d %dn", j sizeof(i), sizeof(j), sizeof(p)); printf("i=%d, adr: %p, ", i, &i); printf("j=%d, adr: %pn", j, &j); printf("*p=%d, p=%p, adr: %pn", *p, p, &p); p *p = 11; printf("i=%d, *p=%dn", i, *p); p = &j; printf("*p=%d, p=%pn", *p, p); (*p)++; printf("j=%d, *p=%dn", j, *p); Velicina: 2 2 4 return 0; } i=10, adr: 0028 FF 1 E, j=20, 0028 FF 20 h 0 0 0028 FF 1 Fh 0 A B 0028 FF 1 Eh 0 0 0028 FF 1 Dh 1 5 4 0028 FF 1 Ch 0 0 0028 FF 1 Bh 2 8 0028 FF 1 Ah F F 0028 FF 19 h 1 C E 0028 FF 18 h 0028 FF 17 h adr: 0028 FF 1 C *p=10, p=0028 FF 1 E, adr: 0028 FF 18 i=11, *p=11 *p=20, p=0028 FF 1 C j=21, *p=21 Pokazivači 2
A 10 POKAZIVAČI I STRUKTURE Pristup elementima strukture #include <stdio. h> struct datum { int dan, mjesec, godina; }; int main() { struct datum d, *p = &d; p->dan = 1; // (*p). dan = 1; p->mjesec = 1; // (*p). mjesec = 1; p->godina = 2000; // (*p). godina = 2000; printf("Datum: %02 d. %d. n", d. dan, d. mjesec, d. godina); printf("Unesite datum: "); scanf("%d %d %d", &p->dan, &p->mjesec, &p->godina); printf("Novi datum: %02 d. %d. ", p->dan, p->mjesec, p->godina); return 0; } Datum: 01. 2000. Unesite datum: 4 4 2010 Novi datum: 04. 2010. Pokazivači 3
A 10 POKAZIVAČI I POLJA Pokazivač na vektor (jednodimenzioni niz) #include <stdio. h> int main() { int niz[5] = { 1, 2, 3, 4, 5 }; int pr[10] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }; int *p = niz; printf("%d %d %dn", niz[0], niz[1], niz[2]); printf("%d %d %dn", *p, *(p + 1), *(p + 2)); printf("%d %d %dn", *niz, *(niz + 1), *(niz + 2)); printf("%d %d %dn", p[0], p[1], p[2]); p = pr + 2; p printf("%d %d %dn", p[0], p[1], p[2]); // niz = p; GRESKA niz[0] = p[0]; p[1] = niz[1]; 15 niz printf("%d %dn", niz[0], p[1]); 0 return 0; } 2 pr 0 1 1 5 5 2 2 7 2 3 3 11 2 3 4 5 1 2 3 4 3 5 72 11 13 17 19 23 29 1 2 3 4 5 6 7 8 9 p Pokazivači 4
A 10 POKAZIVAČI I POLJA Prenos vektora u funkciju pomoću pokazivača #include <stdio. h> #define MAX 100 int suma(int niz[], int n) { int i, s = 0; for (i = 0; i < n; i++) s += niz[i]; // s += *(niz + i); return s; } int main() { int i, n, niz[MAX]; do { printf("n="); scanf("%d", &n); } while (n < 1 || n > MAX); for (i = 0; i < n; i++) { printf("%d. broj: ", i + 1); scanf("%d", niz + i); // &niz[i] } printf("Suma: %d", suma(niz, n)); return 0; } Pokazivači n=3 1. broj: 5 2. broj: 1 3. broj: 9 Suma: 15 #include <stdio. h> #define MAX 100 int suma(int *niz, int n) { int i, s = 0; for (i = 0; i < n; i++) s += *(niz + i); // s += niz[i]; return s; } int main() { int i, n, niz[MAX]; do { printf("n="); scanf("%d", &n); } while (n < 1 || n > MAX); for (i = 0; i < n; i++) { printf("%d. broj: ", i + 1); scanf("%d", niz + i); // &niz[i] } printf("Suma: %d", suma(niz, n)); return 0; } 5
A 10 POKAZIVAČI I POLJA Pokazivač na matricu (dvodimenziono polje) #include <stdio. h> #define MAX 10 int main() { int i, j, n, m, mat[MAX], *p; do { printf("Dimenzije: "); scanf("%d %d", &n, &m); } while (n < 1 || n > MAX || m < 1 || m > MAX); for (i = 0; i < n; i++) for (j = 0; j < m; j++) { printf("mat[%d]=", i, j); scanf("%d", &mat[i][j]); } printf("Matrica: n"); p = mat; for (i = 0; i < n; i++, printf("n")) for (j = 0; j < m; j++) printf(" %4 d", *(p + i * MAX + j)); // printf(" %4 d", *(&mat[0][0] + i * MAX + j)); // printf(" %4 d", mat[i][j]); return 0; } Pokazivači 0 1 2 3 1 4 5 6 3 4 5 6 7 8 9 2 3 4 5 6 Dimenzije: 2 3 mat[0][0]=1 7 mat[0][1]=2 8 mat[0][2]=3 9 mat[1][0]=4 mat[1][1]=5 mat[1][2]=6 Matrica: 1 2 3 4 5 6 6
A 10 ADRESNA ARITMETIKA Adresna aritmetika *c=a *pc 1=a *(pc 1+1)=b *++pc 1=b *pc 1++=b *pc 1=c *pc 1=a pc 2 -pc 1=3 #include <stdio. h> int main() { char c[] = { 'a', 'b', 'c', 'd' }; int i[] = { 1, 2, 3, 4 }; char *pc 1 = &c[0], *pc 2 = &c[3]; int *pi 1 = &i[0], *pi 2 = &i[3]; printf("*c=%c *i=%dn", *c, *i); printf("*pc 1=%c *pi 1=%dn", *pc 1, *pi 1); printf("*(pc 1+1)=%c *(pi 1+2)=%dn", *(pc 1 + 1), *(pi 1 + 2)); printf("*++pc 1=%c *++pi 1=%dn", *++pc 1, *++pi 1); printf("*pc 1++=%c *pi 1++=%dn", *pc 1++, *pi 1++); printf("*pc 1=%c *pi 1=%dn", *pc 1, *pi 1); pc 1 -= 2; pi 1 -= 2; printf("*pc 1=%c *pi 1=%dn", *pc 1, *pi 1); printf("pc 2 -pc 1=%d pi 2 -pi 1=%dn", pc 2 - pc 1, pi 2 - pi 1); return 0; } Pokazivači *i=1 *pi 1=1 *(pi 1+2)=3 *++pi 1=2 *pi 1++=2 *pi 1=3 *pi 1=1 pi 2 -pi 1=3 7
A 10 PRENOS ARGUMENATA REFERISANJEM Napisati program koji učitava niz od n cijelih brojeva, a zatim ispisuje njihovu aritmetičku sredinu i one učitane brojeve koji su veći od sredine. Za učitavanje dimenzije i elemenata niza treba definisati i koristiti funkciju čiji je prototip: void citaj(int *niz, int *n); #include <stdio. h> #define MAX 100 void citaj(int *, int *); int main() { int i, n, niz[MAX], s = 0; double as; citaj(niz, &n); for (i = 0; i < n; i++) s += niz[i]; as = (double)s / n; printf("Sredina: %. 2 lfn", as); printf("Veci su: "); for (i = 0; i < n; i++) if (niz[i] > as) printf(" %d", niz[i]); return 0; } Pokazivači void citaj(int *niz, int *n) { int i; do { printf("n="); scanf("%d", n); } while (*n < 1 || *n > MAX); for (i = 0; i < *n; i++) n=4 { 1. broj: 3 ", i + 1); printf("%d. broj: 2. broj: scanf("%d", niz 4+ i); } 3. broj: 5 } 4. broj: 6 Sredina: 4. 50 Veci su: 5 6 8
A 10 DINAMIČKA ALOKACIJA MEMORIJE Dinamička alokacija memorije #include <stdio. h> #include <stdlib. h> int main() { int i, n, *niz; do { printf("n="); scanf("%d", &n); } while (n < 1); niz = (int *)malloc(n * sizeof(int)); for (i = 0; i < n; i++) { printf("%d. broj: ", i + 1); scanf("%d", niz + i); } printf("Niz: "); for (i = 0; i < n; i++) printf(" %d", niz[i]); free(niz); return 0; } Pokazivači #include <stdio. h> #include <stdlib. h> int* citaj(int *); int main() { int i, n, *niz; niz = citaj(&n); printf("Niz: "); for (i = 0; i < n; i++) printf(" %d", niz[i]); free(niz); return 0; } int* citaj(int *n) { int i, *niz; n=4 do { printf("n="); scanf("%d", n); } while 1. (*nbroj: < 1); 3 niz = (int *)malloc(*n * sizeof(int)); 2. broj: 12 for (i = i < *n; 3. 0; broj: 4 i++) { printf("%d. broj: ", i + 1); 4. broj: 1 scanf("%d", niz + i); } Niz: 3 12 4 1 return niz; } 9
A 10 DINAMIČKA ALOKACIJA MEMORIJE Dinamička alokacija memorije #include <stdio. h> #include <stdlib. h> int main() { int i, j, n, m, **mat, b = 0; do { printf("Dimenzije: "); scanf("%d %d", &n, &m); } while (n < 1 || m < 1); mat = (int **)calloc(n, sizeof(int *)); for (i = 0; i < n; i++) { mat[i] = (int *)calloc(m, sizeof(int)); // *(mat + i) = (int *)calloc(m, sizeof(int)); for (j = 0; j < m; j++, b++) mat[i][j] = b; // *(*(mat + i) + j) = b; } printf("Matrica: n"); Dimenzije: 3 4 for (i = 0; i < n; i++, printf("n")) for (j = 0; j < m; j++) Matrica: printf(" %4 d", mat[i][j]); // *(*(mat + i) + j)) 0 1 2 3 for (i = 0; i < n; i++) 4 5 6 7 free(mat[i]); // free(*(mat + i)); 8 9 10 11 free(mat); return 0; } Pokazivači 10
A 10 DINAMIČKA ALOKACIJA MEMORIJE Napisati program u kojem treba: • definisati tip ARTIKAL kojim se reprezentuju artikli čiji su atributi naziv, količina i cijena. • definisati funkciju koja sa standardnog ulaza učitava podatke o jednom artiklu, a čiji je prototip: void citaj(ARTIKAL *); • definisati funkciju za sortiranje niza podataka o artiklima u opadajućem redoslijedu po ukupnoj vrijednosti, a čiji je prototip: void sortiraj(ARTIKAL *, int); • definisati funkciju koja na standardni izlaz ispisuje podatake o artiklu, a čiji je prototip: void pisi(ARTIKAL *); • definisati funkciju koja ispisuje niz podataka o artiklima (koristeći funkciju pisi) u obliku RB. NAZIV a čiji je prototip: KOL. CIJENA UKUPNO void ispis(ARTIKAL *, int); • u glavnom programu: § učitati podatke za n artikala koristeći funkciju citaj i formirati odgovarajući dinamički niz, § sortirati učitani niz pomoću funkcije sortiraj, § ispisati sortirani niz pomoću funkcije ispis. Pokazivači 11
A 10 DINAMIČKA ALOKACIJA MEMORIJE Rješenje: #include <stdio. h> #include <stdlib. h> typedef struct artikal { char naziv[21]; double kol, cijena; } ARTIKAL; void citaj(ARTIKAL *); void sortiraj(ARTIKAL *, int); void pisi(ARTIKAL *); void ispis(ARTIKAL *, int); int main() { int i, n; ARTIKAL *niz; do { printf("n="); scanf("%d", &n); } while (n < 1); niz = (ARTIKAL *)malloc(n * sizeof(ARTIKAL)); for (i = 0; i < n; i++) { printf("Podaci o %d. artiklu: n", i + 1); citaj(niz + i); } sortiraj(niz, n); ispis(niz, n); free(niz); return 0; } Pokazivači 12
A 10 DINAMIČKA ALOKACIJA MEMORIJE void citaj(ARTIKAL *art) { printf(" Naziv: "); scanf("%s", art->naziv); printf(" Kolicina: "); scanf("%lf", &art->kol); printf(" Cijena: "); scanf("%lf", &art->cijena); } void sortiraj(ARTIKAL *niz, int n) { int i, j; for (i = 0; i < n - 1; i++) for (j = i + 1; j < n; j++) if (niz[i]. kol * niz[i]. cijena < niz[j]. kol * niz[j]. cijena) { ARTIKAL pom = niz[i]; niz[i] = niz[j]; niz[j] = pom; } } Pokazivači 13
A 10 DINAMIČKA ALOKACIJA MEMORIJE void pisi(ARTIKAL *art) { printf("%-20 s %6. 2 lf", art->naziv, art->kol, art->cijena, art->kol * art->cijena); } void ispis(ARTIKAL *niz, int n) { int i; printf("=== ========== printf("RB. NAZIV printf("=== ========== for (i = 0; i < n; i++) { printf("%2 d. ", i + 1); pisi(niz + i); printf("n"); } printf("=== ========== } Pokazivači ======n"); KOL. CIJENA UKUPNOn"); n=2 ======n"); Podaci o 1. artiklu: Naziv: Banane Kolicina: 1. 5 Cijena: 2 Podaci o 2. artiklu: Naziv: Jabuke Kolicina: 2. 5 Cijena: 1. 5 ======"); ============ RB. NAZIV KOL. ============ 1. Jabuke 2. 50 2. Banane 1. 50 ============ CIJENA ====== 1. 50 2. 00 ====== UKUPNO ====== 3. 75 3. 00 ====== 14
A 10 ZADACI ZA VJEŽBU 1. Napisati program koji učitava niz cijelih brojeva, a zatim ga sortira u rastućem redoslijedu. Za učitavanje niza cijelih brojeva treba definisati i koristiti funkciju čiji je prototip: void citaj(int *, int *); Za sortiranje niza cijelih brojeva treba definisati i koristiti funkciju čiji je prototip: void sort(int *, int); Za ispis niza cijelih brojeva treba definisati i koristiti funkciju čiji je prototip: void pisi(int *, int); 2. Definisati tip TACKA kojim se reprezentuje tačka u x 0 y koordinatnom sistemu (svaka tačka ima odgovarajuću slovnu oznaku, te dvije realne koordinate). Definisati tip TROUGAO kojim se reprezentuje trougao u x 0 y koordinatnom sistemu (svaki trougao čine tri tačke koje predstavljaju vrhove trougla). Napisati program koji sa standardnog ulaza učitava četiri tačke, a zatim formira trougao od prve tri tačke, i na kraju provjerava da li se četvrta tačka nalazi u tom trouglu. Za učitavanje tačke treba definisati i koristiti funkciju čiji je prototip: void citaj(TACKA *); Za formiranje trougla treba definisati i koristiti funkciju čiji je prototip: TROUGAO trougao(TACKA *); Za provjeru da li se tačka nalazi unutar trougla treba definisati i koristiti funkciju čiji je prototip: int tacka. Utrouglu(TACKA, TROUGAO); Pokazivači 15
A 10 ZADACI ZA VJEŽBU 3. Napisati program u kojem treba: • definisati tip TIM kojim se reprezentuju fudbalski timovi čiji su atributi naziv, broj postignutih i primljenih golova, te broj bodova. • definisati funkciju koja sa standardnog ulaza učitava podatke o jednom timu, a čiji je prototip: void ucitaj(TIM *); • definisati funkciju koja učitava prirodan broj n i podatke za n timova koristeći funkciju ucitaj, te formira i vraća dinamički niz, a čiji je prototip: TIM* formiraj(int *); • definisati funkciju za sortiranje niza podataka o timovima prema opadajućoj vrijednosti broja bodova (ako ima više timova sa istim brojem bodova, dodatni kriterijum za sortiranje je gol razlika). Prototip funkcije je: void sortiraj(TIM *, int); • definisati funkciju koja ispisuje sortirani niz podataka o timovima u obliku RB. NAZIV a čiji je prototip: GPO GPR GR BOD void ispisi(TIM *, int); • u glavnom programu: § učitati podatke za n timova i formirati odgovarajući dinamički niz koristeći funkciju formiraj, § sortirati učitani niz pomoću funkcije sortiraj, pa ga ispisati pomoću funkcije ispisi. Pokazivači 16
- Slides: 16