uvod u programiranje predavanja 6 i 7

108
Увод у програмски Увод у програмски језик језик C C Функције Електротехнички факултет у Источном Сарајеву

Upload: dragan-kikic

Post on 04-Jan-2016

29 views

Category:

Documents


8 download

DESCRIPTION

uvod u programiranje

TRANSCRIPT

Page 1: uvod u programiranje predavanja 6 i 7

Увод у програмски језик Увод у програмски језик CC

Функције

Електротехнички факултет у Источном Сарајеву

Page 2: uvod u programiranje predavanja 6 i 7

2

СадржајСадржај

1. Функције

2. Област важења и циклус трајања променљиве

3.3. Рекурзивне функцијеРекурзивне функције

4.4. Претпроцесорске наредбеПретпроцесорске наредбе

Page 3: uvod u programiranje predavanja 6 i 7

3

ФункцијеФункције

• Велики програм се дели на мање делове или модуле које је много лакше дефинисати и контролисати.

• Ти делови се називају потпрограми

• У програмском језику C сви потпрограми се називају функције.

Page 4: uvod u programiranje predavanja 6 i 7

4

Зашто функцијеЗашто функције

• Писање мањих целина које се лакше контролишу

• Примена функције као градивног елемента програма, - могућност да се једном написана функција користи у више различитих програма

• Понављање извршавања истог кôда у програму

Page 5: uvod u programiranje predavanja 6 i 7

5

Функције Функције

Потпрограми

Приликом развоја алгоритма могу се уочити логичке целине, односно поступци обраде које се често пута понављају, најчешће над различитим скупом података. Такве целине треба издвојити у посебне програмске целине - потпрограме.

Коришћењем потпрограма:повећава се прегледност, читљивост програма,смањује се величина програма,постиже се универзалност кода,омогућава се лакше отклањање грешака.

У програмским језицима обично се имплементирају:процедурални потпрограми (procedure)функцијски потпрограми (function)

Програмски језик C има имплементиране само функцијске потпрограме.

Page 6: uvod u programiranje predavanja 6 i 7

6

ФункцијеФункције

Функција се обично дефинише као потпрограм који на основу одређеног броја аргумената даје један резултат.

Податак који функција враћа главном програму или другој функцији назива се вредност функције.

Под типом функције подрсазумева се тип податка који враћа функција.

Процедурални потпрограми (у другим програмским језицима) могу да враћају више података (ниједан податак). Због тога, функције у C-у имају имплементирану могућност да осим резултата – вредност функције, врате више података кроз размену аргумената. Ефекет када функција крооз аргументе враћа резултате назива се бочни ефекат.

Функција може у потпуности да се понаша као процедура, односно може да даје само бочне ефекте.

Page 7: uvod u programiranje predavanja 6 i 7

7

Врсте функцијаВрсте функција

• C програм je најчешће комбинација два типа функција: – функција које пише сам програмер

(корисничке функције) и

– функција које постоје у стандардним библиотекама (библиотечке функције) као што су: printf, scanf, sin, malloc, free, и друге.

Page 8: uvod u programiranje predavanja 6 i 7

8

Особине ФункцијеОсобине Функције

• Функције у математици

• Тип функције (тип повратне вредности)

• Аргументи функције

• Тип аргумената функције

( ) 2 5f x x

Page 9: uvod u programiranje predavanja 6 i 7

9

Библиотечке функцијеБиблиотечке функције• Готове функције које постоје у оквиру програмског

језика

#include <math.h>#include <stdio.h>main(){ double y;

/* poziv bibliotečke funkcije*/ y = floor(2.8); printf( “Ceo deo od 2.8 je %f\n", y ); y = floor( -2.8 ); printf( “Ceo deo od -2.8 je %f\n",y );}

Ceo deo od 2.8 je 2.000000

Ceo deo od -2.8 je -3.000000

Page 10: uvod u programiranje predavanja 6 i 7

10

Корисничке функцијеКорисничке функције

• Функције које дефинише програмер

• Mогу се поделити у две категорије:– Функције које имају тип податка, тј.

функције које враћају неку вредност

– Функције које не враћају вредност и оне се називају воид (void) функције.

Page 11: uvod u programiranje predavanja 6 i 7

11

Функције које враћају вредностФункције које враћају вредност

• Својства функције :1. Име функције

2. Број аргумената функције

3. Тип податка сваког аргумента (формалног)

4. Тип повратне вредности, односно тип функције

5. Шта ради та функција, односно њен кôд.

Page 12: uvod u programiranje predavanja 6 i 7

12

Функције Функције

Дефиниција функције

Општи облик дефиниције функције:

tip ime (arg1, arg2, ... , argN)

definicija_formalnih_argumenata;

{

definicija_lokalnih_promjenljivih;

programski_iskazi;

return (izraz); }

Тип функције

Ако се не наведе подразумева се int

Ако функција не враћа податак, тип је void

Листа формалних аргумената Параметри кроз које функција

прима податке (вредности или адресе)

Дефиниција типова аргумената

Име функције Идентификатор у складу са синтаксом језика

Дефиниција локалних променљивих

Променљиве које се користе у функцији,

Нису видљиве изван функције

Излаз из функције и враћа вредност датог типа

У телу функције може бити више return исказа

Ако функција не враћа ништа, return може да се изостави.

Page 13: uvod u programiranje predavanja 6 i 7

13

Функције Функције

Дефиниција функције

Алтернативни облик дефиниције функције:

tip ime ( tip1 arg1, tip2 arg2, ... , tipN argN )

{ definicija_lokalnih_promjenljivih; programski_iskazi; return (izraz); }

Дефиниција типова аргумената садржана је у листи аргумената

Позивање функције

Општи облик позива функције:

ime ( sarg1, sarg2, ... , sargN )

Листа стварних аргумената Параметри који се шаљу у функцију

(вредности или адресе)Зову се стварни зато што су то

стварни, реални подаци

Page 14: uvod u programiranje predavanja 6 i 7

14

Функције које враћају вредностФункције које враћају вредност

• Заглавље и тело функције

int abs(int x) /* Zaglavlje*/

{

if(x < 0)

x = -x;

return x;

}

• Променљиве које су декларисане у заглављу функције се називају формални аргументи функције

