Download as pdf or txt
Download as pdf or txt
You are on page 1of 82

VI

Programirawe
vo C
Op{to za C
Programskiot jazik C e razvien nekade kon krajot na 60-tite od
strana na Denis Ri~i, so ideja da se kreira programski jazik
pogoden za pi{uvawe operativni sistemi (UNIX).
Modernite tipovi podatoci, kontrolni srukturi, golemiot broj
operatori, odli~nata "ekonomija" na izrazite go pravat C
moderen programski jazik za op{ta namena {to kreira mnogu
efikasen izvr{en kod.
Negovite ro{iruvawa vo objektnoorientirana nasoka (C++) i na-
soka za pi{uvawe aplikacii pod Windows operativni sistemi
(na primer Visual C), zaedno so negovata vrzanost za operativ-
nite sistemi go pravat najmnogu koristen jazik na dene{ninata.
Vo dene{no vreme, najgolemiot del od sistemskiot softer
prakti~no sekoga{ se pi{uva vo C ili C++, taka {to sekoj {to
saka profesionalno da se zanimava so programirawe
ednostavno mora da go poznava.

4/9/2013 D. ^akmakov KIP - 6 2


Op{to za C
C has been widely criticized, and many people are quick to show its problems
and drawbacks. But as languages come and go, C stands untouched. So, if you
write software that is going to stay for some time, do not learn "the language
of the day"; learn C.
Many people feel that C lacks the simplicity of Java, or the sophistication of
C++ with its templates and other goodies. True. C is a simple language,
without any frills. But it is precisely this lack of features that makes C adapted
as a first time introduction into a complex high-level language that allows you
fine control over what your program is doing without any hidden features.
As languages come and go, C remains. It was at the heart of the UNIX
operating system development in the seventies, it was at the heart of the
microcomputer revolution in the eighties, and as C++, Delphi, Java, and
many others came and faded, C remained, true to its own nature.
Objective C generates C, as does Eiffel and several other object-oriented
languages. Even C++ started as a pre-processor for the C compiler.

4/9/2013 D. ^akmakov KIP - 6 3


Struktura na programata
tipovi na podatoci

main ( n, v ) {
deklaracii
 prosti podatoci strukturni podatoci poka`uva~i objekti
izvr{ni naredbi
 decimalni indeksni
} celobrojni tekstualni
znakovni slogovi
datoteki

Tip Deklaracija Konstanti


celobrojni int a,vred; −2, 67822
decimalni float x, y, a, pom; 2.44, .710, 0.613299, 5.2e+10
znakoven char a, b, rez; 'a', '$', '?'
konstanti #define ime vrednost #define gravitacija 9.81

4/9/2013 D. ^akmakov KIP - 6 4


Naredba za vlez
scanf (format, v , v , Op{to
1 ...,v );
2 n za C
kade {to format e tekstualna konstanta, a v1, v2, ..., vn se poka`uva~i kon
promenlivite vo koi se ~itaat podatoci vneseni od tastaturata
Primer:
int n; float x; char t1[2], t2[8];
⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
scanf ("%f%s%4s%2d", &x, t1, t2, &n);

Oblik na podatocite Vrednost na promenlivite


4.56#AX#22#3 x=4.56 t1="AX" t2="22" n=3
12.32E−1P H#11230 x=1.232 t1="P" t2="H" n=11230
###−3.44###+1#11#0 x=−3.44 t1="+1" t2="11" n=0
11.0#33#prilog#88000 x=11.0 t1="33" t2="pril" n=0
##4.14#aa
### x=4.14 t1='aa' t2='3' n=7
##3#7

4/9/2013 D. ^akmakov KIP - 6 5


Naredba za izlez
printf (format, p1, p2, ..., pn);
kade {to format e tekstualna konstanta na formatot, a p1, p2, ..., pn se
podatocite (promenlivi ili izrazi) {to se pe~atat

Primer:
int n; float x, y; char t[4];
⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅
printf ("%2d %7.4f %7.4e%s", n, x, y, t);

Vrednost na promenlivite Oblik na pe~ateweto


n=2 x=4.5 y=1.2 t='X' #2##4.5000#1.2000E+00X#
n=122 x=−12.01 y=0.225 t='1' 122#-12.0100#2.2500E-011#
n=0 x=4.0 y=12.0 t=‘aaa ’ #0##4.0000#1.2000E+01aaa
n=444 x=0.00001 y=0.00001 t=‘3’ 444##0.0000#1.0000E−05#3
x=21230.14 y=2123.2 t=‘abba’ n=1 #1#21230.1406#2.1232E+03abba

4/9/2013 D. ^akmakov KIP - 6 6


Primeri (1)
Primer 1. Za daden decimalen broj da se otpe~ati negoviot cel i
decimalen del.
int main () {
float a, ad; int ac;
scanf("%f", &a);
ac = a;
ad = a – ac;
printf ("Celiot del e %d, a decimalniot del e %12.4f\n",ac, ad);
}
Primer 2. Daden e trocifren broj n. Da se sostavi algoritam {to }e go
pronao|a brojot m ~ii{to cifri se vo obraten redosled od cifrite na
brojot n.
int main () {
int n, m, c1, c2, c3;
scanf("%f", &n);
c1 = a/100; c2 = (a – c1*100)/10; c3 = a – c1*100 – c2*10;
m = c3*100 + c2*10 +c1;
printf ("Brojot so obratni cifri e %d\n", m);
}
4/9/2013 D. ^akmakov KIP - 6 7
Naredbi za granawa
if ( uslov) naredba; if ( uslov) { if ( uslov1 ) {
naredbi1; naredbi1
if ( uslov) naredba1 } } else if ( uslov2 ) {
else naredba2 ; else { naredbi2
naredbi2 ; } else if ( uslov3 ) {
if ( uslov) { } naredbi3
naredbi; ..........
} } else {
naredbi
}
switch ( izraz ) {
case vrednost i1: naredbi1;
case vrednost i2 : naredbi2 ;
..........
case vrednost in : naredbin ;
default naredbin+1;
}

4/9/2013 D. ^akmakov KIP - 6 8


Primeri (2)
Primer 5. Da se sostavi programa za re{avawe kvadratna ravenka.
#include <math.h>
int main () {
float a, b, c, d, x1, x2;
printf("Vnesi koeficienti na kv. ravenka:\n"); scanf("%f%f%f", &a, &b, &c);
x1 = -b/(2*a);
d = b*b – 4*a*c;
x2 = sqrt(abs(d))/(2*a);
if (d >= 0) printf ("Realni resenija: %8.2f, %8.2f\n", x1+x2, x1-x2);
else printf ("Kompleksni resenija: %8.2f+%8.2fi, %8.2f-%8.2fi\n", x1, x2, x1, x2);
}
Primer 6. Da se v~itaat dva celi broja m i n i otpe~ati nivniot zbir ako
dvata se parni i nivniot proizvod ako dvata se neparni.
int main () {
int m, n;
printf("Vnesi 2 celi broja:\n"); scanf("%d%d", &m, &n);
if (m%2 == 0 && n%2 == 0) printf ("%d\n", m+n);
else if (m%2 == 1 && n%2 == 1) printf ("%d\n", m*n);
}
4/9/2013 D. ^akmakov KIP - 6 10
Primeri (3)
Primer 7. Da se v~itaat koordinati na to~ka vo ramninata i otpe~ati kvadrantot
vo koj taa se nao|a.
int main () {
float x, y; int kv;
printf("Vnesi koordinati na tocka vo ramninata:\n"); scanf("%f%f", &x1, &x2);
if (x > 0 && y > 0) kv = 1;
else if (x < 0 && y > 0) kv = 2;
else if (x < 0 && y < 0) kv = 3;
else if (x > 0 && y < 0) kv = 4;
else kv = 5;
if (kv <= 4) printf ("Tockata e vo %d-i kvadrant.\n", kv);
else printf ("Tockata e na koordinatna oska.\n");
}
Primer 8. Da se v~itaat koordinati na dve to~ki vo ramninata i otpe~ati nivnoto
rastojanie ako se vo ist kvadrant, a vo sprotivno sumata na rastojanija do (0,0).
#include <math.h>
int main () {
float x1, y1, x2, y2, d;
printf("Vnesi koordinati na 2 tocki:\n"); scanf("%f%f%f%f", &x1, &y1, &x2, &y2);
if (x1*x2 > 0 && y1*y2 > 0) d = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
else d = sqrt(x1*x1 + y1*y1) + sqrt(x2*x2 + y2*y2);
printf ("d = %12.2f\n", d);
}
4/9/2013 D. ^akmakov KIP - 6 11
Naredbi za povtoruvawa
while ( uslov) naredba; Naredbata ili naredbite vo
blokot while se povtoruvaat s#
while ( uslov) { dodeka e ispolnet uslovot, t.e.
naredbi; dodeka toj ima vrednost true. Jasno
} e deka me|u naredbite vo blokot
mora da postoi barem edna {to
vlijae na vrednosta na uslovot.

for ( izraz1; izraz 2 ; izraz3 ) naredba;


for ( izraz1; izraz 2 ; izraz3 ) {
naredbi;
}
izraz1 obi~no ja zadava po~etnata vrednost
na nekoja promenliva, izraz2 e uslovot za
kraj na ciklusot i izraz3 e onoj {to treba
da dovede do ispolnuvawe na uslovot za kraj

4/9/2013 D. ^akmakov KIP - 6 12


Primeri (1)
Primer 9. Da se otpe~ati n-tiot broj na Fibona~i (F1 = F2 = 1; Fi = Fi-1 + Fi-2).
int main () {
A pair of rabbits are
long f1, f2, f3; int n, i; put in a field and, if
printf ("Koj broj na Fibonaci go sakas: "); rabbits take a month
scanf("%d", &n); to become mature
Fibonacci
f1 = f2 = 1; (Leonardo of Pisa)
and then produce a
for (i=3; i<=n; i++) { new pair every
f3 = f1 + f2; f1 = f2; f2 = f3; month after that,
} how many pairs will
there be in twelve
printf ("%d-tiot broj na Fibonaci e %ld\n", n, f3);
} 1175 – 1250 months time?
Primer 10. Da se sostavi programa za nao|awe na NZS za dva celi broja.
int main () {
int m, n, i, pom;
printf ("Vnesi dva celi broja:\n");
scanf("%d%d", m, n);
if (m > n) { pom = m; m = n; n = pom; }
for (i=n; i%m != 0; i=i+n); // i=n; while (i%m != 0) i = i + n;
printf ("NZS = %d\n", i);
}
4/9/2013 D. ^akmakov KIP - 6 13
Primeri (2)
Primer 11. Da se izbrojat delitelite za v~itan cel broj n.
int main () {
int n, i, bdel;
printf ("Vnesi cel broj: ");
scanf("%d", &n);
bdel = 0;
for (i=2; i<=n/2; i++) if (n%i == 0) bdel++;
if (bdel == 0) printf ("Brojot %d e prost.\n", n);
else printf ("Brojot %d ima %d deliteli.\n", n, bdel);
}

Primer 12. Da se sostavi programa za razlo`uvawe broj na prosti mno`iteli.


int main () {
int n, i;
printf ("Vnesi cel broj: ");
scanf("%d", n);
while (n > 1) {
for (i=2; n%i != 0; i++); // i=2; while (n%i != 0) i++;
printf ("%d ", i);
n = n/i;
}
}
4/9/2013 D. ^akmakov KIP - 6 14
Primeri (3)
Primer 13. Da se najdat site broevi me|u m i n delivi so sumata na svoite cifri.
int main () {
int m, n, s, i, br;
printf ("Vnesi 2 celi broja (m,n):\n");
scanf("%d%d", &m, &n);
for (i=m; i<=n; i++) {
s = 0; br = i;
while (br > 0) { s = s + br%10; br = br/10; )
if (i%s == 0) printf ("%d ", i);
}
}

Primer 14. Da se najde prviot prost broj pogolem od n.


int main () {
int n, i, j, bdel;
printf ("Vnesi cel broj: ");
scanf("%d", &n);
for (i=n+1; ; i++) {
for (j=2; i%j !=0 && j<=i/2; j++);
if (j > i/2) { printf ("Prviot prost broj pogolem od %d e %d.\n", n, i); exit(1); }
}
}

4/9/2013 D. ^akmakov KIP - 6 15


Primeri (4)
Primer 15. Da se sostavi tabela za pretvorawe na miqi vo kilometri i
obratno.
kilometri milji
int main () { ----------------------------------
float km, ml, maxkm; 1.0000 0.6214
1.6093 1.0000
printf ("Do koj kilometar: "); 2.0000 1.2428
scanf("%f", &maxkm); 3.0000 1.8641
3.2187 2.0000
printf (" Kilometri Milji\n"); … …
printf ("-----------------------------------\n");
km = ml = 1;
while (km <= maxkm) {
if (km < ml*1.6903) {
printf ("%12.4f%12.4f\n", km, km/1.6093); km++;
}
else {
printf ("%12.4f%12.4f\n", ml*1.6093, ml); ml++;
}
}
}

4/9/2013 D. ^akmakov KIP - 6 16


Koristewe indeksirani
promenlivi
a0, a1, a2, …, an Nizite se memoriraat vo sosedni me-
moriski lokacii. Za razlika od drugi
tip ime[k]; na primer: programaki jazici, vo C nizite zapo~ -
int z[1000]; float vr[100]; nuvaat so indeks 0. Na primer, na ele-
double a[10]; char t[9];
mentite na nizata vr[100] }e i se obra-
}ame so vr[0], vr[1], vr[2], …, vr[99].
d

a1 a2 a3 . . . an-1 an

l0 l1=l0+d l2=l1+2d ln=l1+n⋅d


d = 4 bajti (int); d = 8 bajti (long); d = 8 bajti (float); d = 16 bajti (double)

Za tekst: char t1[10]; strcpy (t1, "Fakultet.");


t1[0] t1[1] t1[2] t1[3] t1[4] t1[5] t1[6] t1[7] t1[8] t1[0]
F a k u l t e t . \0

4/9/2013 D. ^akmakov KIP - 6 17


Primeri (1)
Primer 16. Da se najde najgolemiot i najmaliot element vo nizata a1, a2, …, an
i presmeta nejzinata suma i proizvod.
int main () {
int n, i; float a[1000], max, min, sum, pr;
printf ("Kolku elementi ima nizata: "); scanf("%d", &n);
printf ("Vnesi gi elementite na nizta:\n");
for (i=1; i<=n; i++) scanf("%f", &a[i]);
max = min = a[1];
for (i=2; i<=n; i++) if (max < a[i]) max = a[i];
else if (min > a[i]) min = a[i];
sum = 0;
pr = 1;
for (i=1; i<=n; i++) {
sum = sum + a[i]; // sum += a[i];
pr = pr * a[i]; // pr *= a[i];
}
printf ("Najgolem: %12.2f, najmal: %12.2f, suma: 14.2f, proizvod: %15.2f.\n",
max, min, sum, pr);
}

4/9/2013 D. ^akmakov KIP - 6 18


Primeri (2)
Primer 17. Da se ufrli elementot y na k-to mesto vo nizata x1, x2, …, xn.
int main () {
int n, k, i; float x[1000], y;
printf ("Kolku elementi ima nizata: "); scanf("%d", &n);
printf ("Vnesi gi elementite na nizta:\n");
for (i=1; i<=n; i++) scanf("%f", &x[i]);
printf ("Vnesi go elementot i mestoto na koe se ufrla:\n"); scanf("%f%d", &y, &k);
for (i=n; i>=n; i--) x[i+1] = x[i]; x[k] = y;
for (i=1; i<=n+1; i++) printf("%f ", x[i]);
}
Primer 18. Da se izbri{e k-tiot element od nizata x1, x2, …, xn.
int main () {
int n, k, i; float x[1000];
printf ("Kolku elementi ima nizata: "); scanf("%d", &n);
printf ("Vnesi gi elementite na nizta:\n");
for (i=1; i<=n; i++) scanf("%f", &x[i]);
printf ("Vnesi go redniot broj na elementot:\n"); scanf("%d", &k);
for (i=k; i<=n-1; i++) x[i] = x[i+1];
for (i=1; i<=n-1; i++) printf("%f ", x[i]);
}
4/9/2013 D. ^akmakov KIP - 6 19
Primeri (3)
Primer 19. Da se sortira nizata a1, a2, …, an..
int main () {
int n, i, ind; float a[1000], pom;
printf ("Kolku elementi ima nizata: "); scanf("%d", &n);
printf ("Vnesi gi elementite na nizta:\n");
for (i=1; i<=n; i++) scanf("%f", &a[i]);
ind = 1;
while (ind) {
ind = 0;
for (i=1; i<=n-1; i++)
if (a[i] > a[i+1]) {
pom = a[i];
a[i] = a[i+1];
a[i+1] = pom;
ind =1;
}
}
for (i=1; i<=n; i++) printf ("%f ", x[i]);
}

4/9/2013 D. ^akmakov KIP - 6 20


Primeri (4)
Primer 20. Barawe element y vo sortirana niza x1, x2, …, xn.
int main () {
int n, i; float x[1000], y;
printf ("Kolku elementi ima nizata: "); scanf("%d", &n);
printf ("Vnesi gi elementite na nizta:\n"); for (i=1; i<=n; i++) scanf("%f", &x[i]);
printf ("Vnesi go elementot sto se bara:"); scanf("%f", &y);
x[n+1] = 9999999999.; for (i=1; y>x[i]; i++);
if (y == x[i]) printf("Elementot %f e na %d-to mesto vo nizata.\n", y, i);
else printf("Elementot %f ne e vo nizata.\n", y);
}
Primer 21. Binarno barawe element y vo sortirana niza x1, x2, …, xn.
int main () {
int n, i, d, g; float x[1000], y;
printf ("Kolku elementi ima nizata: "); scanf("%d", &n);
printf ("Vnesi gi elementite na nizta:\n"); for (i=1; i<=n; i++) scanf("%f", &x[i]);
printf ("Vnesi go elementot sto se bara:"); scanf("%f", &y);
d = 1; g = n;
while (d <= g) { i = (d+g)/2;
if (y = x[i]) { printf("Elementot %f e na %d-to mesto vo nizata.\n", y, i); exit(1); }
else if (y < x[i]) g = i – 1;
else d = i + 1; }
printf("Elementot %f ne e vo nizata.\n", y);
}
4/9/2013 D. ^akmakov KIP - 6 21
Primeri (5)
Primer 22. Da se sostavi niza b1, b2, …, bk od onie elementi na nizata a1, a2,
…, an. koi{to zadovoluvaat daden uslov.

int main () {
int n, i, k; float a[1000], b[1000];
printf ("Kolku elementi ima nizata: "); scanf("%d", &n);
printf ("Vnesi gi elementite na nizta:\n");
for (i=1; i<=n; i++) scanf("%f", &a[i]);
k = 0;
for (i=1; i<=n-1; i++)
if (a[i] go zadovoluva uslovot da odi vo nizata b) {
k++;
b[k] = a[i];
}
for (i=1; i<=k; i++) printf ("%f ", b[i]);
}

4/9/2013 D. ^akmakov KIP - 6 22


Primeri (6)
Primer 23. Da se najde dijametarot na mno`estvo to~ki vo ramninata
dadeni so svoite koordinati (x1, y1), (x2, y2), …, (xn, yn) .
#include <math.h>
int main () {
int n, i, j, l1, l2; float x[1000], y[1000], d, dij;
printf ("Kolku tocki imate: "); scanf("%d", &n);
printf ("Vnesi gi koordinatite na tockite:\n");
for (i=1; i<=n; i++) scanf("%f%f", &x[i], &y[i]);
dij = -99999999999999.;
for (i = 1; i <= n-1; i++)
for (j = i+1; j <= n; j++) {
d = sqrt((x[j]-x[i])*(x[j]-x[i]) + (y[j]-y[i])*(y[j]-y[i]));
if (d > dij) { dij = d;
l1 = i;
l2 = j;
}
printf ("Dijametarot na mno`estvoto e %12.2f dobien za tockite (%10.2f, %10.2f) i
(%10.2f, %10.2f).\n", dij, x[l1], y[l1], x[l2], y[l2]);
}

4/9/2013 D. ^akmakov KIP - 6 23


Koristewe poka`uva~i (1)
• Poka`uva~ite se promenlivi koi{to sodr`at memoriski adresi
na drugi promenlivi.
• Poka`uva~ite ponekoga{ se neophodni za efikasna realizacija
na programskite tehniki, kako {to e na primer, rabotata so
dinami~kite strukturi na podatoci, listite i steblata na koi
tuka nema da se zadr`uvame.
• Deklariraweto na promenlivite od tip poka`uva~ se pravi so
stavawe * pred promenlivata. Na primer, naredbite
int *a, *b;
double *pp;
deklariraat poka`uva~i a i b kon celobrojni promenlivi i poka`uva~
pp kon decimalna promenliva so dvojna preciznost. Ako x e decimalen
broj so dvojna preciznost toga{ mo`e da se stavi
pp = &x;
• Unarniot operator & ednostavno ja dava adresata na objektot
pred koj stoi i mo`e da se koristi samo za promenlivi.
Konstrukciite kako &(x+1) ili &12 se pogre{ni.

4/9/2013 D. ^akmakov KIP - 6 24


Koristewe poka`uva~i (2)
• Unarniot operator * ja dava sodr`inata na lokacijata na koja
poka`uva poka`uva~ot {to go sledi. Taka
y = *pp;
sodr`inata na promenlivata x ja stava vo promenlivata y kako da
e izvr{ena naredbata y = x. Toa zna~i deka poka`uva~ so * pred
nego mo`e da se koristi kako promenliva vo najrazli~ni izrazi:
*pp = 12.999999;
z =*pp +1;
u = sin( *pp);
printf("%f ", *pp);
• Se razbira, mo`no e manipulirawe so poka`uva~ite kako
promenlivi. Taka po naredbata
b = a;
b }e poka`uva kon istata lokacija kako i a.

4/9/2013 D. ^akmakov KIP - 6 25


Primer (1)
#include <stdio.h>
int main() {
int broj, *br; Brojot 99 so vrednost 99 ima adresa 1245032
br = &broj;
*br = 99;
printf("Brojot %d so vrednost %d ima adresa %d", broj, *br, br);
}

4/9/2013 D. ^akmakov KIP - 6 26


Primer (stringovi) (2)
• Vo C tekstualnite nizi se pretstavuvaat preku nizi bajtovi
{to zavr{uvaat so nulti bajt simboli~ki pretstaven so ‘\0’.
Na primer so:

char *name = "lcc-win32";

vo memorijata }e imame:

l c c - w i n 3 2 \0
108 99 99 45 119 105 110 51 50 0

Na sekoja pozicija od nizata simboli memorijata sodr`i broj:


ASCII kod na simbolot. Nizata zavr{uva so 0-bajt. 0-ta ne e
ASCII simbol, i ne mo`e da se pojavuva vo nizi simboli, pa toa
zna~i deka nizata tamu zavr{uva.

4/9/2013 D. ^akmakov KIP - 6 27


Primer (stringovi) (2)
int main() {
char prv[15], vtor[15]; int i=0;
printf("Zbor 1: "); scanf("%s", prv);
printf("Zbor 2: "); scanf("%s", vtor);
while(prv[i]==vtor[i])
if(prv[i++]=='\0') { printf("Zborovite se isti.\n"); exit(1); }
printf("Zborovite se razlikuvaat (simbolite %c i %c).\n", prv[i], vtor[i]);
}

int main() {
char prv[15], vtor[15], *z1, *z2; Zbor 1: Pero
printf("Zbor 1: "); scanf("%s", prv); Zbor 2: Petre
printf("Zbor 2: "); scanf("%s", vtor); Zborovite se razlikuvaat (simbolite r i t).
z1 = prv; z2 = vtor;
for(; *z1==*z2; z1++, z2++)
if(*z1=='\0') { printf("Zborovite se isti.\n"); exit(1); }
printf("Zborovite se razlikuvaat (simbolite %c i %c).\n", *z1, *z2);
}

4/9/2013 D. ^akmakov KIP - 6 28


VI
Programirawe
vo C (II)
Rabota so datoteki (1)
A B C D ... EOF

Po~etok Kraj
Tekovna pozicijata
Rabotata so datoteki e edna od najva`nite mo`nosti vgradena vo pro-
gramskite jazici. Vo programite datotekata se razgleduva kako niza
logi~ki zapisi so po~etok i kraj (EOF = "end of file") pri {to sekoga{
postoi edna tekovna pozicija od koja se ~ita ili vo koja se zapi{uva
sledniot logi~ki zapis.
Vo programata se deklarira poka`uva~ kon datotekata:
FILE *ime; na primer: FILE *pod, *ff;

i taa se otvora:
ime = fopen ("fizi~ko ime na datekata", "vid na otvorawe");
na primer: Ime na disk Se otvora za
pod = fopen ("Podatoci.txt", "r+"); ~itawe i dodavawe
if (pod == NULL) printf ("Ne moze da se otvori datotekata Podatoci.dat !!!\n);

4/9/2013 D. ^akmakov KIP - 6 2


Rabota so datoteki (2)
Po otvoraweto, poka`uva~ot kon datotekata se postavuva na po~et-
niot bajt. ^itaweto podatok vo promenlivata x se pravi so
char x; ...
fgetc(ime, x); ili fscanf(ime, "%c", &x);,

Pove}e podatoci odedna{ mo`e da se v~itaat so:


fscanf(ime, "%c%c%...%c", &x1, &x2, ..., &xn);

Za proverka dali sme stignale do krajot na datotekata, operaciite na


~itawe se sporeduvaat so EOF pri {to vrednosta e true ako sme na
krajot na datotekata. Slednava programska {ema ~ita simbol po
simbol od datotekata ime i go obrabotuva (~esto koristena {ema).

while ((x = fgetc(ime)) != EOF) { while ((x = fscanf(ime, "%c", x)) != 1) {


obraboti go x; ili obraboti go x;
} }

4/9/2013 D. ^akmakov KIP - 6 3


Rabota so datoteki (3)
• Datotekite na standarden vlez (obi~no tastatura) i
standarden izlez (obi~no monitor) gi imaat imiwata stdin i
stdout. So startuvaweto na programata, ovie datoteki
zaedno so stderr avtomatski se otvoraat od strana na
operativniot sistem
• Sekoja naredba bez zadadena datoteka, ~ita od i zapi{uva vo
datotekite stdin i stdout soodvetno
• Postojat analogni funkcii na getc() i putc() {to namesto od
proizvolnna datoteka, ~itaat i pi{uvaat na stdin i stdout.
Tie se nare~eni getchar() i putchar() i se ednostavno definirani
so
#define getchar() getc(stdin)
#define putchar(c) putc(c, stdout))

4/9/2013 D. ^akmakov KIP - 6 4


Rabota so datoteki (4)
Osnovni naredbi:
Funkcija Zna~ewe
fgetc(f, ...), getc(f), fscanf(f, ...),
fgets(..., f), fputc(f, ...), putc(…, f), ~itawe i pi{uvawe
fprintf(f, ...), fputs(..., f)
otvorawe (r - ~itawe, w - pi{uvawe, + -
fopen("ime", "vid"), fclose(f) dodavawe pri {to e mo`na i kombinacija
na ovie simboli) i zatvorawe na datoteka
feof(f), ferror(f) proverka za kraj i gre{ka
fseek(f, n, pos) pozicionirawe na n-ti bajt
ftell(f) tekovna pozicija

Slednava programska {ema kopira datoteka vlez vo datoteka izlez:

FILE *vlez, *izlez;


int x;
vlez = fopen ("vl.dat", "r");
izlez = fopen ("iz.dat", "w");
while ((x = fgetc(vlez)) != EOF) fputc(x, izlez);

4/9/2013 D. ^akmakov KIP - 6 5


Primeri (1)
Primer 1. Vo tocki.d zapi{ani se koordinati na nepoznat broj to~ki od
ramninata. Da se sostavi programa {to }e ja presmetuva to~kata {to e prosek
na koordinatite na to~kite i soodvetnite disperzii.
#include <stdio.h>
#include <math.h>
int main() {
FILE *fp; int n; float x, y, xp, yp, xdis, ydis;
if((fp = fopen("tocki.d","r+"))==NULL) { printf("Ja nema datotekata Tocki.d !\n");
exit(1); }
n = xp = yp = xdis = ydis = 0; tocki.d
fscanf (fp, "%f%f", &x, &y); 1. 2.
while ( !feof(fp) ) { xp += x; yp += y; n++; 2. 3.
fscanf (fp, "%f%f", &x, &y); }
xp = xp/n; yp = yp/n; 3. 3.
n = 0; rewind(fp); // ili fseek(fp, 0l, 0l);
fscanf (fp, "%f%f", &x, &y); Centralnata tocka e ( 2.00, 2.67)
while ( !feof (fp) ) { so disperzija ( 0.82, 0.47).
xdis += (x - xp)*(x - xp); ydis += (y -yp)*(y - yp); n++;
fscanf (fp, "%f%f", &x, &y); }
xdis = sqrt(xdis/n); ydis = sqrt(ydis/n);
printf("Centralnata tocka e (%12.2f,%12.2f) so disperzija (%12.2f,%12.2f).", xp, yp, xdis, ydis);
}
4/9/2013 D. ^akmakov KIP - 6 6
Primeri (2)
Primer 2. Da se sostavi programa za broewe na znaci vo datoteka.

#include <stdio.h>
int main(int argc, char *argv[]) {
int c, count=0;
FILE *infile;
if (argc < 2) {
printf("Koristi: ime <datoteka >\n"); exit(1);
}
if ((infile = fopen(argv[1],"r"))==NULL) {
printf("Ja nema datotekata %s !\n",argv[1]); exit(1);
} Ako programata se narekuva
c = fgetc(infile); pr2.c, a izvr{nata programa
while (c != EOF) { pr2.exe, toga{:
count++;
c = fgetc(infile); C:\LCPP\KIP\LCC> pr2 pr2.c
} Brojot na simboli e 492.
printf("Brojot na simboli e %d.\n",count); go dava brojot na simboli vo
} na{ata programa.
4/9/2013 D. ^akmakov KIP - 6 7
Primeri (3)
Primer 2. Da se pronajde zborot so najgolema dol`ina vo tekstot
zapi{an vo datotekata pismo.txt.
#include <stdio.h>
#include <string.h>
int main() {
FILE *txt; int l, ml; char s, zbor[20], mzbor[20];
If ( (txt = fopen("pismo.txt","r+")) == NULL)
{ printf("Ne moze da se otvori datotekata PISMO.TXT !\n");
exit(); }
l = ml = 0;
s = getc(txt); // ili fscanf(txt, "%c", &s);
while ( !feof(txt) ) {
if (s==' ' || s==',' || s=='.' || s==';' || s=='!' || s=='?' || s==':' || s=='\n') {
zbor[l] = '\0'; // simbol za kraj na zbor
if (ml < l) { ml = l; strcpy(mzbor, zbor); }
printf("%d ", l); l = 0;
} else { zbor[l] = s; l++; }
s = getc(txt);
}
fprintf(txt, "Najdolgiot zbor e '%s' so %d simboli.", mzbor, ml);
}
4/9/2013 D. ^akmakov KIP - 6 8
Primeri (3)
pismo.txt
Hi Younes,

I make preparations for my stay in Oxford, (about 40 days), so I will not be


in Skopje until 1st September. I know that you also use August for your vacation
(in Maroco?). Could you inform me about our paper submited to the Revue
d'intelligence artificielle. Do we have any response? I am still waiting response
from the second paper submited to the journal of PAA in UK.

Regards from: Dusan


Najdolgiot zbor e 'd'intelligence' so 14 simboli.

Na ekranot }e se otpe~ati:
2 6 0 0 1 4 12 3 2 4 2 6 0 6 2 5 0 2 1 4 3 2 2 6 5 3 9 0 1 4 4 3 4 3 6 3 4 8 0
3 6 1 0 5 3 6 2 5 3 5 8 2 3 5 0 14 12 0 2 2 4 3 8 0 1 2 5 7 8 0 4 3 6 5 8 2 3
72322007405

4/9/2013 D. ^akmakov KIP - 6 9


Primeri (4)
Primer 3. Da se otpe~ati frekvencijata na pojavuvawe na simbolite
vo datoteka.
#include <stdio.h>
#include <string.h>
int Frequencies[256]; // Tabela na frekvencii
int main() {
int c, count=0; char ime[15]; FILE *in;
printf("Datoteka: "); scanf("%s", ime);
if ((in = fopen(ime,"rb")) == NULL) { printf("Ja nema datotekata %s !\n",ime);
exit(1);
}
c = fgetc(in);
while (c != EOF) {
count++;
if (c >= ‘ ‘) Frequencies[c]++;
c = fgetc(in);
}
fclose(in);
printf("%d simboli vo %s.\n", count,ime);
for (count=0; count<256;count++)
if (Frequencies[count] != 0)
printf("%3c (%4d) = %d\n", count, count, Frequencies[count]);
}
4/9/2013 D. ^akmakov KIP - 6 10
Primeri (4)
605 simboli vo freq.c.
( 32) = 68 ; ( 59) = 17 e ( 101) = 31
! ( 33) = 3 < ( 60) = 3 f ( 102) = 14
" ( 34) = 12 = ( 61) = 11 g ( 103) = 3
# ( 35) = 2 > ( 62) = 3 h ( 104) = 4
% ( 37) = 7 D ( 68) = 1 i ( 105) = 35
' ( 39) = 2 E ( 69) = 2 k ( 107) = 3
( ( 40) = 18 F ( 70) = 6 l ( 108) = 6
) ( 41) = 18 I ( 73) = 1 m ( 109) = 8
* ( 42) = 1 J ( 74) = 1 n ( 110) = 38
+ ( 43) = 6 L ( 76) = 3 o ( 111) = 18
, ( 44) = 9 N ( 78) = 1 p ( 112) = 5
. ( 46) = 3 O ( 79) = 1 q ( 113) = 4
/ ( 47) = 2 T ( 84) = 1 r ( 114) = 13
0 ( 48) = 3 U ( 85) = 1 s ( 115) = 12
1 ( 49) = 2 [ ( 91) = 5 t ( 116) = 27
2 ( 50) = 2 \ ( 92) = 3 u ( 117) = 16
3 ( 51) = 1 ] ( 93) = 5 v ( 118) = 2
4 ( 52) = 1 a ( 97) = 13 w ( 119) = 1
5 ( 53) = 3 b ( 98) = 3 x ( 120) = 1
6 ( 54) = 2 c ( 99) = 29 { ( 123) = 3
: ( 58) = 1 d ( 100) = 7 } ( 125) = 3

4/9/2013 D. ^akmakov KIP - 6 11


Primeri (5)
Primer 5. Da se pronajde daden zbor i zameni so drug vo datotekata d1.txt.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
FILE *d1, *d2; char s, zbor[15], zamena[15]; int i, j, m, n, k, lok[100];
printf("Zbor: "); scanf("%s",zbor); printf("Zamena: "); scanf("%s",zamena);
m = strlen(zbor); n = strlen(zamena);
if ((d1=fopen("d1.txt","r"))==NULL) { printf("Ne moze da se otvori d1.txt !!!\n"); exit(1); }
i = j = k = 0; s = fgetc(d1); i++;
while(!feof(d1)) {
while (zbor[j]==s && j<=m) {
j++; if(j==m) lok[++k] = i-m+1;
s = fgetc(d1); i++;
}
j=0; s = fgetc(d1); i++;
}
lok[k+1]=i; rewind(d1);
if ((d2=fopen("d2.txt","w"))==NULL) { printf("Ne moze da se otvori d2.txt !!!\n"); exit(1); }
for (j=1; j<lok[1]; j++) { s=fgetc(d1); fputc(s,d2); }
for (i=1; i<=k; i++) {
for (j=1; j<=m; j++) s=getc(d1);
for (j=0; j<n; j++) putc(zamena[j],d2);
for (j=lok[i]+m; j<lok[i+1]; j++) { s=getc(d1); putc(s,d2); }
}
}

4/9/2013 D. ^akmakov KIP - 6 12


Primeri (5)
d1.txt
Dear Prof. Bennani
I arrive in Paris at 01 June and from 02 June (Friday) I will be accommodated in
Cite Universitaire (Fondation Abreu de Grancher). In this moment I do not know the
phone number of my room, but you can obtain the phone number from reception
(tel: 01 44 16 82 93).
It would be nice if you inform me (by phone because I will not have access to
Internet) when is most appropriate time for you to meet me at LIPN. For me, every
day from 05 June (Monday) is ok.
Best Regards: Dusan
Po izvr{uvaweto na programata za Zbor: phone i Zamena: tel. se dobiva d2.txt:
d2.txt
Dear Prof. Bennani
I arrive in Paris at 01 June and from 02 June (Friday) I will be accommodated in
Cite Universitaire (Fondation Abreu de Grancher). In this moment I do not know the
tel. number of my room, but you can obtain the tel. number from reception (tel: 01
44 16 82 93).
It would be nice if you inform me (by tel. because I will not have access to
Internet) when is most appropriate time for you to meet me at LIPN. For me, every
day from 05 June (Monday) is ok.
Best Regards: Dusan
4/9/2013 D. ^akmakov KIP - 6 13
Koristewe indeksirani
promenlivi od povisok red
a11 a1,2  a1,n  Elementite od nizite mo`e da
,
a  bidat novi nizi, {to vodi do
a  a nizi so dimenzii 2, 3, 4 itn.
 2,1 2,2 2,n 
    (pove}edimenzionalni nizi).
a m,1 a m,2  a m,n 
  Od poseben interes se nizite
so dimenzija 2, bidej}i preku
tip ime[m][n]; na primer: niv se pretstavuvaat poznati-
int z[1000][2]; float vr[100][100]; te matemati~ki objekti, matri-
double a[10][10][10]; char t[9][25];
cite i determinantite.

Primer na inicijalizacija:
int denm[2][13] = {
(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
(0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
};

4/9/2013 D. ^akmakov KIP - 6 14


Primeri (1)
Primer 1. Da se najdat sumite na elementite po glavnata i sporednata di-
jagonala kako i vo dolniot desen triagolnik na kvadratna matrica A(n×n).

int main () {
FILE *mat; int n, i, j; float a[100][100], sg, ss, sddtr;
if ((mat = fopen("mat.dat", "r")) == NULL) {
printf ("Ne moze da se otvori datotekata mat.dat !!! "); mat.dat
exit (1); }
4
fscanf (mat, "%d", &n);
for (i=1; i<=n; i++) 1. 2.1 0.5 6.44
for (j=1; j<=n; j++) scanf(mat, "%f", &a[i][j]); 2.0 4.90 3.1 -12.80
sg = ss = sddr = 0; 3.3 -6.2 10.0 5
for (i=1; i<=n; i++) { sg = sg + a[i][i]; .20 2.2 20.5 8.80
ss = ss + a[n-i+1][i]; }
for (i=1; i<=n; i++)
for (j=1; j<=n; j++) if (i < j) sddr = sddr + a[i][j]; Sumite se:
printf ("Sumite se:\nsg = %12.2f\nss = %12.2f sg = 24.70
\nsddtr = %12.2f\", sg, ss, sddtr); ss = 3.45
} sddtr = 33.7
4/9/2013 D. ^akmakov KIP - 6 15
Primeri (2)
Primer 2. Dadena e matrica A(m×n). Da se sostavi nova matrica B(m×n)
dobiena taka {to od sekoja kolona na matricata A se odzeme najmaliot
element vo kolonata.
#include <stdio.h>
int main () {
FILE *mm; int m, n, i, j; float a[100][100], b[100][100], min;
if ((mat = fopen("mat.dat", "r")) == NULL) { mat.dat
printf ("Ne moze da se otvori datotekata mat.dat !!!\n");
exit (1); }
34
fscanf (mm, "%d%d", &m, &n); 1. 2.1 0.5 6.44
for (i=1; i<=m; i++) 2.0 4.90 3.1 -12.80
for (j=1; j<=n; j++) scanf(mm, "%f", &a[i][j]); 3.3 -6.2 10.0 5
for (i=1; i<=n; i++) {
min = a[1][i]; 0.00 8.30 0.00 19.24
for (j=1; j<=m; j++) if (a[j][i] < min) min = a[j][i]; 1.00 11.10 2.60 0.00
for (j=1; j<=m; j++) b[j][i] = a[j][i] - min; 2.30 0.00 9.50 17.80
}
for (i=1; i<=m; i++) {
for (j=1; j<=n; j++) fprintf(mm, "%6.2f", a[i][j]); printf("\n");
}
}
4/9/2013 D. ^akmakov KIP - 6 16
Primeri (3)
Primer 3. Vo dadena matrica A(m×n) da se zameni sekoj element so sumata
na negovite dijagonalni sosedi (ako gi ima).
mat.dat
#include <stdio.h> 34
int main () {
FILE *mat; int m, n, i, j; float a[100][100] ; 1. 2.1 0.5 6.4
if ((mat = fopen("mat.dat", "r")) == NULL) { 2.0 4.90 3.1 2.80
printf ("Ne moze da se otvori datotekata mat.dat !!!\n"); 1.0 -6.2 10.0 5
exit (1); }
Novata matrica e:
fscanf (mat, "%d%d", &m, &n);
for (i=1; i<=m; i++) 1.00 2.10 0.50 6.40
for (j=1; j<=n; j++) scanf(mat, "%f", &a[i][j]); 2.00 12.50 7.30 2.80
for (i=2; i<=m-1; i++) 1.00 -6.20 10.00 5.00
for (j=2; j<=n-1; j++)
a[i][j] = a[i-1][j-1] + a[i-1][j+1] + a[i+1][j-1] + a[i+1][j+1];
fprintf (mat, "Novata matrica e:\n");
for (i=1; i<=m; i++) {
for (j=1; j<=n; j++) fprintf(mat, "%6.2f", a[i][j]); printf("\n");
}

4/9/2013 D. ^akmakov KIP - 6 17


Primeri (4)
Primer 4. Da se formira niza xi, i=1,...,k od onie elementi na matricata
A(m×n) (bez a1,1) koi{to nalevo od sebe imaat pogolem element. Ako
elementot e vo prva kolona, elementot nalevo e posledniot element vo
prethodnata redica.

#include <stdio.h>
int main () { mat.dat
FILE *mm; int m, n, i, j, k; float a[100][100], x[8000], min;
34
if ((mat = fopen("mat.dat", "r")) == NULL) {
printf ("Ne moze da se otvori datotekata mat.dat !!!\n"); 1. 2.1 0.5 6.44
exit (1); } 2.0 4.90 3.1 -12.80
fscanf (mm, "%d%d", &m, &n); 3.3 -6.2 10.0 5
for (i=1; i<=m; i++)
for (j=1; j<=n; j++) scanf(mm, "%f", &a[i][j]);
a[0][n] = -99999999999999.; k = 0; 0.50 2.00 3.10 -12.
for (i=1; i<=m; i++) 80 -6.20 5.00
for (j=1; j<=n; j++) if (j == 1) {
if (a[i][j] < a[i-1][n]) x[++k] = a[i][j];
} else if (a[i][j] < a[i][j-1]) x[++k] = a[i][j];
for (i=1; i<=k; i++) printf("%8.2f ", x[i]);
}
4/9/2013 D. ^akmakov KIP - 6 18
Potprogrami i funkcii (1)
t ip ime( a1 , a 2 ,, a n )
t ip ime( t ip1 a1, t ip2 a2 ,  , t ipn a n ) { deklaracii na a1 , a 2 ,, a n
 {
izvr{ni naredbi ili 
 izvr{ni naredbi
} 
}
Zna~i, deklariraweto na promenlivite {to se prenesuvaat vo, ili od fun-
kcijata mo`e da bide napraveno direktno vo listata na podatoci ili pred
po~etokot na teloto na funkcijata. Funkcijata ne smee da ima naredba od
oblik ime = ..., a vrednostite {to funkcijata gi vra}a ednostavno se
stavaat vo naredbata return.

Tipot tip na funkcijata e vidot na vrednosta {to funkcijata go vra}a vo


funkcijata od koja e povikana. Ako funkcijata ne vra}a vrednost, za tipot
se stava void. Povikuvaweto na funkcijata se pravi so ednostavno navedu-
vawe na nejzinoto ime i vrednosti na nejzinite argumenti v1, v2, ..., vn
rez = ime (v1, v2, ..., vn);
kade {to sekoe vi mo`e da bide konstanta, promenliva, izraz ili funkcija.

4/9/2013 D. ^akmakov KIP - 6 19


Potprogrami i funkcii (2)
Da ja pogledneme funkcijata strcmp(z1, z2) {to sporeduva dva zbora i
vra}a vrednost <0 ako prviot e pomal od vtoriot (spored abc... redosled),
=0 ako zborovite se ednakvi i >0 ako prviot zbor e pogolem od vtoriot.

int strcmp(char z1[], char z2[]) {


int i;
while (z1[i] == z2[i]) if (z1[i++] == '\0') return (0);
return (z1[i] − z2[i]);
}

Funkcijata e od tip int bidej}i vra}a takva vrednost. Dimenzijata na


zborovite z1 i z2 se ostava prazna bidej}i tie se definirana vo
povikuva~kata funkcija. Vsu{nost z1 i z2 se poka`uva~i kon 0-tite
elementi na zborovite. Ako simbolite na zborovite se ednakvi do krajot
na prviot zbor funkcijata vra}a vrednost 0. Vo sprotivno, funkcijata ja
vra}a razlikata na prvite simboli vo koi zborovite z1 i z2 se
razlikuvaat.

4/9/2013 D. ^akmakov KIP - 6 20


Potprogrami i funkcii (3)
Prenosot na vrednostite v1, v2, ..., vn vo argumentite a1, a2, ..., an e normalno "po
vrednost" ("by value"). Toa zna~i deka funkcijata pravi svoja privatna
privremena kopija na vrednostite na argumentite.
Na primer za promena na vrednosti na dve promenlivi naivno e:

void smena(real x , real y ) {


real pom ; bidej}i povikot smena(x, y); nema da gi
pom = x; x = y; y = pom; smeni vrednostite na x i y
}
(tie }e ostanat nepromeneti). Ednostavno, vrednostite na x i y od povikot se
preneseni vo promenlivite x i y vo funkcijata kade {to nivnata vrednost e
zameneta, no tie ne se po~etnite promenlivi od povikot.
Za originalnite vrednosti da bidat promeneti, argumentite vo funkcijata
smena treba da se prenesat "po ime" ("by name"). Toa vo C se postignuva so
prenesuvawe na poka`uva~ite kon memoriskite lokacii na argumentite.

void smena(real * x , real * y ) {


a povikot e smena(&x, &y);
real pom ;
pom = *x; * x = * y; * y = pom;
}

4/9/2013 D. ^akmakov KIP - 6 21


Potprogrami i funkcii (4)
Funkciite ne mora da koristat argumenti. Tipi~en primer za vakov slu~aj
e koga argumentite se globalni, t.e. mo`e da se koristat vo funkciite
(menuvaat nivnite vrednosti) iako se definirani nadvor od niv. Sledniov
primer gi ilustrira oblastite na va`ewe na promenlivite:

int x , y , z;
f 1() {
float a , b, x;
oblast na va`nost
 na a, b, x
}
char a , u; oblast na va`nost
f 2() { na x, y, z
 oblast na va`nost
} na a, u
main() {

}

Sekoj deklariran objekt nadvor od bilo koja funkcija va`i do krajot na


datotekata (zna~i vo site funkcii pod nego). Sekoj objekt deklariran vo
vnatre{nosta na edna funkcija va`i do krajot na funkcijata.

4/9/2013 D. ^akmakov KIP - 6 22


Potprogrami i funkcii (5)
Koga edna funkcija se koristi vo druga, taa ne mora da bide deklarirana
ako prethodno e definirana. Vo sprotivno, taa mora da bide deklarirana
spored vrednosta {to ja vra}a ili kako void. Na primer, slednive dve
mo`nosti se dobri:
void fun2() {
double fun1( int x , int y , double z ) {
double fun1(int, int, double );


}
rez  fun1(11
, ,6.95)
void fun2() {
ili 

}
rez  fun1(11
, ,6.95)
double fun1( int x , int y , double z ) {


}
}

Rekurzija:
main() {
int nzd(int n, int m) { int a, b;
if (m != 0) return nzd(m, n−(n/m)*m); printf("Prv broj: "); scanf("%d", &a);
else return n; printf("Vtor broj: "); scanf("%d", &b);
} printf("NZD = %d", nzd(a,b));
}

4/9/2013 D. ^akmakov KIP - 6 23


Primeri (1)
Primer 1. Da se sostavi funkcija za presmetka na sumata
s = 4/3! − 7/4! + 10/5! − 13/6! + 16/7!9 − . . .
zemaj}i gi prvite n ~lenovi.

float sum(int n) {
int i, znak = -1; float s = 0., f = 2.;
for (i = 1; i <= n; i++) {
f = f*(i+2);
znak = -znak;
s = s + znak*(3*i+1)/f;
}
return s;
}

int main () {
int n; float suma;
printf ("Kolku clena: "); scanf("%d", &n);
printf ("Sumata e %15.7f", sum(n));
}

4/9/2013 D. ^akmakov KIP - 6 24


Primeri (2)
Primer 2. Da se sostavi funkcija za pribli`na presmetka na re{enie na ravenka so
metodot na polovi~no delewe na intervalot kade {to e re{enieto.
#include <math.h>
float f(float x) {
return x*sin(x)-1;
}
float pold (float a, float b, float eps) {
float xsr;
while (b-a > eps) {
xsr = (a + b)/2.; y b−a
if (f(a)*f(xsr) <= 0) b = xsr; | xn − ξ |≤ = eps
else a = xsr; 2n f(x)
}
return (a + b)/2.; ξ
} 0
a x1 x3 x4 x2 b x
int main () {
float a, b, gr;
printf ("Vnesi go intervalot na resenieto i tocnosta:\n"); scanf("%f%f%f", &a, %b, %gr);
printf ("Resenieto e %12.7f\n", pold(a, b, gr));
}

4/9/2013 D. ^akmakov KIP - 6 25


Primeri (3)
Primer 3. Da se sostavi funkcija za barawe presek me|u dve otse~ki.
int p = 0; float px, py; // p e 1 ako ima presek; (px, py) e presecnata tocka
void prot (float x1, float y1, float x2, float y2, float z1, float w1, float z2, float w2) {
float t, u;
delta = (z2-z1)*(y2-y1) – (x2-x1)*(w2-w1);
if (delta <> 0) {
t = (z2-z1)*(w1-y1) – (z1-x1)*(w2-w1)/delta;
u = (x2-x1)*(w1-y1) – (z1-x1)*(y2-y1)/delta;
if (t >= 0 && t <= 1 && u >= 0 && u <= 1) { p = 1;
px = x1 + (x2-x1)*t;
py = y1 + (y2-y1)*t; }
}
}
int main () {
float a1, b1, a2, b2, c1, d1, c2, d2;
printf ("Koordinati na 1-ta otsecka:\n"); scanf("%f%f%f%f", &a1, &b1, &a2, &b2);
printf ("Koordinati na 2-ta otsecka:\n"); scanf("%f%f%f%f", &c1, &d1, &c2, &d2);
prot (a1, b1, a2, b2, c1, d1, c2, d2);
if (p = 1) printf ("Presekot e (%10.2f, %10.2f).\n", px, py);
else printf ("Nema presek.\n");
}
4/9/2013 D. ^akmakov KIP - 6 26
Primeri (4)
Primer 4. Da se sostavi funkcija {to go presmetuva skalarniot proizvod
me|u dva vektora zadadeni so svoite koordinati (a1, a2, ..., an ) i (b1, b2, ..., bn).
Potoa vo glavanata programa da se presmeta agolot me|u niv.

float skp (int n, float a[], float b[]) {


int i; float s = 0.;
for (i = 1; i <= n; i++) s = s + a[i] * b[i];
return s;
}

#include <math.h>
int main () {
int n; float x[1000], y[1000], agol, an, bn;
printf ("Dimenzija na vektorite: "); scanf("%d", &n);
printf ("Koordinati na prviot vektor:\n"); for (i=1; i<=n; i++) scanf("%f", &x[i]);
printf ("Koordinati na vtoriot vektor:\n"); for (i=1; i<=n; i++) scanf("%f", &y[i]);
agol = acos( skp(n, x, y)/sqrt(skp(n, x, x)*skp(n, y, y)) );
printf ("Agolot megu vektorite e %8.2f stepeni.", agol*PI/180.);
}

4/9/2013 D. ^akmakov KIP - 6 27


return na nizi
float *niz(int n, float x[]) { void niz(int n, float a[]) {
int i; int i;
for (i=1; i<=n; i++) x[i] += 1; for (i=1; i<=n; i++) a[i] += 1;
return x; }
} int main() {
int main() { int n,i; float a[5];
int n,i; float a[5], *b; a[1]=a[2]=a[3]=a[4]=1;
a[1]=a[2]=a[3]=a[4]=1; niz(4,a);
b=niz(4,a); for (i=1; i<=4; i++)
for (i=1; i<=4; i++) printf("%f ", *(a+i)); printf("%f ", a[i]);
for (i=1; i<=4; i++) printf("%f ", *(b+i)); }
}
int main() {
float *niz(int n, float *x) { int n,i; float a[5], *b;
int i; a[1]=a[2]=a[3]=a[4]=1;
for (i=1; i<=n; i++) x[i] += 1; b=niz(4,&a[0]);
return x; for (i=1; i<=4; i++) printf("%f ", a[i]);
} for (i=1; i<=4; i++) printf("%f ", b[i]);
}
4/9/2013 D. ^akmakov KIP - 6 28
Primeri (5)
Primer 5. Da se sostavi funkcija za presmetka na plo{tina na proizvo-
len poligon zadaden so koordinatite na svoite temiwa.

#include <stdio.h> y
#define D 100 P P=−B+A...
float ppol(float *px, float *py, int n) { 3
int i;
float pp = 0; 2
px[n] = px[0]; py[n] = py[0]; A B
for (i = 0; i < n; i++) 1
pp = pp + (px[i+1] − px[i])
*0.5*(py[i+1] + py[i]);
return pp; 0 1 2 3 4 5 6 7 x
}
main () {
FILE *pol; pol.dat
int i;
float x[D], y[D]; 0. 0.
if ((pol=fopen("pol.dat","r")) == NULL) { 0. 1.
printf("Nemoze da se otvori datotekata POL.DAT\n"); 1. 2.
exit(1);
} 1. 1.
for (i = 0; !feof(pol); i++) fscanf(pol, "%f%f", &x[i], &y[i]); 1. 0.
printf("Plostina =%8.2f", ppol(x, y, i−1)); Plostina = 1.25
}
4/9/2013 D. ^akmakov KIP - 6 29
Primeri (6)
Primer 6. Programa {to presmetuva pribli`na vrednost na opredelen
integral (plo{tina) po metodot Monte Karlo.
#include <stdio.h> y
#include <math.h>
#include <stdlib.h> 1
float f(float x) {
return x*x; 2
} x
float g(float x) {
3
return x*x*x; x
}
main() {
float a, b, c, d, xarg, yarg, vred;
long i, n; 0 1 x
printf("Vnesi granici po x-oska: "); scanf("%f %f", &a, &b);
printf("Vnesi granici po y-oska: "); scanf("%f %f", &c, &d);
printf("Kolku simulacii: "); scanf("%ld", &n);
vred = 0;
for (i = 1; i <= n; i++) {
xarg = a + (b − a) * rand()/32767; // rand() generira slucaen cel broj od
yarg = c + (d − c) * rand()/32767; // [1,32767], a nam ni treba realen od [0,1]
if (yarg <= f(xarg) && yarg >= g(xarg)) vred++;
}
printf("Vrednosta na integralot e: %f", vred*(b−a)*(d−c)/n);
}
4/9/2013 D. ^akmakov KIP - 6 30
Koristewe slogovi (1)
• Kako i vo drugite programski jazici, slogovite vo C se komplek-
sen tip na podatoci sostaveni od pove}e razli~ni prosti ili
kompleksni tipovi na podatoci.
Na primer, slog datum sostaven od promenlivite den, mesec i
godina mo`e da se deklarira na sledniov na~in:

typedef enum mes (jan,feb,mar,apr,maj,jun,jul,avg,sep,okt,noe,dek);


struct {
int den;
mes mesec;
int godina;
} datum ;

• So komponentite na slogot mo`e da raboti kako so bilo koi


promenlivi. Taka, so slednive naredbi se stava datumot 14.06.98
vo slogot datum:
datum.den = 14; datum.mesec = jun; datum.godina = 1998;

Zna~i imeto na slogot i komponentata se razdeluvaat so ".".

4/9/2013 D. ^akmakov KIP - 6 31


Koristewe slogovi (2)
• Slogot mo`e da se deklarira kako tip i potoa da se koristi vo
drugi deklaracii:
struct datum { struct coord {
int den; int x;
mes mesec; int y;
int godina; int z;
}; };
struct datum denes, vcera, utre; struct coord toc1, toc2;
• Vrednosta na eden slog mo`eme da ja preneseme vo drug po
komponenti:
struct MailMessage { struct toc {
int ID; int xc;
int day; int month; int yc;
float time; } ots[2];
char *Sender;
char *Subject; Mailb.day = denes.den;
char *Text; Mailb.month = denes.mesec;
char *Attachements; ots[1].xc = toc1.x; ots[1].yc = toc1.y
} Mailb; ots[2].xc = toc1.y; ots[2].yc = toc1.z

4/9/2013 D. ^akmakov KIP - 6 32


Koristewe slogovi (3)
• Komponentite na slogot mo`e da bidat drugi slogovi. Naredbite
struct ispit {
int br_ind; char prez[20], ime[12];
struct datum {
int den; mes mesec; int godina;
};
struct predmet: {
char ime[30]; int ocena;
};
};
struct ispit m1, m2, kip;
deklariraat slog ispit so informacii za studentot, i podslogovi
za datata na polagawe (datum) i predmetot na polagawe (predmet).
Na elementite na strukturata im se obra}ame so
m1. datum.god ili kip.predmet.ocena

4/9/2013 D. ^akmakov KIP - 6 33


Koristewe slogovi (4)
• Poka`uva~ kon struktura se deklarira ednostavno so
struct ispit *dm, *m3;
pri {to do elementite na strukturata im se obra}ame so
dm −> datum −> god ili m3 −> predmet −> ocena
Sega mo`eme da stavime m3 = dm, so {to sodr`inata na poka`uva~ot dm
ja stavame vo m3, pa i m3 }e poka`uva kon istata struktura. Na ovoj
na~in ne sme napravile nova kopija na strukturata, tuku samo sme
ovozmo`ile na istata struktura da & se obratime so imeto m3.
• Za pravewe kopija na strukturata bi morale da zazememe memo-
riski prostor za nea i da go napolnime so istite podatoci. Za
taa cel se koristi vgradenata funkcija malloc():
m3 = ( ( struct ispit *) malloc( sizeof ( struct ispit) ) );
• Funkcijata sizeof() ednostavno ja dava goleminata na objektot
naveden kako nejzin argument. Sega sodr`inata objektot na koj
poka`uva dm mo`eme da ja preneseme so
*m3 = *dm;
• Ako ponatamu vo programata sakame da ja oslobodime memorijata
zazemena od strukturata na koja poka`uva u }e ja koristime
funkcijata free(⋅): free(m3);
4/9/2013 D. ^akmakov KIP - 6 34
Primeri (1)
Primer 7. Da se sostavi mini-aplikacija za studenti {to polagale ispit
(ime i prezime, predmet, data na polagawe i dobiena ocenka).
#include <stdio.h>
struct slog {
char PreIme[30]; char Pred[30];
struct {
int den, mes, god;
} Data;
int Oce;
};
char dime[15]; int n = 0; float procena = 0; // ime na datotekata; brojac na slogovi; i pros. ocena;
void polni(FILE *dpol) { // funkcija za polnenje na datotekata
struct slog Vlez; char tipka[1];
do { printf("\nPrezime i ime: "); scanf("%30s", Vlez.PreIme);
printf("\nPredmet: "); scanf("%30s", Vlez.Pred);
printf("Data - den: "); scanf("%d", &Vlez.Data.den);
printf("Data - mes: "); scanf("%d", &Vlez.Data.mes);
printf("Data - god: "); scanf("%d", &Vlez.Data.god);
printf("Ocena: "); scanf("%d", &Vlez.Oce);
if (Vlez.Data.den > 31 || Vlez.Data.mes > 12 || Vlez.Data.god > 2004 || Vlez.Oce > 10) {
printf("Pogresen podatok. Slogot ne e vnesen vo datotekata !\n");
continue;
}
fprintf(dpol, "%s %s %d %d %d %d\n", Vlez.PreIme, Vlez.Pred,
Vlez.Data.den, Vlez.Data.mes, Vlez.Data.god, Vlez.Oce);
printf("Vnesuvate uste? (Y/N) "); scanf("%1s", &tipka);
} while (strcmp(tipka, "N") != 0 && strcmp(tipka, "n") != 0);
}
4/9/2013 D. ^akmakov KIP - 6 35
Primeri (1)
void listaj(FILE *dpol) { // funkcija za listanje na datotekata
struct slog Izlez;
while (fscanf(dpol,"%s %s %d %d %d %d", Izlez.PreIme, Izlez.Pred,
&Izlez.Data.den, &Izlez.Data.mes, &Izlez.Data.god, &Izlez.Oce) == 6) {
printf("%20s%30s%6d.%2d.%4d%6d\n", Izlez.PreIme, Izlez.Pred,
Izlez.Data.den, Izlez.Data.mes, Izlez.Data.god, Izlez.Oce);
n++; procena += Izlez.Oce; // gi sobirame ocenite
}
}
main() {
FILE *dpol; // pokazuvac kon datotekata
printf("Ime na datotekata: "); scanf("%s", dime);
if ((dpol = fopen(dime,"w"))==NULL) printf("Nemoze da se otvori datotekata %s!", dime);
printf("\nVnesuvanje na podatoci - %s\n", dime);
polni(dpol);
fclose(dpol);
if ((dpol=fopen(dime,"r")) == NULL) printf("Nemoze da se otvori datotekata %s!", dime);
printf("\nLista na polozeni studenti\n\n");
printf(" PREZIME i IME PREDMET DATA OCENA\n");
printf("−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−\n");
listaj(dpol);
printf("−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−\n");
printf(" Prosek = %6.2f", procena/n);
fclose(dpol);
}
4/9/2013 D. ^akmakov KIP - 6 36
V
Programirawe
vo C (III)
Rekurzija
• Za eden objekt velime deka e rekurziven ako toj kako pomala
kopija se sodr`i vo sebe ili pak ako e definiran preku sebe

• Vo matematikata, rekurzijata ovozmo`uva definirawe na


beskone~ni mno`estva preku ednostaven i kratok opis.
Prirodni broevi: f(0) = 0; f(k) = f(k−1) + 1;
• Rekurzivnite algoritmi se realiziraat taka {to funkcijata
se povikuva samata sebe s# dodeka ne se ispolni uslovot za
kraj. Rekurzivnite algoritmi ovozmo`uvaat povtoruva~ki
presmetuvawa bez koristewe na ciklusi.
long f(int n) { // Presmetuva n!
if (n == 0) return 1;
else return n*f(n-1);
}

4/9/2013 D. ^akmakov KIP - 6 2


Stekovi (1)
• Pri povikuvaweto na procedurite ili funkciite sekoga{ se
koristi edna linearna struktura nare~ena stek (“Stack”). Stekot
gi ~uva vrednostite na site promenlivi na sekoja aktivna
(nezavr{ena) procedura ili funkcija od algoritamot
• Stekot e linearna struktura kade {to site operacii na ufrluva-
we i bri{ewe samo na edniot kraj
Izlez od Vlez vo Vrv
stekot stekot

...
Ufrluvawe
ili bri{ewe
Stek

Dno

Koga vagonite ili lokomotivite }e vlezat vo stekot sekoga{ posledniot


{to e vlezen mo`e da izleze. Ottuka poteknuva i kratenkata za imeto na
stekot: LIFO (“Last-In-First-Out”), posledniot {to vleguva prv izleguva.
4/9/2013 D. ^akmakov KIP - 6 3
Stekovi (2)
• Stekovite imaat ogromna primena vo algoritmite:
♦ Kaj operativnite sistemi sekoja programa {to se izvr{uva ima
pridru`eno stek za promenlivite so koi raboti
♦ Korisni~kite aplikacii kade {to odreden broj posledni operacii
se zapomnuvaat vo stek za da mu se ovozmo`i na korisnikot
eventualno vra}awe na sostojbata pred izvr{uvawe na nekoja od tie
operacii (“undo”)
(takvi se prakti~no site Windows aplikacii: MS Office, CorelDraw,
Visual Studio, …)
♦ Oznaki:
S ⇐ x // x odi vo stekot
y ⇐ S // y se zema od stekot
• Za nas od poseben interes e koristeweto na stekovite vo
rekurzivnite algoritmi

4/9/2013 D. ^akmakov KIP - 6 4


Rekuzivni algoritmi (1)
• Sekoj programski jazik {to dozvoluva rekurzivno povikuvawe na
programite koristi stek za ~uvawe na vrednostite na site pro-
menlivi na sekoja aktivna funkcija i procedura od programata
• Koga nekoja procedura e povikana, se kreira nov zapis vo stekot
so vrednosti za site promenlivi od povikuva~kata procedura,
bez razlika dali prethodno ve}e postoi zapis vo stekot za
istata. Koga povikanata procedura }e zavr{i, se zema zapisot od
stekot so site promenlivi od povikuva~kata procedura i taa
prodol`uva so svojata rabota

void REKURZ( tip p1, tip p2 ,, tip pn ) { Op{t rekurziven


izvr{i grupa naredbi 1 algoritam so eden
if not uslov za kraj then REKURZ( v1,v 2 ,,v n ) rekurziven povik
else grupa naredbi za kraj
izvr{i grupa naredbi 2
}

4/9/2013 D. ^akmakov KIP - 6 5


Rekurzivni algoritmi (2)
Iterativna verzija na op{tiot rekurziven algoritam bi mo`ela da
bide realizirana vaka:

void REKURZ( tip p1, tip p2 ,, tip pn ) {


izvr{i grupa naredbi 1
 S ⇐ ( p1, p2 ,, pn ,v1,v 2 ,,v n )
 p1 = vrednost 1

while (! uslov za kraj ) do  
 pn = vrednost n
 izvr{i grupa naredbi 1
izvr{i grupa naredbi 2
 ( p1, p2 ,, pn ,v1,v 2 ,,v n ) ⇒ S
while not prazen stek do  naredbi so ( p1, p2 ,, pn ,v1,v 2 ,,v n )
 izvr{i grupa naredbi 2
}

4/9/2013 D. ^akmakov KIP - 6 6


Primeri (1)
Primer 1. Rekurzivna programa {to izdvojuva cifri od cel broj.
void cifri(int n) { Ovoj primer poka`uva
if (n >= 10) cifri(n/10); kako rekurzivniot
printf (“%d “, n%10); algoritam gi svrtuva
}
rezultatite obratno
int main() { (poradi stekot).
int n;
printf(“Cel broj: "); scanf("%d", &n);
cifri(n);
}

1 1%10 = 1
n = 13806
13 13 13%10 = 3
138 138 138 138%10 = 8
1380 1380 1380 1380 1380%10 = 0
13806 13806 13806 13806 13806 13806%10 = 6
prv povik vtor povik tret povik ~etvrti povik petti povik

4/9/2013 D. ^akmakov KIP - 6 7


Primeri (2)
Primer 2. Rekurzivna programa {to presmetuva n! za cel broj n.

Rekurzivna definicija: f(0) = 1; f(k) = k*f(k-1)

long f(int n) {
if (n >= 2) return n*f(n-1); [to bi se slu~ilo ako ako go
else return 1; ispu{time else blokot vo
} naredbata if?
int main() {
int k;
printf("Broj: "); scanf("%d", &k);
printf("Fak = %ld\n", f(k));
}

4/9/2013 D. ^akmakov KIP - 6 8


Primeri (3)
Primer 3. Rekurzivna programa za nao|awe NZD za dva celi broja i glavna
programa {to so pomo{ na potprogramata nao|a NZD za k
broevi.

Rekurzivna definicija: f(n, 0) = n; f(n, m) = f(m, n%m)

int nzd(int n, int m) {


if (m != 0) return nzd(m, n%m);
else return n;
}
n m
int main() { 16 28 28 ≠ 0
int i, y, k, x[100];
printf(“Kolku broevi: "); scanf("%d", &k); 28 16 16 ≠ 0
printf("Vnesi gi broevite:\n");
for (i=1; i<=k; i++) scanf("%d", &x[i]); 16 12 12 ≠ 0
y = x[1]; 12 4 4≠0
for (i=2; i<=k; i++) y = nzd(y, x[i]);
printf("NZD = %d", y); 4 0 0=0
} return 4

4/9/2013 D. ^akmakov KIP - 6 9


Primeri (4)
Primer 4. Rekurzivna programa za broevite na Fibona~i.
long fib(int n) { Ovoj rekurziven algoritam
if (n >= 2) return fib(n-1) + fib(n-2); e eden isklu~itelno neefi-
else return n; kasen na~in za presmetka na
} broevite na Fibona~i.
main() { Stebloto go prika`uva bro-
int k; jot na povikuvawa na fun-
printf(“Koj broj na Fibonaci: ");
scanf("%d", &k); kcijata za n=5 koj{to raste
printf(“%d-tiot broj na Fibonaci e %ld", k, fib(k)); eksponencijalno.
} n povikuvawa na fib()
0 1
5 1 1
2 3
4 3 3 5
3 2 2 1 4 9
5 15
6 25
2 1 1 0 1 0 7 41
8 67
9 109
1 0 10 177
4/9/2013 D. ^akmakov KIP - 6 10
Primeri (5)
Primer 5. Rekurzivna programa za presmetka na sumi.
float x[1000]; Kolku elementi: 10
float sum(int d, int g) { Od koj do koj indeks ja sakas sumata:
int sred; 39
if (d > g) return 0; Sumata e 84.000000
else if (d == g) return x[d];
else sred = (d + g)/2;
return sum(d, sred) + sum(sred + 1, g);
}
int main() {
int i, k, poc, kraj;
printf("Kolku elementi: "); scanf("%d", &k);
for(i=0; i<=k; i++) x[i] = 2*i;
printf("Od koj do koj indeks ja sakas sumata:\n"); scanf("%d%d",&poc, &kraj);
if (poc>=0 && kraj<=k) printf("Sumata e %f\n", sum(poc,kraj));
else printf("Pogresen opseg!\n");
}

4/9/2013 D. ^akmakov KIP - 6 11


Primeri (6)
Primer 6. Rekurzivna programa za problemot na Hanojskite stolp~iwa.
Imame 3 stolba A, B i C, pri {to na stolbot A ima n prsteni so razli~-
na golemina (radius) naredeni eden nad drug od najgolemiot do najmali-
ot. Problemot e da se prefrlat prstenite na stolbot C, koristej}i go
stolbot B, pri {to e dozvoleno stavawe samo pomal prsten vrz
pogolem.
void prem(int n, char s1, char s2, char s3) { int main() {
if (n > 0) { int k;
prem(n-1, s1, s3, s2); printf(“Kolku prsteni: ");
printf(“Od stolb: %c, na stolb: %c\n”,s1 s3); scanf("%d", &k);
prem(n-1, s2, s1, s3); prem(k,’A’,’B’,’C’);
} }
}
A B Kolku prsteni: 3 C
Od stolb: A na stolb: C
1 Od stolb: A na stolb: B
2 Od stolb: C na stolb: B
⋅ Od stolb: A na stolb: C
⋅ Od stolb: B na stolb: A
⋅ Od stolb: B na stolb: C
n-1
n Od stolb: A na stolb: C

4/9/2013 D. ^akmakov KIP - 6 12


Primeri* (7)
Primer 7. Rekurzivna programa za binarno barawe element vo niza.
int count = 0;
int bs(int y, int d, int g, int x[], int *poz) {
int sred;
count++; Koj element baras: 122
if (g < d) return 1; Elementot 122 e najden na 61-ta pozicija.
sred = (d + g)/2; Imavme 17 povika do bs().
if (y == x[sred]) { *poz = sred; return 0; }
else if (y < x[sred]) return bs(y, d, sred-1, x, poz);
else return bs(y, sred+1, g, x, poz);
} Koj element baras: 13
Elementot 13 ne e vo nizata!
int main() {
int i, poz, y, x[SIZE], status; Imavme 18 povika do bs().
for (i=0; i<1000; i++) x[i] = 2*i;
printf("\nKoj element baras: "); scanf("%d", &y);
status = bs(y, 0, SIZE-1, x, &poz);
if (status == 0) printf("Elementot %d najden na %d-tata pozicija \n", y, poz);
else printf("Elementot %d ne e vo nizata!\n\n", y);
printf("Imavme %d povika do bs().\n\n", count);
}

4/9/2013 D. ^akmakov KIP - 6 13


Primeri* (8)
Primer 7. Rekurzivna programa za najkus pat vo lavirint.
1 1 1 1 1

1 0 0 0 0 0 1
po~etna
lokacija 1 1 0 1 1 0 1

1 0 0 0 1 0 1

celna
1 0 1 0 0 1 1
lokacija
1 0 0 1 0 1 1

1 1 1 1 1

Rekurzijata e zgodna bidej}i na sekoe sledno pole gi pravime


istite proverki kako na prethodnoto.

4/9/2013 D. ^akmakov KIP - 6 14


Primeri* (8)
Primer 7. Rekurzivna programa za najkus pat vo lavirint.
int l[100][100], p, q, lpat, mlpat; 5
void pat(int i, int j) { 0 0 0 0 1
if (i==p && j==q) { if (lpat<mlpat) mlpat = lpat; } 1 1 0 0 1
else if (l[i][j]==0) { 0 0 0 1 0
lpat ++; l[i][j] = 9; // Patekata se polni so 9-ki 0 0 1 1 0
pat(i+1, j); pat(i-1, j); pat(i, j+1); pat(i, j-1); 1 0 0 0 0
lpat--; l[i][j] = 0; // Patekata se vraca na pocetno
3 1
}
} Ima pateka so dolzina 6.
int main() {
FILE *lav; int i, j, n;
if ((lav=fopen("l.txt","r+"))==NULL) { printf("Ja nema datotekata l.txt !!!\n"); exit(1); }
fscanf(lav,"%d",&n); for(i=1; i<=n; i++) for(j=1; j<=n; j++) fscanf(lav,"%d", &l[i][j]);
fscanf(lav,"%d %d", &p, &q);
for (i=1; i<=n; i++) {
l[i][0] = 1; l[i][n+1] = 1; l[0][i] = 1; l[n+1][i] = 1; // Ramka od 1-ci okolu lavirintot
}
lpat = 0; mlpat = n*n +1; pat(1,1); // Ja povikuvame rekurzivnata funkcija pat()
if (mlpat==n*n +1) printf("\nNema pateka od (1,1) do (%d,%d).\n",p,q);
else printf("\nIma pateka so dolzina %d.\n", mlpat);
}

4/9/2013 D. ^akmakov KIP - 6 15


Soveti za programirawe (1)
Minimalno vreme na izvr{uvawe
Razbirlivost i ~itlivost najva`no
Koristewe na minimalen memoriski prostor
Minimalno vreme na preveduvawe pomalku
va`no
So isklu~ok na razbirlivosta i ~itlivosta, site drugi celi najmnogu
zavisat od algoritamot koristen za re{avawe na problemot.

Soveti za pi{uvwe razbirlivi i ~itlivi programi:


• Pi{uvaj ja programata so vovle~eni linii spored programskite blokovi
• Koristi komentari za objasuvawe na programskite blokovi
• Imenuvaj gi promenlivite so imiwa {to asociraat na nivnata uloga
• Odbegnuvaj koristewe na “trikovi”
a=a+b pom = a
b = a − b tro{i pomalku memorija od a=b
a=a−b b = pom
no e trik i ne bi trebalo da se koristi

4/9/2013 D. ^akmakov KIP - 6 16


Soveti za programirawe (2)
Iako algoritamskoto re{enie e najva`no, sepak slednite sugestii za
pi{uvawe poefikasni (vreme na izvr{uvawe) programi se bitni:

• Deklariraj gi promenlivite spored potrebite na programata


• Odbegnuvaj koristewe razli~ni tipovi promenlivi vo izrazite
int i; podobro e int i;
i = i + 1.0 i=i+1
• Koristi pobrzi aritmeti~ki izrazi
y = pow(x,2); podobro e y = x*x;
a = 2.0*b podobro e a = b + b;
s = v/100; podobro e s = v*0.01;
• Koga e mo`no koristi konstanti vo izrazite
Fragment od programa Podobro re{enie Najdobro re{enie
a = a*(3.14/180) *4. − b x = (3.14/180.)*4. #define x = (3.14/180.)*4.
. . .
. . .
. . .
b = c*(3.14/180)*4. − z a = a*x − b a = a*x − b
b = c*x − z b = c*x − z

4/9/2013 D. ^akmakov KIP - 6 17


Soveti za programirawe (3)
• Reduciraj gi povicite do potprogramite i funkciite
x = log(y) + log(z); podobro e x = log(y*z);
x = pow(y,3); podobro e x = y*y*y;
a = min(x,y,3.0)-5; am = min(x,y,3.0);
b = min(x,y,3.0); podobro e a = am - 5;
b = am + 4;
• Koga e mo`no kombiniraj gi naredbite za povtoruvawe
for (i=1; i<=n; i++) sx = sx + x[i]; podobro e for (i=1; i<=n; i++) { sx = sx + x[i];
for (i=1; i<=n; i++) sy = sy + y[i]; sy = sy + y[i]; }
• Izbegnuvaj gi kratkite povtoruva~ki konstrukcii
x[1] = y[1]*z[1];
for (i=1; i<=3; i++) x[i] = y[i]*z[i]; podobro e x[2] = y[2]*z[2];
x[3] = y[3]*z[3];
• Koristi minimalen broj operacii vo povtoruva~kite konstrukcii
sum = 0. sum = 0.
for (i=1; i<=n; i++) podobro e for (i=1; i<=n; i++)
sum = sum + v*v + a[i]; sum = sum + v*v + a[i];
sum = sum + n*v*v;
4/9/2013 D. ^akmakov KIP - 6 18
Soveti za programirawe (4)
• Koristi efikasni if naredbi
Vo naredbite blok if kako prv treba da se stavi uslovot so najgolema verojatnost
na slu~uvawe, kako vtor onoj so sledna verojatnost itn.
if (sim >= 5000) … ; Ova e dobro ako najmnogu pati
else if (sim >= 1000) … ; sim dobiva vrednost pogolema
else if (sim>=200) …; od 5000, potoa od 1000 itn. (Na
else if (sim >= 80) …; primer, ako sim e broja~.)

Kaj logi~kite uslovi so operatorite || i && redosledot na uslovite e va`en.


Slednata if naredba e efikasna ako {ansite n da bide pomal od 100 se pogolemi
od {ansite m da bide pogolem od 50:
if (n < 100 || m > 50) … ; (vtoriot uslov ne se proveruva ako prviot e to~en)
Slednata if naredba e efikasna ako {ansite n da bide pomal od 100 se pomali od
{ansite m da bide pogolem od 50:
if (n < 100 && m > 50) … ; (vtoriot uslov ne se proveruva ako prviot e neto~en)
• Koristi konstrukcii so pomali memoriski barawa
s = a*b - 4.;
t = c*c; podobro e rez = a*b + c*c -4.;
rez = s + t;

4/9/2013 D. ^akmakov KIP - 6 19

You might also like