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 nasoka za pi{uvawe aplikacii pod Windows operativni sistemi
(na primer Visual C), zaedno so negovata vrzanost za operativnite 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



decimalni
celobrojni
znakovni

indeksni
tekstualni
slogovi
datoteki

poka`uva~i

objekti

izvr{ni naredbi

}

Tip
celobrojni
decimalni
znakoven
konstanti

4/9/2013

Deklaracija
int a,vred;
float x, y, a, pom;
char a, b, rez;
#define ime vrednost

D. ^akmakov

Konstanti
−2, 67822
2.44, .710, 0.613299, 5.2e+10
'a', '$', '?'
#define gravitacija 9.81

KIP - 6

4

Naredba za vlez
scanf (format, v , v , Op{to
...,v );
za C
1

2

n

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
4.56#AX#22#3
12.32E−1P H#11230
###−3.44###+1#11#0
11.0#33#prilog#88000
##4.14#aa
###
##3#7

4/9/2013

Vrednost na promenlivite
x=4.56 t1="AX" t2="22" n=3
x=1.232 t1="P" t2="H" n=11230
x=−3.44 t1="+1" t2="11" n=0
x=11.0 t1="33" t2="pril" n=0
x=4.14 t1='aa' t2='3' n=7

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
n=2 x=4.5 y=1.2 t='X'
n=122 x=−12.01 y=0.225 t='1'
n=0 x=4.0 y=12.0 t=‘aaa ’
n=444 x=0.00001 y=0.00001 t=‘3’
x=21230.14 y=2123.2 t=‘abba’ n=1

4/9/2013

D. ^akmakov

Oblik na pe~ateweto
#2##4.5000#1.2000E+00X#
122#-12.0100#2.2500E-011#
#0##4.0000#1.2000E+01aaa
444##0.0000#1.0000E−05#3
#1#21230.1406#2.1232E+03abba

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) naredba1
else naredba2 ;
if ( uslov) {
naredbi;
}

if ( uslov) {
naredbi1;
}
else {
naredbi2 ;
}

if ( uslov1 ) {

naredbi1
} else if ( uslov2 ) {
naredbi2
} else if ( uslov3 ) {
naredbi3
..........
} else {

naredbi

}
switch ( izraz ) {
case vrednost i1: naredbi1;
case vrednost i2 : naredbi2 ;

}
4/9/2013

..........
case vrednost in : naredbin ;
default naredbin+1;
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
while ( uslov) {
naredbi;
}

blokot while se povtoruvaat s#
dodeka e ispolnet uslovot, t.e.
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
and then produce a
f1 = f2 = 1;
(Leonardo of Pisa)
new pair every
for (i=3; i<=n; i++) {
month after that,
f3 = f1 + f2; f1 = f2; f2 = f3;
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 () {
---------------------------------1.0000
0.6214
float km, ml, maxkm;
1.6093
1.0000
printf ("Do koj kilometar: ");
2.0000
1.2428
3.0000
1.8641
scanf("%f", &maxkm);
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
Nizite se memoriraat vo sosedni memoriski lokacii. Za razlika od drugi
programaki jazici, vo C nizite zapo~ nuvaat so indeks 0. Na primer, na elementite na nizata vr[100] }e i se obra}ame so vr[0], vr[1], vr[2], …, vr[99].

a0, a1, a2, …, an
tip ime[k]; na primer:
int z[1000]; float vr[100];
double a[10]; char t[9];
d
a1

a2
l1=l0+d

l0

. . .

a3

an-1

an
ln=l1+n⋅d

l2=l1+2d

d = 4 bajti (int);

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

Za tekst:

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

4/9/2013

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

.

###BOT_TEXT###

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() {
Brojot 99 so vrednost 99 ima adresa 1245032
int broj, *br;
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 ‘###BOT_TEXT###’.
Na primer so:
char *name = "lcc-win32";

vo memorijata }e imame:
l

c

c

-

108

99

99

45

w

i

n

119 105 110

3

2

###BOT_TEXT###

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++]=='###BOT_TEXT###') { 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=='###BOT_TEXT###') { 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
Kraj

Po~etok
Tekovna pozicijata

Rabotata so datoteki e edna od najva`nite mo`nosti vgradena vo programskite 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~etniot 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) {
obraboti go x;
ili
}
4/9/2013

D. ^akmakov

while ((x = fscanf(ime, "%c", x)) != 1) {
obraboti go x;
}
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:
Zna~ewe

Funkcija
fgetc(f, ...), getc(f), fscanf(f, ...),
fgets(..., f), fputc(f, ...), putc(…, f),
fprintf(f, ...), fputs(..., f)
fopen("ime", "vid"), fclose(f)
feof(f), ferror(f)
fseek(f, n, pos)
ftell(f)

~itawe i pi{uvawe
otvorawe (r - ~itawe, w - pi{uvawe, + dodavawe pri {to e mo`na i kombinacija
na ovie simboli) i zatvorawe na datoteka
proverka za kraj i gre{ka
pozicionirawe na n-ti bajt
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); }
tocki.d
n = xp = yp = xdis = ydis = 0;
1. 2.
fscanf (fp, "%f%f", &x, &y);
while ( !feof(fp) ) { xp += x; yp += y; n++;
2. 3.
fscanf (fp, "%f%f", &x, &y); }
3. 3.
xp = xp/n; yp = yp/n;
n = 0; rewind(fp); // ili fseek(fp, 0l, 0l);
Centralnata tocka e ( 2.00, 2.67)
fscanf (fp, "%f%f", &x, &y);
so disperzija ( 0.82, 0.47).
while ( !feof (fp) ) {
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:\LCPP\KIP\LCC> pr2 pr2.c
c = fgetc(infile);
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] = '###BOT_TEXT###';
// 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.