Page 15: uvod u programiranje predavanja 6 i 7

15

Формални и стварни аргументиФормални и стварни аргументи

main(){ double u = 2.5; double v = 3.0; double x,y,z; x=stepen(u,v); /* Linija 1 */ y=stepen(2.0, 3.2); /* Linija 2 */ z=stepen(v,7); /* Linija 3 */ ...}

double stepen(double osnova, double eksponent){ ...}

Формални аргументи

стварни аргументи

Page 16: uvod u programiranje predavanja 6 i 7

16

Дефинисање функцијаДефинисање функција

• Општа синтакса за дефинисање функције је:tip_funkcije ime_funkcije(lista form argumenata)

{

naredbe

}

• Тело функције– Група наредби, део између витичастих заграда

– наредбе могу бити наредбе за дефинисање променљивих (декларативне наредбе) или извршне наредбе

Page 17: uvod u programiranje predavanja 6 i 7

17

Тип функцијеТип функције

• Представља тип вредности коју враћа функција.

• Назива се и тип повратне вредности (return type) функције.

• Уколико се изостави подразумева се тип int.

• За функције које не враћају вредност резервисан је тип void.

Page 18: uvod u programiranje predavanja 6 i 7

18

Тип функцијеТип функције

int ime_funkcije(lista form. argumenata)

double ime_funkcije(lista form. argumenata)

void ime_funkcije(lista form. argumenata)

Page 19: uvod u programiranje predavanja 6 i 7

19

Име функције Име функције

• Додељује се према правилима за доделу имена идентификатора.

• испред имена функције је могуће ставити *, што значи да је повратна вредност функције показивач на податке чији је тип наведен као tip_funkcije

double *treci_stepen(lista form. argumenata)

void *moja_funkcija(lista formalnih argumenata)

Page 20: uvod u programiranje predavanja 6 i 7

20

Листа формалних аргуменатаЛиста формалних аргумената

• Унутар малих заграда наводи се листа аргумената.• Потребно је навести тип податка и његово име.

• Уколико постоји више аргумената они се међусобно

раздвајају зарезом.

tip_funkcije ime_funkcije(tip_prom1 ime_prom1, tip_prom2 ime_prom2,... ,tip_promN ime_promN)

float funPrimer(int a, double b)

Page 21: uvod u programiranje predavanja 6 i 7

21

Листа формалних аргуменатаЛиста формалних аргумената

• Аргумената не мора бити али и у том случају се морају навести мале заграде.

tip_funkcije ime_funkcije()

• У случају да је листа формалних параметара празна, онда приликом позива те функције не треба наводити листу стварних аргумената.

ime_funkcije(); /* poziv*/

Page 22: uvod u programiranje predavanja 6 i 7

22

Наредба Наредба returnreturn

• Након што се унутар тела функције израчуна вредност коју функција треба да врати, та вредност се враћа помоћу наредбе return.

• Општи облик синтаксе за враћање вредности је return izraz;

• izraz може да буде променљива, константа или неки израз чијим израчунавањем се добија жељена вредност.

Page 23: uvod u programiranje predavanja 6 i 7

23

Наредба Наредба returnreturn

• Након извршења наредбе return функција се тренутно напушта, а контролу преузима део програма одакле је функција позвана.

• Наредба којом је позвана функција се „замењује” са вредношћу коју враћа функција, тј. са вредношћу поред наредбе return.

Page 24: uvod u programiranje predavanja 6 i 7

24

Наредба Наредба returnreturnfloat manji(float x,float y){ float pom; if(x<=y) pom=x; else pom=y; return pom;}

1

float manji(float x, float y){ if(x<=y)

return x; 2 else return y; }

float manji(float x, float y){

if(x<=y) 3 return x; return y; }

Page 25: uvod u programiranje predavanja 6 i 7

26

Прототип функцијеПрототип функције

• Идентификатор (име функције или променљиве) мора се декларисати пре прве употребе, (пре функције main)

• У пракси се обично прво пише функција main пре свих осталих корисничких функција.

• Овај проблем је могуће решити увођењем прототипа функције пре дефинисања било које функције (укључујући и функцију main)

Page 26: uvod u programiranje predavanja 6 i 7

27

Прототип функцијеПрототип функције

• Прототип функције представља заглавље функције (без навођења тела функције). Прототип функције је обавезно завршити са знаком тачка-зарез (;)

tip_funkcije ime_funkcije(lista formalnih arg.);

• Прототип за функцију manji је:

float manji(float x, float y);

• Није неопходно да се наведе име променљиве у листи аргумената, мора се навести тип аргумента.

float manji(float , float );

Page 27: uvod u programiranje predavanja 6 i 7

28

Прототип функцијеПрототип функције

Декларације функције (прототип)

Прототип или декларација функције представља њен ”опис за спољашњи свет”

Из прототипа се види како се комуницира са датом функцијом, јер садржи:

тип функције,име функције,типове (а може и имена) аргумената.

Општи облик прототипа је:

tip ime ( tip1, tip2, ... , tipN );

Пример:int zbir( int a, int b )

{ return (a+b); }

int zbir( int, int );

void poruka ()

{ printf(”Zdravo!”); }

void poruka ();

Page 28: uvod u programiranje predavanja 6 i 7

29

функцијефункције

Структура C програма

Уобичајена је следеће структура:

pretprocesorske direktive

prototip funkcija

main

definicija funkcija

Алтернативно је могуће и:

pretprocesorske direktive definicija funkcija main

Погодно када имамо мали број функција

Ако функција позива неку другу функцију, функција која се позива мора претходно бити дефинисана

Пример:

#include <stdio.h>

void poruka ();

main() { poruka(); }

void poruka () { printf(”Zdravo!”); }

Page 29: uvod u programiranje predavanja 6 i 7

30

vvoidoid функције функције

• Функције које не враћају вредност

• tip_funkcije који представља тип повратне вредности као и наредба return немају посебног значаја.

• У void функцијама се може користити наредба return али без израза поред ње, користи се за напуштање

функције пре њеног краја.

• void функције могу али не морају имати аргументе

Page 30: uvod u programiranje predavanja 6 i 7

31

Прослеђивање вредности аргуменатаПрослеђивање вредности аргумената

