Бочни ефекти функција

Често је потребно да у програму користимо посебне логичке целине – потпрограме који не дају само једну излазну вредност већ неколико вредности (резултата) или уопште не дају резултате већ обављају неки посебан задатак, попут штампе…

Видели смо да параметри функција садрже копије одговарајућих аргумената. Због тога није могуће променом вредности параметара унутар функције створити додатне резултате, односно променити вредност аргумената у главном програму, поред вредности функције. Програмски језик C дозвољава изношење резултата из функције посредством параметара, али је то могуће извести искључиво индиректним адресирањем параметара.

Да вас подсетим:

Променљиве у програмском језику су објекти који имају неку вредност, која се може мењати у току извршавања програма. Име променљиве се повезује са адресом меморијске локације у којој је уписана текућа вредност променљиве. Овакав приступ подацима, где се на адреси у меморији чува ВРЕДНОСТ податка назива се директно адресирање.

Са друге стране, постоји и индиректно адресирање, код кога се у меморији чува адреса на којој је уписана вредност траженог податка. Индиректно адресирање се у програмском језику C реализује помоћу показивача. Показивач (енгл. pointer) представља променљиву која чува адресу меморијске локације неког другог податка.

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

Применом показивачких типова мења се вредност показиваног податка, а не сам показивач који је параметар функције. С обзиром да се показивани податак налази изван функције промена вредности тог податка видеће се и изван функције. Промене вредности података настале на тај начин не сматрају се природним резултатима функције и зато се називају бочни ефекти функције. Једини природни резултат функције је вредност функције која се враћа наредбом return.

Функције у језику C могу истовремено да дају вредност функције и да стварају бочне ефекте. Могуће је чак да функције не дају вредност функције и тада се за ознаку типа вредности функције користи службена реч void. Такве функције своје резултате стварају искључиво кроз бочне ефекте. Пошто не враћају вредност функције у њима не постоји наредба return. Повратак из функције наступиће при доласку до краја тела функције. Ове функције могу се позивати искључиво засебним наредбама у програму, не могу бити део неког аритметичког израза!

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

Параметар показивачког типа може се сматрати само средством за долажење до податка који је предмет обраде. Суштински аргумент функције је тај обрађивани податак чија се адреса доставља преко показивача. Због тога се каже да се показивачким параметрима аргументи преносе у функције помоћу адресе.

Ако је параметар показивач на податке неког типа, аргумент може да буде само показивач на податке истог типа. Показивачки аргумент је најчешће адресни израз којим се формира адреса неке променљиве (&prom). Другим речима – у дефиницији функције која враћа бочне ефекте за показивачке параметре користе се показивачи (*p), а при позиву те функције за показивачке параметре користе се адресни изрази (&prom).

Пример:

Нека су улазне вредности два цела броја m и n, а резултат цели бројеви p и q. Резултат p треба да буде збир квадрата бројева од m до n, а резултат q збир кубова од m до n. Уместо увођења две функције kv (за израчунавање збира квадрата) и kub (за израчунавање збира кубова) написаћемо један потпрограм који ћемо назвати KvKub у којој се израчунавају вредности резултата p и q. Тај програм је функција која враћа бочне ефекте. Њен тип је void, а параметри p и q треба да буду дефинисани као показивачки параметри (*pKv, *pKub).

#include<stdio.h>
void KvKub(int m, int n, int *pKv, int *pKub)
{
int i;
*pKv=0;*pKub=0;
for (i=m;i<=n;i++)
{
*pKv=*pKv+i*i;
*pKub=*pKub+i*i*i;
}
}
main()
{
int m,n,k,l,p,q,r;
KvKub(2,4,&p,&q);
printf("zbir kvadrata od 2 do 4 iznosi:%d, a zbir kubova: %d\n",p,q);
printf("unesi 4 cela broja");
scanf("%d%d%d%d",&m,&n,&k,&l);
KvKub(m,n,&p,&q);
printf("zbir kvadrata od %d do %d iznosi:%d, a zbir kubova: %d\n",m,n,p,q);
KvKub(m-k,n+l,&p,&r);
printf("zbir kvadrata od %d-%d do %d+%d iznosi:%d, a zbir kubova: %d\n",m,k,n,l,p,r);
}