!
"
#
%
'
(
)
*
+
,
.
/
0
1
2
3
4
5
6
:

(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(

4/9/2013

32)
33)
34)
35)
37)
39)
40)
41)
42)
43)
44)
46)
47)
48)
49)
50)
51)
52)
53)
54)
58)

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

68
3
12
2
7
2
18
18
1
6
9
3
2
3
2
2
1
1
3
2
1

;
<
=
>
D
E
F
I
J
L
N
O
T
U
[
\
]
a
b
c
d

( 59)
( 60)
( 61)
( 62)
( 68)
( 69)
( 70)
( 73)
( 74)
( 76)
( 78)
( 79)
( 84)
( 85)
( 91)
( 92)
( 93)
( 97)
( 98)
( 99)
( 100)

D. ^akmakov

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

17
3
11
3
1
2
6
1
1
3
1
1
1
1
5
3
5
13
3
29
7
KIP - 6

e
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
v
w
x
{
}

(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(
(

101)
102)
103)
104)
105)
107)
108)
109)
110)
111)
112)
113)
114)
115)
116)
117)
118)
119)
120)
123)
125)

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

31
14
3
4
35
3
6
8
38
18
5
4
13
12
27
16
2
1
1
3
3

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 
,
a


a
a
2,2
2,n 
 2,1

 


a m,1 a m,2  a m,n 

tip ime[m][n]; na primer:
int z[1000][2]; float vr[100][100];
double a[10][10][10]; char t[9][25];