• Приликом позива функције у малим заградама се наводи листа аргумената. По начину преношења вредности, уопштено гледано, постоји две врсте аргумената :

1. Аргументи који се прослеђују преко вредности (value arguments)

2. Аргументи који се преносе помоћу адресе (reference arguments)

Page 31: uvod u programiranje predavanja 6 i 7

32

Пример 1:Пример 1:

Учитати дужине страница правоугаоника, а затим израчунати и исписати обим и површину. Обим треба да се рачунау функцији obim, а површина у функцији povrs.

#include <stdio.h>

float obim(float, float);

float povrs(float s1, float s2);

main(){ float a,b, o,p; printf(”Stranica a: ”); scanf(”%d”, &a); printf(”Stranica b: ”); scanf(”%d”, &b); o = obim(a,b); p = povrs(a,b); printf(”Obim : %7.3f\n”, o); printf(”Povrsina : %7.3f\n”, p);}

float obim (float x, float y) { return ( 2*x + 2*y ); }

float povrs (float c, float d) { return ( c*d ); }

Prototip funkcije obim

Navedeni samo tipovi argumenata

Prototip funkcije povrs

Navedeni tipovi i imena argumenata

Poziv funkcije obimPoziv funkcije povrs

Šalju se stvarni podaci a i b

Definicija funkcije obim

Funkcija prihvata proslijeđene vrijednosti (a i b) kroz formalne argumente x i y

Funkcija izračunava obim 2*x+2*y i to vraća u glavni program

Page 32: uvod u programiranje predavanja 6 i 7

33

Пример 2:Пример 2:

Функција која не враћа вредност:

#include <stdio.h>

void kvadrat ( int );

main(){ int i,n;

do { printf(”n = ”); scanf(”%d”, &n); } while (n<1);

for (i=1; i<=n; i++) kvadrat(i);}

void kvadrat (int k) { int kv; kv = k * k; printf(”%5d %5d\n”, k, kv); }

Функција kvadrat не враћа вредност (void)

Оваква функција понаша се као процедурални потпрограм

n = 4....1 ....1....2 ....4....3 ....9....4 ...16

Page 33: uvod u programiranje predavanja 6 i 7

34

Пример 3:Пример 3:Програм који исписује првих n простих бројева. Провера да ли је број прост врши се у функцији prost.

#include <stdio.h>#include <math.h>int prost (int);main(){ int i=1, broj=1, n; do { printf(”n = ”); scanf(”%d”, &n); } while (n<1); printf(”To su brojevi:\n”);

while (i<=n)

{

if ( prost(broj) )

{ printf(” %d”, broj); i++; }

broj++;

}

}

int prost (int b){ int d=3, pom; pom = (b%2) || (b==2); while (pom && d<=sqrt(b)) { pom = b%2; d += 2; } return(pom);

}

n = 6To su brojevi: 1 2 3 5 7 11

Page 34: uvod u programiranje predavanja 6 i 7

35

Пренос параметра у функцију преко ВРЕДНОСТИУ претходним примери кориштен је пренос параметра по ВРЕДНОСТИ:

1. приликом позива функције шаље се вредност • као стварни аргумент може да се наведе: име променљиве, нека константа или израз• израчунава се вредност израза и та вредност се шаље у функцију

2. функција прихвата послате вредности у формалне аргументе• формални и стварни аргументи морају да се слажу у:

броју, редоследу i типу• формални аргументи (променљиве) аутоматски настају приликом

уласка у функцију и преузимају прослеђене вредности

3. по изласку из функције формални аргументи аутоматски нестају

• аутоматски настају и нестају па се називају аутоматске променљиве

У функцији се формира слика стварних аргумената и користе се те слика, а не стравне променљиве из главног програма,

зато након изласка из функције променљиве у главном програму остају непромењене!!!

Page 35: uvod u programiranje predavanja 6 i 7

36

Пример 4:Пример 4:

Илустрација преноса параметара путем вредности.

#include <stdio.h>

void f (int);

main(){ int i=10; printf(”main: %d\n”,i);

f(i); printf(”main: %d\n”,i);

}

void f (int k){ printf(”f: %d\n”,k); k=20; printf(”f: %d\n”,k);

}

main: 10

MEMOРИJA

i10

k1020

f: 10f: 20main: 10

Page 36: uvod u programiranje predavanja 6 i 7

39

ПримерПример

• Након линије 3 извршена је иницијализација

Linija 4: Unutar funk. main num1=10, num2=15, ch=A

main

10

15

A

.

.

.

.

.

.

.

.

.

1200

add

1430

1620

ime

num1

num2

ch