Прва два параметра су „улазни подаци”: Они се у функцију преносе помоћу вредности. На месту позива функције у променљиве m и n уписују се копије вредности аргумената. Наш потпрограм израчунава вредности збира квадрата и збира кубова. Ови параметри су дефинисани као показивачки параметри (*pKv, *pKub), да би се омогућило да се помоћу њих резултати врате у главни програм. Показивачки параметри се у функцију преносе помоћу адресе. На месту позива функције у променљиве *pKv и *pKub (а то су показивачи, чија вредност је адреса!) уписују се адресе променљивих у које желимо да упишемо израчунате вредности!

Први позив ове функције је наредба:

KvKub(2,4,&p,&q);

На том месту процедура се извршава са улазним подацима 2 и 4. Резултати ће бити уписани на адресе променљивих p и q. Због тога потпрограм, односно функција која враћа бочне ефекте има директан приступ овим локацијама (иако оне физички припадају меморијском простору намењеном за променљиве које припадају главном програму), тако да у њих може уписати резултате кад их израчуна.

Advertisements

4 thoughts on “Бочни ефекти функција

  1. pohvala za veoma ozbiljan pristup i trud.
    veoma ozbiljan clanak, i tema , iz programiranja opste, pogotovo C.
    hteo bih da pomognem dobronamerno, pa bih skrenuo paznju za pocetak na neke lakse stvari, pa mozda i da analiziramo post.
    prva stvar je ,dobronamerno, a bolje cu upoznati vas blog jer je interesantan,da vam code kako demonstracioni tako i resenja zadataka nije dovoljno komentarisan.desice se da klinci izvuku code ,testiraju i analiziraju medjusobno.
    mislim da klincima treba dati primer na taj nacin,da u startu nauce da je komentar code-a veoma vazan i da se toga pridrzavaju.
    ostale,nadam se konstruktivne diskusije,drugi put ,ako ste za.
    pozdrav Aleksa

    • Најпре – хвала на читању и коментару. Радујем се конструктивним критикама 🙂
      Ово је „наменски текст“ – објављен после часа, да им допуним оно речено на часу. Што се коментара у самом коду тиче – трудим се да не претерујем, мада би можда ипак било боље да кроз коментаре дам додатна објашњења

      • molim,:)
        ja mislim, i drzim se toga da je komentar veoma vazan.sto vise vremena prodje,sto vise ljudi/klinaca pogleda taj code i podeli ,komentari ce biti sve vazniji.a naravno, i vama ce kasnije pomoci da „rekonstruisete nacin razmisljanja“ koji se vremenom menja.za kasnije je dobra ideja da sve vase priloge, code, podelite na nekoj lokaciji, i onda ce komentar u code-u biti od najvece pomoci.
        Iako je tekst namenski,stivo za ucenje ,pogotovu,C jezika je jako dragoceno.ne bih da uticem na vas nacin rada, ali je cinjenica da ce dosta klinaca pretrazivati ovaj tekst.moyda ne bi bilo lose da tekst bude samostalniji.mislim da jeste.i msilim da je bas ovaj post jako dobar primer za to kako treba da neka tema iz C bude objasnjena.
        toliko za sada , voleo bih da post pretresemo i eventualno unapredimo.bilo bi super da klincima poklonimo jednu dobru skolu C-a.naravno , vasu . 🙂

      • Моја првобитна идеја је била да направим „збирку задатака“, јер је за средњошколски узраст врло оскудна литература. Онда сам схватила да збирка без „теорије“ не би била комплетна. И тако већ годинама покушавам да комплетирам ову причу, и надам се да ћу ове године успети.м
        Што се Ваших предлога о „анализи“ текстова на блогу тиче – можемо наставити у личној преписци :);

Оставите одговор

Попуните детаље испод или притисните на иконицу да бисте се пријавили:

WordPress.com лого

Коментаришет користећи свој WordPress.com налог. Одјавите се / Промени )

Слика на Твитеру

Коментаришет користећи свој Twitter налог. Одјавите се / Промени )

Фејсбукова фотографија

Коментаришет користећи свој Facebook налог. Одјавите се / Промени )

Google+ photo

Коментаришет користећи свој Google+ налог. Одјавите се / Промени )

Повезивање са %s