Elementite od nizite mo`e da
bidat novi nizi, {to vodi do
nizi so dimenzii 2, 3, 4 itn.
(pove}edimenzionalni nizi).
Od poseben interes se nizite
so dimenzija 2, bidej}i preku
niv se pretstavuvaat poznatite matemati~ki objekti, matricite 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 dijagonala 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 !!! ");
exit (1); }
fscanf (mat, "%d", &n);
for (i=1; i<=n; i++)
for (j=1; j<=n; j++) scanf(mat, "%f", &a[i][j]);
sg = ss = sddr = 0;
for (i=1; i<=n; i++) { sg = sg + a[i][i];
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];
printf ("Sumite se:\nsg = %12.2f\nss = %12.2f
\nsddtr = %12.2f###BOT_TEXT###quot;, sg, ss, sddtr);
}
4/9/2013

D. ^akmakov

KIP - 6

mat.dat
4
1.
2.1
0.5
6.44
2.0 4.90 3.1 -12.80
3.3 -6.2 10.0 5
.20 2.2
20.5 8.80
Sumite se:
sg =
24.70
ss =
3.45
sddtr =
33.7
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");
34
exit (1); }
1.
2.1
0.5
6.44
fscanf (mm, "%d%d", &m, &n);
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++) {
0.00 8.30 0.00 19.24
min = a[1][i];
1.00 11.10 2.60 0.00
for (j=1; j<=m; j++) if (a[j][i] < min) min = a[j][i];
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 () {
1.
2.1
0.5
6.4
FILE *mat; int m, n, i, j; float a[100][100] ;
2.0 4.90 3.1 2.80
if ((mat = fopen("mat.dat", "r")) == NULL) {
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);
1.00 2.10 0.50 6.40
for (i=1; i<=m; i++)
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) {
1.
2.1
0.5
6.44
printf ("Ne moze da se otvori datotekata mat.dat !!!\n");
2.0 4.90 3.1 -12.80
exit (1); }
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]);
0.50 2.00 3.10 -12.
a[0][n] = -99999999999999.; k = 0;
80 -6.20 5.00
for (i=1; i<=m; i++)
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 )
deklaracii na a1 , a 2 ,, a n

t ip ime( t ip1 a1, t ip2 a2 ,  , t ipn a n ) {


izvr{ni naredbi

ili

{



izvr{ni naredbi





}

}
Zna~i, deklariraweto na promenlivite {to se prenesuvaat vo, ili od funkcijata 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 naveduvawe 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++] == '###BOT_TEXT###') 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 ;
pom = x; x = y; y = pom;
}

bidej}i povikot smena(x, y); nema da gi
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 ) {
real pom ;
pom = *x; * x = * y; * y = pom;
}
4/9/2013

D. ^akmakov

a povikot e smena(&x, &y);

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;

}
char a , u;
f 2() {

}
main() {

}

oblast na va`nost
na a, b, x
oblast na va`nost
na x, y, z
oblast na va`nost
na a, u

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:

double fun1( int x , int y , double z ) {

}
void fun2() {

rez  fun1(11
, ,6.95)

}

ili

void fun2() {
double fun1(int, int, double );

rez  fun1(11
, ,6.95)

}
double fun1( int x , int y , double z ) {

}

Rekurzija:
int nzd(int n, int m) {
if (m != 0) return nzd(m, n−(n/m)*m);
else return n;
}
4/9/2013

D. ^akmakov

main() {
int a, b;
printf("Prv broj: "); scanf("%d", &a);
printf("Vtor broj: "); scanf("%d", &b);
printf("NZD = %d", nzd(a,b));
}
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
if (f(a)*f(xsr) <= 0) b = xsr;
else a = xsr;
}
return (a + b)/2.;
0
}

| xn − ξ |≤

b−a
= eps
2n

f(x)
ξ

x1

a

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[]) {
int i;
for (i=1; i<=n; i++) x[i] += 1;
return x;
}
int main() {
int n,i; float a[5], *b;
a[1]=a[2]=a[3]=a[4]=1;
b=niz(4,a);
for (i=1; i<=4; i++) printf("%f ", *(a+i));
for (i=1; i<=4; i++) printf("%f ", *(b+i));
}
float *niz(int n, float *x) {
int i;
for (i=1; i<=n; i++) x[i] += 1;
return x;
}
4/9/2013

D. ^akmakov

void niz(int n, float a[]) {
int i;
for (i=1; i<=n; i++) a[i] += 1;
}
int main() {
int n,i; float a[5];
a[1]=a[2]=a[3]=a[4]=1;
niz(4,a);
for (i=1; i<=4; i++)
printf("%f ", a[i]);
}

