[go: up one dir, main page]

0% found this document useful (0 votes)
137 views82 pages

Binder1 PDF

This document provides an overview of the C programming language. It discusses C's history, development in the 1960s by Dennis Ritchie for writing operating systems like UNIX, and how its modern data types, control structures and large number of operators make it an efficient general purpose language. It notes that C's object-oriented extensions like C++ and use for Windows applications have contributed to it being one of the most widely used languages today. Most system software is written in C or C++ due to its efficiency and closeness to operating systems. The document recommends learning C if developing software that will be used for a long time, as C has endured while other languages have come and gone.

Uploaded by

darko sofkovski
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
137 views82 pages

Binder1 PDF

This document provides an overview of the C programming language. It discusses C's history, development in the 1960s by Dennis Ritchie for writing operating systems like UNIX, and how its modern data types, control structures and large number of operators make it an efficient general purpose language. It notes that C's object-oriented extensions like C++ and use for Windows applications have contributed to it being one of the most widely used languages today. Most system software is written in C or C++ due to its efficiency and closeness to operating systems. The document recommends learning C if developing software that will be used for a long time, as C has endured while other languages have come and gone.

Uploaded by

darko sofkovski
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 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