main( ){ int num1, num2, char ch;

num1=10; /*L1*/

num2=15; /*L2*/

ch='A'; /*L3*/

Page 37: uvod u programiranje predavanja 6 i 7

40

main( ){ int num1, num2; char ch; num1=10; /* L1*/ num2=15; /* L2*/ ch='A'; /* L3*/ printf("Linija 4: ....); funJedan(num1, &num2, ch); /* L5*/

Page 38: uvod u programiranje predavanja 6 i 7

41

ПримерПример funJedan(num1, &num2, ch); /* L5 poziv*/

void funJedan(int a, int *b, char v)

{

int jedan;

...

10

1430

A

.

.

.

.

.

.

.

.

. ??

funJedan

.

.

10

15

A

.

.

.

.

.

.

.

.

.

1200

add

1430

1620

ime

num1

num2

ch

ime

a

b

v

jedan

main

Page 39: uvod u programiranje predavanja 6 i 7

42

void funJedan(int a, int *b, char v){ int jedan; jedan=a; /* L 9 */ a++; /* L10 */ *b=(*b)*2; /* L11 */ v='B'; /* L12 */ printf("Linija 13: Unutar funJedan a=%d, *b=%d, v=%c\n",a,*b,v);

}

Page 40: uvod u programiranje predavanja 6 i 7

43

ПримерПример

• У линији 9, након наредбе jedan=a;

a

b

v

jedan

num11200

num2

ch

funJedan main

10

15

A

.

.

.

.

.

.

.

.

.

10

1430

A

.

.

.

.

.

.

.

.

. 10

1200

14300

1620

Page 41: uvod u programiranje predavanja 6 i 7

44

void funJedan(int a, int *b, char v){ int jedan; jedan=a; /* L 9 */ a++; /* L10 */ *b=(*b)*2; /* L11 */ v='B'; /* L12 */ printf("Linija 13: Unutar funJedan a=%d, *b=%d, v=%c\n",a,*b,v);

}

Page 42: uvod u programiranje predavanja 6 i 7

45

ПримерПример

• Након линије 10 (а++):

10

15

A

.

.

.

.

.

.

.

.

.

main

ime: num2

ime: ch

ime: num1

adresa:14300

adresa:1200

adresa:16200

11

1430

A

.

.

.

.

.

.

.

.

.

ime: а

ime: b

ime: v

ime: jedan 10

funJedan

Page 43: uvod u programiranje predavanja 6 i 7

46

void funJedan(int a, int *b, char v){ int jedan; jedan=a; /* L 9 */ a++; /* L10 */ *b=(*b)*2; /* L11 */ v='B'; /* L12 */ printf("Linija 13: Unutar funJedan a=%d, *b=%d, v=%c\n",a,*b,v);

}

Page 44: uvod u programiranje predavanja 6 i 7

47

ПримерПример

• Након наредбе *b=(*b)*2; у линији 11

10

30

A

.

.

.

.

.

.

.

.

.

main

ime: num2

ime: ch

ime: num1

adresa:14300

adresa:1200

adresa:16200

11

1430

A

.

.

.

.

.

.

.

.

.

ime: а

ime: b

ime: v

ime: jedan 10

funJedan

Page 45: uvod u programiranje predavanja 6 i 7

48

void funJedan(int a, int *b, char v){ int jedan; jedan=a; /* L 9 */ a++; /* L10 */ *b=(*b)*2; /* L11 */ v='B'; /* L12 */ printf("Linija 13: Unutar funJedan a=%d, *b=%d, v=%c\n",a,*b,v);

}

Page 46: uvod u programiranje predavanja 6 i 7

49

ПримерПример

• Након наредбе v='B' у линији 12

10

30

A

.

.

.

.

.

.

.

.

.

main

ime: num2

ime: ch

ime: num1

adresa:14300

adresa:1200

adresa:16200

11

1430

B

.

.

.

.

.

.

.

.

.

ime: а

ime: b

ime: v

ime: jedan 10

funJedan

Page 47: uvod u programiranje predavanja 6 i 7

50

void funJedan(int a, int *b, char v){ int jedan; jedan=a; /* L 9 */ a++; /* L10 */ *b=(*b)*2; /* L11 */ v='B'; /* L12 */ printf("Linija 13: Unutar funJedan a=%d, *b=%d, v=%c\n",a,*b,v);

}

а=11, *b=30, v=B

Page 48: uvod u programiranje predavanja 6 i 7

51

ПримерПример

• након извршавања наредбе у линији 13 напушта се функција funJedan и програм наставља да се извршава у линији L6 функције main

10

30

A

.

.

.

.

.

.

.

.

.

main

ime: num2

ime: ch

ime: num1

adresa:14300

adresa:1200

adresa:16200

Page 49: uvod u programiranje predavanja 6 i 7

52

main( ){ int num1, num2; char ch; num1=10; /* L 1 */ num2=15; /* L 2 */ ch='A'; C /* L 3 */ printf("Linija 4: ....); funJedan(num1, &num2, ch); /* L 5 */ printf("Linija 6: Unutar...); funDva(&num2, 25, &ch); /* L 7*/ printf("Linija 8: ...);}

Page 50: uvod u programiranje predavanja 6 i 7

53

ПримерПримерfunDva(&num2, 25, &ch) /* L7 poziv */

void funDva(int *x, int y, char *w);

{

...

10

30

A

.

.

.

.

.

.

.

.

.

main

ime: num2

ime: ch

ime: num1

adresa:14300

adresa:1200

adresa:16200

1430

25

1620

.

.

.

.

.

.

.

.

.

ime: x

ime: y

ime: w

funDva

Page 51: uvod u programiranje predavanja 6 i 7

54

void funDva(int *x, int y, char *w){ (*x)++; /* L14*/ y=y*2; /* L15*/ *w='G'; /* L16*/ printf("Linija 17: Unutar funDva *x=%d, y=%d, *w=%c\n",*x,y,*w);

}

Page 52: uvod u programiranje predavanja 6 i 7

55

ПримерПример

• Након извршавања наредбе у линији 14, (*x)++

10

31

A

.

.

.

.

.

.

.

.

.

main

ime: num2

ime: ch

ime: num1

adresa:14300

adresa:1200

adresa:16200

1430

25

1620

.

.

.

.

.

.

.

.

.

ime: x

ime: y

ime: w

funDva

Page 53: uvod u programiranje predavanja 6 i 7

56

void funDva(int *x, int y, char *w){ (*x)++; /* L14*/ y=y*2; /* L15*/ *w='G'; /* L16*/ printf("Linija 17: Unutar funDva *x=%d, y=%d, *w=%c\n",*x,y,*w);

}

Page 54: uvod u programiranje predavanja 6 i 7

57

ПримерПример

• Наредба у линији 15 (y=y*2) даје следеће

10

31

A

.

.

.

.

.

.

.

.

.

main

ime: num2

ime: ch

ime: num1

adresa:14300

adresa:1200

adresa:16200

1430

50

1620

.

.

.

.

.

.

.

.

.

ime: x

ime: y

ime: w

funDva

Page 55: uvod u programiranje predavanja 6 i 7

58

void funDva(int *x, int y, char *w){ (*x)++; /* L14*/ y=y*2; /* L15*/ *w='G'; /* L16*/ printf("Linija 17: Unutar funDva *x=%d, y=%d, *w=%c\n",*x,y,*w);

}

Page 56: uvod u programiranje predavanja 6 i 7

59

ПримерПример

• Након линије 16 (*w='G')

10

31

G

.

.

.

.

.

.

.

.

.

main

ime: num2

ime: ch

ime: num1

adresa:14300

adresa:1200

adresa:16200

1430

50

1620

.

.

.

.

.

.

.

.

.

ime: x

ime: y

ime: w

funDva

Page 57: uvod u programiranje predavanja 6 i 7

60

void funDva(int *x, int y, char *w){ (*x)++; /* L14*/ y=y*2; /* L15*/ *w='G'; /* L16*/ printf("Linija 17: Unutar funDva *x=%d, y=%d, *w=%c\n",*x,y,*w);

}

*x=31, y=50, *w=G

Page 58: uvod u programiranje predavanja 6 i 7

61

ПримерПример

• Након завршетка наредбе у линији 17 напушта се функциа funDva и враћа се у линију 8 функције main.

10

31

G

.

.

.

.

.

.

.

.

.

main

ime: num2

ime: ch

ime: num1

adresa:14300

adresa:1200

adresa:16200

Page 59: uvod u programiranje predavanja 6 i 7

62

main( ){ int num1, num2; char ch; num1=10; /* L 1 */ num2=15; /* L 2 */ ch='A'; C /* L 3 */ printf("Linija 4: ....); funJedan(num1, &num2, ch); /* L 5 */ printf("Linija 6: Unutar...); funDva(&num2, 25, &ch); /* L 7*/ printf("Linija 8: ...); /* L 8*/}

Page 60: uvod u programiranje predavanja 6 i 7

63

ПримерПример

• Након линије 8 се прекида извршавање програма и ослобађа меморијски простор

nim1=10, num2=31, ch=G

Page 61: uvod u programiranje predavanja 6 i 7

64

Домени и меморијске класеДомени и меморијске класе

Домен идентификатора

Домен (област дефинисаности, област важења ) идентификатора (променљиве) је подручје програма у којем је тај идентификатор доступан по имену (видљив)

Основно правило:Идентификатор је доступан у блоку у којем

је дефинисан, као и у свим угњежденим блоковима, осим аку у њима није маскоран другим идентификатором са истим именом!

Пример:

#include <stdio.h>main(){ int x=1; printf(”Pre bloka: %d\n”,x); { int x=0; printf(”U bloku: %d\n”,x); } printf(”Posle bloka: %d\n”,x);}

Pre bloka: 1U bloku: 0Posle bloka: 1

У угњежденом блоку је

дефинисана променљива са истим именом,

чиме је маскирана променљива x iz funkcije main()

Page 62: uvod u programiranje predavanja 6 i 7

65

Домени и меморијске класеДомени и меморијске класеМеморијске класе променљивих

У програмском језику C разликујемо 4 меморијске класе променљивих:

• глобалне

дефинишу се изван свих функција

• статичке

дефинишу се помоћу кључне речи static static tip ime=vrednost

• аутоматске

дефинишу се помоћу кључне речи auto auto tip ime=vrednost

подразумева се да је променљива аутоматска, ако се другачије не наведе

• регистрске

дефинишу се помоћу кључне речи register register tip ime=vrednost

Page 63: uvod u programiranje predavanja 6 i 7

66

Домени и меморијске класеДомени и меморијске класе

Аутоматске променљиве

Аутоматске променљиве дефинишу се на почетку тела функције (главног програма или потпрограма). Често се користи термин локална променљива.

Почетна вредност им се не подразумева!!! (То значи није нула!!!)

Могу да се користе само у функцији у којој су дефинисане. То значи да исто име можемо да користимо независно у више различитих функција. Чак те променљиве могу да буду и различитих типова.

Аутоматски настају прилико уласка у функцију, и аутоматски нестају након изласка из функције.

Подразумева се да је променљива аутоматска ако се другачије не наведе.

Не мора се експлицитно наводити да се ради о аутоматској променљивој, али може помоћу речи auto

auto tip ime=vrednost;

Page 64: uvod u programiranje predavanja 6 i 7

67

Домени и меморијске класеДомени и меморијске класе

Рад са аутоматским променљивама.

#include <stdio.h>

void f1 () { int i=1; printf(”f1: %d\n”, i); }

void f2 () { int i=2; printf(”f2: %d\n”, i); i=10; }

main(){ int i=0; printf(”main: %d\n”, i); f1(); printf(”main: %d\n”, i); i=5; f2(); printf(”main: %d\n”, i);}

main: 0 f1: 1main: 0 f2: 2main: 0

Page 65: uvod u programiranje predavanja 6 i 7

68

Домени и меморијске класеДомени и меморијске класе

Статичке променљиве

• Дефинишу се навођењем кључне речи static static tip ime=vrednost

• Вредност им се одређује пре почетка извршавања програма • Узима се експлицитна вредност којом је иницијализована променљива.

Подразумева се да је почетна вредност нула, ако се другачије или ништа не наведе

• Имају трајан карактерПостоје у меморији од почетка до краја извођења програмаВредност остаје сачувана до следећег позива те функције

Page 66: uvod u programiranje predavanja 6 i 7

69

Домени и меморијске класеДомени и меморијске класе

Рад са астатичком променљивом.

#include <stdio.h>

void f () { static int brs=1; auto int bra=1; printf(”static brs=%d auto bra=%d\n”, brs, bra); brs++; bra++; }

main(){ int i; for (i=1; i<=3; i++) f();}

static brs=1 auto bra=1 static brs=2 auto bra=1 static brs=3 auto bra=1

Page 67: uvod u programiranje predavanja 6 i 7

70

Глобалне променљивеГлобалне променљиве

• Променљиве које су заједничке за већи број функција.

• Дефинишу се изван било које функције.

• Досег :од места где је дефинисан до краја фајла у ком се налази та наредба.

Page 68: uvod u programiranje predavanja 6 i 7

71

Глобалне променљивеГлобалне променљиве

• Функције које сачињавају програм не морају бити у једном фајлу.

• Скуп тих фајлова: пројекат.

• Сваки фајл унутар пројекта се преводи независно.

• Након успешног превођења врши се повезивање (linking) преведених фајлова у извршни програм.

Page 69: uvod u programiranje predavanja 6 i 7

72

Глобалне променљивеГлобалне променљиве

• Глобални идентификатори могу имати досег на све фајлове у пројекту.

• У сваком од фајлова треба да постоји декларација глобалног податка или функције која ће се у њему користити.

• У тачно једном од фајлова дефиниција.• У сваком фајлу у ком се користи

глобална променљива дефинисана у другом фајлу мора постојати тзв. екстерн (extern) декларација.

Page 70: uvod u programiranje predavanja 6 i 7

73

Домени и меморијске класе - Домени и меморијске класе - Глобалне променљивеГлобалне променљиве

Глобалне променљиве дефинишу се изван свих функција. Ако се у дефиницији не наведе почетна вредност подразумева се нула!!!

Глобална променљива доступна је у свим функцијама које су дефинисане након дефиниције дате променљиве.

Глобалне променљиве омогућавају да више функција манипулише истим скупом података, па самим тим омогућавају ефикасну размену података између функција (јер све функције приступају истим меморијским локацијама).

Page 71: uvod u programiranje predavanja 6 i 7

74

Домени и меморијске класе - Домени и меморијске класе - Глобалне променљивеГлобалне променљиве

Треба их избегавати јер се губи универзалност функције и флексибилност примене на различите сетове података.

Ако се у некој функцији дефинише променљива са истијм именом као нека глобална, тада та локална променљива маскира глобалну и глобалној се не може приступити из те функције.

Ако се у некој функцији користи нека глобална променљива то може да се експлицитно нагласи декларацијом коришћењем кључне речи extern, иако не постоји обавезада се глобалне променљиве декларишу у функцији

extern tip promjenljiva;

Page 72: uvod u programiranje predavanja 6 i 7

75

Домени и меморијске класеДомени и меморијске класе

Рад са глобалним променљивимРад са глобалним променљивим#include <stdio.h>

void f1 () { int i=1; printf(”f1: %d\n”, i); }

int i;

void f2 () { extern int i; printf(”f2: %d\n”, i); i=10; }

main(){ printf(”main: %d\n”, i); f1(); printf(”main: %d\n”, i); i=5; f2(); printf(”main: %d\n”, i);}

main: 0 f1: 1main: 0 f2: 5main: 10

Глобална променљива

i=0

Глобална променљива i није видљива у функцији f1() јер је дефинисана након функције.

У функцији f1() расположива је локална променљива i.

У функцији f2() користи се глобална, екстерна променљива i.

Декларације extern int i могла је да се изостави

Page 73: uvod u programiranje predavanja 6 i 7

76

Глобалне променљивеГлобалне променљиве

FILENAME1.c 1 extern int brojac; 2 int rezultat=2; 3 void funkcija_1(); 4 int main() 5 { 6 int i= 4; 7 printf("M3: %d, %d\n", brojac, rezultat); 8 rezultat++; 9 brojac=rezultat*i;10 printf("M6: %d, %d\n", brojac, rezultat);11 funkcija_1(); 12 printf("M8: %d, %d\n", brojac, rezultat);13 return 0;14 }

Page 74: uvod u programiranje predavanja 6 i 7

77

Глобалне променљивеГлобалне променљиве

FILENAME2.c 1 extern int rezultat;

2 int brojac = 0

3 void funkcija_1()

4 {

5 printf("F1: %d %d\n", brojac,rezultat);

6 rezultat=5;

7 brojac=1;

8 printf("F4: %d %d\n", brojac, rezultat);

9 return;

10 }

Page 75: uvod u programiranje predavanja 6 i 7

78

Домени и меморијске класеДомени и меморијске класе

Регистарске променљиве

Registarske promjenljive su automatske promjenljive za koje je izražena želja da se drže u registrima procesora, a ne u memoriji, kako bi se dobilo na brzini.

Poželjno je korišćenje registarskih promjenljivih kod promjenljivih koje se često koriste (npr. brojač)

Ne garantuje se da će promjenljiva stvarno i biti registarska. To zavisi i od konkretnog prevodioca, procesora , ukupnog broja registarskih promjenljivih do trenutka deklaracije date promjenljive...

Broj registarskih promjenljivih je ograničen i malen.

Registarske promjenljive definišu se uz pomoć ključne riječi registerregister tip ime=vrijednost

Primjer:register int i=10;register j;

Page 76: uvod u programiranje predavanja 6 i 7

79

Вектор (поље) као аргумент Вектор (поље) као аргумент функцијефункције

Пренос вектора (поља) врши се путем адресе

1. приликом позива функције шаље се адреса низа (вектора) • као стварни аргумент наводи се име низа (име низа је почетна адреса низа) 2. функција прихвата адресу низа • формални аргумент у дефиницији функције мора да садржи [ ]

број елемената низа не мора да се наводи • не ствара се копија низа већ се ради са стварним подацима

У функцији се манипулише стварним подацима, а не копијом низа. Зато функција може да промени низ, па по повратку из функције немамо оригинални него

модификовани низ !!!

Page 77: uvod u programiranje predavanja 6 i 7

80

Пример 5: Вектор као аргумент Пример 5: Вектор као аргумент функцијефункције

Програм учитава низ, позива потпрограм који проналази и враћа највећи елемент низа, који се штампа у програму.

#include <stdio.h>

int max ( int niz[], int n);

main(){ int a[] = { 2,15,5,0,8 }; int n = 5; printf(”Najveci: %d\n”, max( a,n ) );

}

int max ( int niz[], int n ){ int i, m=niz[0]; for (i=1; i<n; i++) if (niz[i]>m) m=a[i]; return (m);

}

Najveci: 15

Формални аргумент

Декларација низа без димензије

Могло је и int niz[5]

Позив функције

Шаље се адреса низа

Page 78: uvod u programiranje predavanja 6 i 7

81

Пример 6: Вектор као аргумент Пример 6: Вектор као аргумент функцијефункције

Програм позива функције за сортирање и исписивање низа.

#include <stdio.h>

void sort ( int niz[], int n);void pisi ( int niz[], int n);

main(){ int a[] = { 2,15,5,0,8 }; printf(”Pre:”); pisi( a,n ); sort( a,n ); printf(”Posle:”); pisi( a,n ); }

void pisi ( int niz[], int n ){ int i; for (i=0; i<n; i++) printf(” %d”, niz[i]); printf(”\n”); }

void sort ( int niz[], int n ){ int i,j,rb,pom; for (i=0; i<n-1; i++) { for (rb=i, j=i+1; j<n; j++) if (niz[j]<niz[rb]) rb=j; if (rb!=i) { pom=niz[i]; niz[i]=niz[rb]; niz[rb]=pom; } }}

Pre: 2 15 5 0 8Posle: 0 2 5 8 15

Page 79: uvod u programiranje predavanja 6 i 7

82

Вишедимензионално поље као Вишедимензионално поље као аргумент функцијеаргумент функције

Пренос вишедимензионалног поља врши се путем адресе

У декларацији формалних аргумената:

• прва димензија не мора да се наведе (може само [ ] )

• остале димензије морају да се наведу

Пример:

int funkcija (int a[][10][10], int p, int q)

или

int funkcija (int a[10][10][10], int p, int q)

У функцији се ради са стварним подацима,а не са копијом поља. Зато по повратку из функције поље

може бити модификовано !!!

Page 80: uvod u programiranje predavanja 6 i 7

83

Пример 7: Поље као аргумент Пример 7: Поље као аргумент функцијефункције

Програм позива потпрограме за испис и транспоновање матрица.

#include <stdio.h>

void tran ( int m[10][10], int n);void pisi ( int m[10][10], int n);

main(){ int a[10][10] = { {1,2},{3,4} }; printf(”Pre:\n”); pisi(a,n); tran( a,n ); printf(”Posle:\n”); pisi(a,n); }

void pisi (int m[10][10], int n){ int i,j; for (i=0; i<n; i++) { for (j=0; j<n; j++) printf(” %4d”, m[i][j]); printf(”\n”); }}

void tran (int m[10][10], int n){ int i,j,pom; for (i=0; i<n; i++) for (j=i+1; j<n; j++) { pom=m[i][j]; m[i][j]=m[j][i]; m[j][i]=pom; } }}

Pre: 1 2 3 4Posle: 1 3 2 4

Page 81: uvod u programiranje predavanja 6 i 7

84

Рекурзивне функције

Page 82: uvod u programiranje predavanja 6 i 7

85

Рекурзивне функцијеРекурзивне функције

• Функције које могу да позову саме себе

• Своде сложен проблем на једноставнији проблем (исте природе) који могу да реше.

Page 83: uvod u programiranje predavanja 6 i 7

86

Рекурзивне функцијеРекурзивне функције

• Пример: рачунање факторијела n! =n*(n-1)*(n-2)*(n-3)*...*1

1! = 1

0! = 1

4! = 4*3*2*1=4*(3*2*1) = 4*(3!)

3! = 3*2*1=3*(2*1) = 3*(2!)

2! = 2*1=2*(1) = 2*(1!)

1! = 1

Page 84: uvod u programiranje predavanja 6 i 7

87

Рекурзивне функцијеРекурзивне функције

long faktorijel(long broj);

main(){ ... faktorijel(4); ...}

long faktorijel(long broj){ if( broj <= 1 ) return 1; else return (broj * faktorijel(broj - 1) ); }

Page 85: uvod u programiranje predavanja 6 i 7

88

Рекурзивне функцијеРекурзивне функције

broj=4зато што je broj>1 return (4*faktorijel(3));

faktorijel(4)

broj=3зато што je broj>1 return (3*faktorijel(2));

faktorijel(3)

broj=2зато што je broj>1 return (2*faktorijel(1));

faktorijel(2)

broj=1

return (1);

faktorijel(1)

2*1=2

3*2=6

4*6=24

Page 86: uvod u programiranje predavanja 6 i 7

89

Рекурзивне функцијеРекурзивне функције

Rekurzivne funkcije (REKURZIJE)

Rekurzivna funkcija je funkcija koja sama sebe poziva!!!

Primer:

faktorijel: n! = n * (n-1)!, n>0; 0!=1

stepenovanje: xn = x * xn-1, n>0; x0=1

Fibonačijev niz: fn = fn-1 * fn-2, n>1; f0=0, f1=1

Opšte karakteristike rekurzivnih (rekurentnih) rješenja:

• problem se svodi na rešavanje istog problema, ali jednostavnijeg

• funkcija poziva samu sebe sve dok se problem ne pojednostavi do trivijalnog

• rekurzivna rešenja su manje efikasna (veći zahtjev za memorijom)

• treba ih izbjegavati, ali postoje problemi koji su po prirodi rekurzivni i koje je gotovo nemoguće rešiti bez rekurzije

Page 87: uvod u programiranje predavanja 6 i 7

90

Рекурзивне функцијеРекурзивне функције

Matematički opis rekurzije:

n! = n * (n-1)!, n>0; 0!=1

Primer: Rekurzivno izračunavanje faktorijela.

3! = 3 * 2!

2! = 2 * 1!

1! = 1 * 0!

0! = 1

1*1 = 1

2*1 = 2

3*2 = 6

int fakt (int n){ if (n == 0) return (1); else return (n * fakt(n-1));}

int fakt (int n){ return (n==0 ? 1 : n*fakt(n-1));}

Page 88: uvod u programiranje predavanja 6 i 7

91

Рекурзивне функцијеРекурзивне функције

Primer: Rekurzivna funkcija za konverziju dekadnog u binarni brojni sistem.

1410 = ?2

void kon (int b){ int cif; cif = b % 2; b /= 2; if (b>0) kon (b); printf(”%d”,cif); }

19 : 2

9 1

4 1

2 0

1 0

0 1

1410 = 100112

19cif=1b=9kon(9) => cif=1 b=4

kon(4) => cif=0 b=2

kon(2) => cif=0 b=1 kon(1) => cif=1

b=0”1”

”0” <= ”0” <=

”1” <= ”1” <=

Page 89: uvod u programiranje predavanja 6 i 7

92

ПретпроцесорПретпроцесор

• Уметање садржаја фајла (наредба #include)

• Замена лексичких симбола (наредба #define)

– Дефинисање симболичких константи

– Дефинисање макро-а

• Условно превођење (наредба #if, #ifdef, ...)

Page 90: uvod u programiranje predavanja 6 i 7

93

ПретпроцесорПретпроцесор

• Претпроцесорске наредбе не представљају део програмског језика C

• Претпроцесор је део преводиоца који треба да изврши предобраду кôда.

• Обавља одговарајуће трансформације текста којима се добија коначан облик изворног кôда који треба да буде преведен.

Page 91: uvod u programiranje predavanja 6 i 7

94

ПретпроцесорПретпроцесор

• Претпроцесорска наредба се пише у засебном реду и почиње са знаком #.

• Испред ње не могу бити друге наредбе.

• Пре превођења замењује текст у изворном кôду.

Page 92: uvod u programiranje predavanja 6 i 7

95

ПретпроцесорПретпроцесор

• Претпроцесорске наредбе се не завршавају знаком ;

• Могу да се уведу на било ком месту у програму.

• Дејство: од појављивања па надаље, док се посебном наредбом не укину или до краја програма.

Page 93: uvod u programiranje predavanja 6 i 7

96

ПретпроцесорПретпроцесор

• Неке од важнијих претпроцесорских наредби које препоручује АNSI стандард су следеће:

#include#define#if#ifdef#ifndef#elif#else#endif#undef

Page 94: uvod u programiranje predavanja 6 i 7

97

Уметање садржаја фајлаУметање садржаја фајла

Наредба #include#include ″ime fajla″

#include <ime fajla>

• Тражени фајл може и сам да садржи наредбу #include.

Page 95: uvod u programiranje predavanja 6 i 7

98

Замена лексичких симболаЗамена лексичких симбола

Наредба #define

• Користи се за дефинисање симболичких константи и макро-а.

#define SIMBOLICKA_KONSTANTA ZnakovniNiz

Пример:#define PI 3.1415926#define NASLOV "Programski jezik C"#define ZAUVEK for( ; ; )

Page 96: uvod u programiranje predavanja 6 i 7

99

Дефинисање симболичке константеДефинисање симболичке константе

• Претпроцесор претражује изворни кôд и након појављивања наредбе облика

#define SIMBOLICKA_KONSTANTA ZnakovniNiz

свако појављивање SIMBOLICKA_KONSTANTA замењује са ZnakovniNiz.

• у коментару или унутар неког другог знакованог низа неће доћи до замене.

Page 97: uvod u programiranje predavanja 6 i 7

100

Дефинисање симболичке константеДефинисање симболичке константе

#include<stdio.h>#define PI 3.1415926

main(){ float a; float r=4.23; char ch[ ]="PILICI"; /* slogovi PI LI CI */ /*L3*/ a=2*r*PI; /*L5*/ printf("Niz ch je %s a obim a je %f\n ",ch,a);} ИзлазNiz ch je PILICI a obim a je 26.577874

Page 98: uvod u programiranje predavanja 6 i 7

101

Дефинисање симболичке константеДефинисање симболичке константе

#include <stdio.h>#define WIDTH 80 /* L1 */#define LENGTH ( WIDTH + 10 ) /* L2 */ main(){ int var; var = LENGTH * 20; /* var=(80+10)*20;*/ printf("var=%d\n",var) ...}var=1800

Page 99: uvod u programiranje predavanja 6 i 7

102

Дефинисање симболичке константеДефинисање симболичке константе

• Значење претпроцесорске наредбе #define SIMBOLICKA_KONSTANTA

се може укинути наредбом:

#undef SIMBOLICKA_KONSTANTA

Page 100: uvod u programiranje predavanja 6 i 7

103

Дефинисање симболичке константеДефинисање симболичке константе

include <stdio.h>#define WIDTH 80main(){ int x=2,y; y=WIDTH*x; printf("Vrednost y=%d\n",y); #undef WIDTH y=WIDTH; /* GRESKA! 'WIDTH':undeclared identifier */}

Page 101: uvod u programiranje predavanja 6 i 7

104

Дефинисање макро-аДефинисање макро-а

#define IME(par_a, par_b,...) Zakovni_niz

• Макро-и су веома слични функцијама,начин њиховог коришћења и извршавања је различит.

• Макро-и се замењују пре превођења програма

• Функције постоје и за време извршавања програма.

Page 102: uvod u programiranje predavanja 6 i 7

105

Дефинисање макро-аДефинисање макро-а

#include<stdio.h>#define MAX(a,b) a>b ? a : b

main()

{

int broj_a, broj_b;

printf("Odredjivanje maksimuma\n\n");

printf("Upisite dva broja\n");

scanf("%d %d",&broj_a,&broj_b);

printf("Veci broj je: %d\n", MAX(broj_a,broj_b));

}

Odredjivanje maksimuma

Upisite dva broja

4,9

Veci broj je: 9

Page 103: uvod u programiranje predavanja 6 i 7

107

Условно превођењеУсловно превођење

Наредба #if, #ifdef, #ifndef... • Основна наредба за почетак условног превођења :

#if uslov

• Ако услов није испуњен,

део кôда иза наредбе #if uslov неће бити преведен.

Page 104: uvod u programiranje predavanja 6 i 7

108

Условно превођењеУсловно превођење

#define VERZIJA 1.1

#define TESTIRANJE

#ifdef TESTIRANJE

#ifndef TESTIRANJE

Page 105: uvod u programiranje predavanja 6 i 7

109

Условно превођењеУсловно превођење

• Правила употребе #if, #ifdef и #ifndef• Свака од ових наредби се мора завршити

наредбом #еndif.

• Између ове две наредбе може постојати произвољан број #еlif наредби и највише једна #еlse наредба.

• Уколико постоји #еlse наредба она мора бити последња претпроцесорска наредба пре наредбе #еndif.

Page 106: uvod u programiranje predavanja 6 i 7

110

Условно превођењеУсловно превођење

#define TST #define DAN 2main(){ #ifdef TST int a=5; #endif #if (DAN==1)

printf("Ponedeljak\n"); #elif (DAN==2)

printf("Utorak\n"); #else

printf("Nije pon. ni utorak\n"); #endif

#ifdef TST

a=a+7;

printf("a= %d\n",a);

#endif

printf("DAN je %d“,DAN);

}

Utorak

a= 12

DAN je 2

Page 107: uvod u programiranje predavanja 6 i 7

111

Условно превођењеУсловно превођење#define DAN 2main(){ #ifdef TST int a=5; #endif #if(DAN = = 1) printf("Poned.\n"); #elif(DAN = = 2)

printf("Utorak\n"); #else

printf("Nije poned. ni utorak\n"); #endif

#ifdef TST

a=a+7;

printf("a= %d\n",a);

#endif

printf("DAN je %d“ ,DAN);

}

Utorak

DAN je 2

Page 108: uvod u programiranje predavanja 6 i 7

112

Хвала на пажњи

Питања?