7. Potprogrami Flashcards
Potprogrami
Potprograme karakterisu 4 osnovna elementa: ime potprograma, lista fiktivnih argumenata, telo potprograma i sredina u kojoj je potprogram definisan. Postoje funkcijski potprogrami (funkcije, imaju samo jednu ili ni jednu povratnu vrednost) i potprogrami opsteg tipa (mogu da imaju i vise povratnih vrednosti)
U programskim jezicima koji nasledjuju sintaksu C-a postoje samo funkcijski potprogrami Definisu se kao:
tip imeFunkcije (lista fiktivnih parametara) {//teloprogram}
tip je tip rezultata funkcije. ukoliko funkcija ne vraca nikakvu vrednost, tip je void.
Za izlazak iz programa koristi se return izraz; ili return; ako je funkcija void.
Poziv potprograma izgleda kao ime(lista stvarnih parametara). Liste stvarnih paremtara moraju da se slazu po broju i tipovima svih parametara.
Primer int a,b,m1,m2,m3; m1=manji(a,b); m2=manji(a*b,5); m3=manji(a+5,b-4);
Parametri potprograma
Semanticki gledano, prenos parametara moze da bude u jednom od tri semanticka modela.
Potprogram moze da:
• od glavnog programa primi vrednost parametar (ulazni)
• vrati vrednost glavnom programu (izlazni)
• da primi vrednost i vrati rezultat glavnom programu (ulazno-izlazni)
Prenos parametara
U teoriji programskih jezika, najcesce su koricene 2 metode za prenos parametara:
• prenos paremtara po vrednosti - u trenutku poziva rezervise se novi prostor u koji se kopiraju vrednosti stvarnih parametara
• po referenci - fiktivni parametar je drugo ime za stvarni parametar koji se navodi u pozivu.
Pored dva navedena metoda, postoji i pernos po rezultatu, prenos po vrednosti i rezultatu i prenos po imenu.
Prenos argumenata po vrednosti
Sastoji se u tome sto se pri pozivu funkcije vrednosti stvarnih argumenata kopiraju u memorijske adrese odgovarajucih fiktivnih argumenata. Sve promene argumenata se odvijaju na tim lokacijama i “nevidljive” su glavnom programu.
Zbog toga ova tehnika moze da se koristi samo za prenos ulaznih parametara, ali ne i za vracanje rezultata glavnom programu.
Prenos argumenata po referenci
Potprogramu se prenosi referenca memorijske lokacije u kojoj je vrednost stvarnog argumenta. Potprogram pristupa istim memorijskim lokacijama kojim pristupa i glavni program, pa su sve promene koje su napravljene u potprogramu vidljive i u glavnom (nema rezervisanja novih memorijskih lokacija za fiktivne). Zbog toga je ovo tehnika koja se koristi za prenos ulazno-izlaznih parametara.
Prenos argumenata po vrednosti i rezultatu
To je u sustini kombinacija prenosa po vrednosti i prenosa po rezultatu. Vrednosti stvarnih argumenata se kopiraju u memorijske lokacije fiktivnih argumenata i potprogram radi sa fiktivnih argumentima. Pre nego sto se vrati upravljanje glavnom programu, nove vrednosti na fiktivnim memorijskim adresama se upisuju u memorijske adrese stvarnih argumenata.
Ovaj nacin se takodje naziva i prenos kopiranjem, jer se vrednosti najpre kopiraju iz glavnog programa u potprogram, a onda se rezultati kopiraju iz potprograma u glavni program.
Prenos argumenata po imenu
Prenos argumenata po imenu je nacin prenosa ulazno-izlaznih argumenata potprograma koji se razlikuje od svih po tome sto nema ni prenosa reference ni kopiranja vrednosti vec se pri pozivu potprograma imena stvarnih argumenata ubacuju u tekst potprograma svuda umesto odgovarajucih fiktivnih argumenata.
Potprogram se izvrsava kao da se radi o kodu koji je napisan sa imenima stvarnih argumenata.
Prenos argumenata po rezultatu
Primenjuje se za prenos izlaznih parametara. Kada se argumenti prenose po rezultatu, njihove vrednosti se izracunavaju na lokalnim memorijskim lokacijama fiktivnih argumenata. Pre nego sto se vrati upravljanje glavnom programu, vrednosti se iz tih lokalnih mem. lokacija upisuju u memorijske lokacije stvarnih argumenata. Stvarni argumenti u ovom slucaju mora da budu promenljive. Kao i kod prenosa po vrednosti, i ovde se rezervise poseban lokalni mem. prostor za fiktivne promenljive.
Prenos parametara u C-u i C++-u
U C-u, parametri se prenose iskljucivo po vrednosti. Kada funkcija treba da menja stvarnu vrednost parametara, prenose joj se pokazivaci.
U C++-u, parametri mogu da se prenose i po vrednost i po referenci i na programeru je da izabere nacin.
void (int i, float &k){ i++; k++}
Prenos parametara u Javi
U javi, parametri se prenose iskljucivo po vrednosti. Tipovi podataka u Javi su vrednosni (svi elementarni tipovi) i referentni (klase,interfejsi,polja,enumeracije)
Kod prenosa parametara vrednosnog tipa, u lokalnoj memoriji se zauzima novi memorijski prostor i tu se upisuju vrednosti stvarnih argumenata na koje se te promene ne odrazavaju.
Kod prenosa parametara referentnog tipa, prilikom poziva se kreira nova referenca, ali ne i novi objekat. Promene koje se desavaju u metodi se odrazavaju i na originalan objekat, ali ako mu se dodeli neki novi objekat te promene nece biti vidljive.
void f(MyClass p) { p.Change() } //vidi se void f(MyClass p) {p=new MyClass(); p.Change() } //ne vidi
Prenos parametara u C#-u
Parametri u C#-u mogu biti
• ulazni(podrazumevani),
• izlazni(ispred definicije stoji kljucna rec out) i
• ulazno-izlazni(ispred definicije stoji kljucna rec ref)
Kod ulaznih parametara, argumenti se salju po vrednosti.
Kod izlaznih i ulazno-izlaznih parametara, argumenti se salju po referenci.
Ulazni parametri vrednosnog tipa se prenose po vrednosti (pravi se nova kopija podataka u memoriji, promene parametara se ne vide van metode, kao stvarni parametri mogu da se koriste promenljive, konsante ili izrazi odgovarajuceg tipa)
Izlazni i ulazno - izlazni parametri vrednosnog tipa se salju po referenci (promene unutar metode se vide i u pozivajucem metodu, stedi se prostor i stvarni parametar moze biti samo promenljiva i ne sme biti null)
Ulazni parametri referentnog tipa se prenose po vrednosti (kreira se kopija reference i metoda moze da menja objekat ali ne da mu dodeli drugi)
Izlazni i ulazno - izlazni parametri referentnog tipa se prenose po referenci (koristi se ista referenca kao i u pozivajucem modulu, moze da se dodeli sasvim drugi objekat i ukoliko je parametar out, moze da bude i null)
Podrazumevane vrednosti parametara
U nekim jezicima kao sto je C# ili C++, mogu da se navedu podrazumevane vrednosti parametara koji se koriste ukoliko pri pozivu te funkcije stvarni parametri nisu navedeni
• void f(float a=3.5f, int k=2);
Podrazumevane vrednosti mogu da imaju samo poslednja mesta u listi parametara. void f(float f, int k=2);//ispravno void f(int k=1, float f);//neispravno
Funkcije sa promenljivim brojem parametara istog tipa
Neki jezici (Java,C#…) omogucavaju da se definisu funkcije sa proizvoljnim brojem parametara koriscenjem kljucne reci params. U listi parametara, samo poslednji element moze imati ovu kljucnu rec. Funkcije takav parametar vide kao niz, a u pozivu funkcije navode se nezavisni stvarni parametri.
C# public static float prosek(params int[] niz) { float s=0; for(int i=0;i
Rekurentni potprogrami
Neki programski jezici dozvoljavaju poziv potprograma u samom svom telu. Takvi potprogrami se nazivaju rekurentni programi i oni se primenuju za resavanje problema koji su matematicki rekurzivno definisani.
Primer za fibonacijev niz i faktorijel.
Organizacija memorije i struktura aktivacionog sloga
Memorija dodeljena jednom programu moze da se podeli na sledece delove: deo sa generisanim kodom, polje podataka i deo sa aktivacionim slogovima potprograma.
Struktura aktivacionog sloga:
• Privremene promenljive - promenljive koje generise kompilator prilikom resavanja aritmetickih izraza
• Lokalni podaci potprograma
• Polje gde se pamti status procesora prilikom prenosenja upravljanja na potprogram
• Opcioni linkovi do nelokalnih podataka koji su sadrzani u drugim aktivacionim slogovima
• Opcioni linkovi do aktivacionog sloga programa iz kojeg je pozvan potprogram
• Stvarni argumenti potprograma
• Polje preko kojeg se vracaju rezultati u glavni program