int main() {
int n,i; float a[5], *b;
a[1]=a[2]=a[3]=a[4]=1;
b=niz(4,&a[0]);
for (i=1; i<=4; i++) printf("%f ", a[i]);
for (i=1; i<=4; i++) printf("%f ", b[i]);
}
KIP - 6

28

Primeri

(5)

Primer 5. Da se sostavi funkcija za presmetka na plo{tina na proizvolen poligon zadaden so koordinatite na svoite temiwa.
#include <stdio.h>
y
#define D 100
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;
1
0
2
3
}
main () {
FILE *pol;
int i;
float x[D], y[D];
if ((pol=fopen("pol.dat","r")) == NULL) {
printf("Nemoze da se otvori datotekata POL.DAT\n");
exit(1);
}
for (i = 0; !feof(pol); i++) fscanf(pol, "%f%f", &x[i], &y[i]);
printf("Plostina =%8.2f", ppol(x, y, i−1));
}
4/9/2013

D. ^akmakov

KIP - 6

P=−B+A...

P

4

5

6

7

x

pol.dat
0. 0.
0. 1.
1. 2.
1. 1.
1. 0.
Plostina =

1.25

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) {
return x*x*x;
}
main() {
float a, b, c, d, xarg, yarg, vred;
0
1
long i, n;
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

x

3

x

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 {
int den;
mes mesec;
int godina;
};
struct datum denes, vcera, utre;

struct coord {
int x;
int y;
int z;
};
struct coord toc1, toc2;

• Vrednosta na eden slog mo`eme da ja preneseme vo drug po
komponenti:

struct MailMessage {
int ID;
int day; int month;
float time;
char *Sender;
char *Subject;
char *Text;
char *Attachements;
} Mailb;
4/9/2013

struct toc {
int xc;
int yc;
} ots[2];
Mailb.day = denes.den;
Mailb.month = denes.mesec;
ots[1].xc = toc1.x; ots[1].yc = toc1.y
ots[2].xc = toc1.y; ots[2].yc = toc1.z
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

4/9/2013

ili

kip.predmet.ocena

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 ufrluvawe i bri{ewe samo na edniot kraj
Izlez od
stekot

Vrv

Vlez vo
stekot

Stek

Ufrluvawe
ili bri{ewe

...

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 promenlivi 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 ) {

izvr{i grupa naredbi 1
if not uslov za kraj then REKURZ( v1,v 2 ,,v n )
else grupa naredbi za kraj
izvr{i grupa naredbi 2

Op{t rekurziven
algoritam so eden
rekurziven povik

}

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) {
if (n >= 10) cifri(n/10);
printf (“%d “, n%10);
}
int main() {
int n;
printf(“Cel broj: "); scanf("%d", &n);
cifri(n);
}

Ovoj primer poka`uva
kako rekurzivniot
algoritam gi svrtuva
rezultatite obratno
(poradi stekot).

1

1%10 = 1

13

13

13%10 = 3

138

138

138

138%10 = 8

1380

1380

1380

1380

1380%10 = 0

13806

13806

13806

13806

13806

prv povik

vtor povik

n = 13806

4/9/2013

13806%10 = 6

tret povik ~etvrti povik petti povik

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);
else return 1;
}

[to bi se slu~ilo ako ako go
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;
}
int main() {
int i, y, k, x[100];
printf(“Kolku broevi: "); scanf("%d", &k);
printf("Vnesi gi broevite:\n");
for (i=1; i<=k; i++) scanf("%d", &x[i]);
y = x[1];
for (i=2; i<=k; i++) y = nzd(y, x[i]);
printf("NZD = %d", y);
}

4/9/2013

D. ^akmakov

n

m

16

28

28 ≠ 0

28

16

16 ≠ 0

16

12

12 ≠ 0

12

4

4≠0

4

0

0=0
return 4

KIP - 6

9

Primeri (4)
Primer 4. Rekurzivna programa za broevite na Fibona~i.
long fib(int n) {
if (n >= 2) return fib(n-1) + fib(n-2);
else return n;
}
main() {
int k;
printf(“Koj broj na Fibonaci: ");
scanf("%d", &k);
printf(“%d-tiot broj na Fibonaci e %ld", k, fib(k));
}

Ovoj rekurziven algoritam
e eden isklu~itelno neefikasen na~in za presmetka na
broevite na Fibona~i.
Stebloto go prika`uva brojot na povikuvawa na funkcijata za n=5 koj{to raste
eksponencijalno.

5
4

3

3
2
1

2

2
1

1

0

1

1
0

0
4/9/2013

D. ^akmakov

KIP - 6

n povikuvawa na fib()
0
1
1
1
2
3
3
5
4
9
5
15
6
25
7
41
8
67
9
109
10
177

10

Primeri (5)
Primer 5. Rekurzivna programa za presmetka na sumi.
float x[1000];
float sum(int d, int g) {
int sred;
if (d > g) return 0;
else if (d == g) return x[d];
else sred = (d + g)/2;
return sum(d, sred) + sum(sred + 1, g);
}

Kolku elementi: 10
Od koj do koj indeks ja sakas sumata:
39
Sumata e 84.000000

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 najmaliot. 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) {
if (n > 0) {
prem(n-1, s1, s3, s2);
printf(“Od stolb: %c, na stolb: %c\n”,s1 s3);
prem(n-1, s2, s1, s3);
}
}
A

B

1

2

n-1
n

4/9/2013

D. ^akmakov

int main() {
int k;
printf(“Kolku prsteni: ");
scanf("%d", &k);
prem(k,’A’,’B’,’C’);
}
Kolku prsteni: 3
Od stolb: A na stolb: C
Od stolb: A na stolb: B
Od stolb: C na stolb: B
Od stolb: A na stolb: C
Od stolb: B na stolb: A
Od stolb: B na stolb: C
Od stolb: A na stolb: C

KIP - 6

C

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() {
Imavme 18 povika do bs().
int i, poz, y, x[SIZE], status;
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.

po~etna
lokacija

celna
lokacija

1

1

1

1

1

1

0

0

0

0

0

1

1

1

0

1

1

0

1

1

0

0

0

1

0

1

1

0

1

0

0

1

1

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.
5
int l[100][100], p, q, lpat, mlpat;
0 0 0 0 1
void pat(int i, int j) {
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
Minimalno vreme na izvr{uvawe
Razbirlivost i ~itlivost
Koristewe na minimalen memoriski prostor
Minimalno vreme na preveduvawe

(1)

najva`no
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
a = a*(3.14/180) *4. − b
.
.
.
b = c*(3.14/180)*4. − z

4/9/2013

Podobro re{enie
x = (3.14/180.)*4.
.
.
.
a = a*x − b
b = c*x − z
D. ^akmakov

Najdobro re{enie
#define x = (3.14/180.)*4.
.
.
.
a = a*x − b
b = c*x − z

KIP - 6

17

Soveti za programirawe

(3)

Reduciraj gi povicite do potprogramite i funkciite
x = log(y) + log(z); podobro e
x = pow(y,3);
podobro e

x = log(y*z);
x = y*y*y;

a = min(x,y,3.0)-5;
b = min(x,y,3.0);
podobro e

am = min(x,y,3.0);
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.
for (i=1; i<=n; i++)
podobro e
sum = sum + v*v + a[i];

4/9/2013

D. ^akmakov

sum = 0.
for (i=1; i<=n; i++)
sum = sum + v*v + a[i];
sum = sum + n*v*v;
KIP - 6

18

Soveti za programirawe
• Koristi efikasni

(4)

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) … ;
else if (sim >= 1000) … ;
else if (sim>=200) …;
else if (sim >= 80) …;

Ova e dobro ako najmnogu pati
sim dobiva vrednost pogolema
od 5000, potoa od 1000 itn. (Na
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;
rez = s + t;
4/9/2013

podobro e
D. ^akmakov

rez = a*b + c*c -4.;
KIP - 6

19