Alamprogrammidest üldiselt

From Wikiversity

< 10. nädala teemad

Ülalt-alla projekteerimine[edit]

Divide et impera! Jaga ja valitse!

Probleemist arusaamiseks ja tema kirjapanemiseks algoritmina tuleb jagada ta osadeks. Veidi suurem programm peab tegema mitut tööd ja kõigepealt tuleb need tööd üles leida ja enda jaoks formuleerida.

Näiteks eesmärgiks on leida päevade arv, millal ühes kuus oli temperatuur selle kuu keskmisest kõrgem. Jagame tööd järgmiselt:

  1. sisesta temperatuurid
  2. leia keskmine temperatuur
    1. summeeri
    2. jaga summa päevade arvuga
  3. loenda päevad, kui temperatuur oli keskmisest kõrgem
  4. väljasta tulemus

Sõltuvalt probleemi suurusest ja keerukusest võib jagamissamme ja -sügavust palju rohkem olla. Programmi projekteerimismeetodit, kus pseudokoodi ja programmini jõutakse probleemi tükeldamise teel, kusjuures igal järgmisel sammul muutub spetsifikatsioon detailsemaks, kutsutakse ülalt-alla projekteerimiseks (top-down design) ja ta on tihedalt seotud struktuurprogrammeerimisega ja programmi moodulitesse jaotamisega.

Probleemi samm-sammuline täpsustamine:

  1. Tee probleem lihtsamaks, jagades ta loogilisetks alamprobleemideks.
  2. Kui Sul on selge, kuidas seda kodeerida, on täpsustus piisav
  3. Kui mitte, tee alamprobleem tükeldamise läbi veelgi täpsemaks, kuni teda saab esitada alamprogrammina.

Vastupidine tegevus on ülalt-alla disain (top-down design):

  1. Kirjuta valmis peaprogrammi lauseosa. See koosneb peamiselt AP-väljakutsetest. Iga AP peab lahendama osa kogu probleemist.
  2. Peaprogrammi osa peaks olema nii lihtne, et ta oleks arusaadav mitteprogrammeerijale, kuid piisavalt üksikasjalik, et programmeerija mõistaks, kuidas programm peab töötama.
  3. Kui alamprogramm on liiga keerukas, tuleks teda veel täpsustada (jagada).

Ülalt-alla projekteerimise lõpp-tulemuseks on alamprobleemide spetsifikatsioonid, mille järgi on võimalik tööd ära jaotada ja programmeerijad saavad asuda programmi osi kirjutama. Spetsifikatsioonist peab programmeerija ka teada saama, mida tema kirjutatav alamprogramm tegema peab. Peale alamprobleemide programmeerimist pannakse osad kokku ja tulemuseks on lahendatud probleem. Programmi osadeks tükeldamiseks peavad keeles kasutatavad olema vahendid, mis sellist tehnikat toetavad. Nendeks vahenditeks on alamprogrammid.

Alamprogramm[edit]

Alamprogrammide kasutamiseks on mitmeid põhjuseid. Programmi on inimesel raske jälgida ja kirjutada, kui programm on liiga pikk. Peaprogrammi saab muuta kergemini hallatavaks alamprogrammide abil. Protseduursele programmeerimiskeelele on iseloomulik võimalus kirjutada ja kasutada alamprogramme.

KLassikaliselt on jaotatud alamprogramme kahte liiki:

  • funktsioon (function) - AP, mis on mõeldud ühe väärtuse leidmiseks ja mida saab kasutada lause koostisosana.
  • protseduur (procedure) - AP, mille abil tehakse kindel tegevus ja mis kutsutakse tavaliselt välja eraldi lausega.

Mõisteid protseduur' ja alamprogramm kasutatakse ka sünonüümidena, järgnevalt on püütud neil vahet teha järgmiselt: alamprogramm on üldisem mõiste, protseduur aga teatud reeglitele vastav ja funktsioonile vastanduv alamprogramm.

Iga programmeerimiskeel ei tee otseselt vahet protseduuril ja funktsioonil, kuid võimalus sisuliselt nende kirjutamiseks on siiski olemas ja seetõttu tundub olevat otstarbekas nende erineval iseloomul siiski vahet teha.

Alamprogrammi mõiste[edit]

Alamprogramm (procedure, subprogram, subroutine) osa programmi koodist, mis teeb ära kindla töö, mis on vajalik antud programmi jaoks. Keeli, kus protseduride kasutamine on olulisel kohal, nimetatakse protseduurseteks keelteks (procedure-oriented language, procedural programming language). Alamprogrammid on kasulikud selleks, et:

  • programmi paremini hallatavaks muuta;
  • korduvaid tegevusi lühemalt kirja panna;
  • samu alamprogramme korduvalt kasutada;
  • muuta mõne olulise tegevuse algoritmi ilma kogu programmi ümberkirjutamata;
  • võimaldada meeskonnatööd.

Alamprogramme jagatakse keelesisesteks ehk sisseehitatud alamprogrammideks (buildt-in) ja programmeerija poolt kirjutatud AP-ks. Esimesi nimetatakse ka standardfunktsioonideks jms. StandardAP-d muudavad keelevahendid rikkamaks ja programmeerija elu kergemaks. Programmerijal ei ole vaja muud, kui nad kasutamiseks väljakutsuda. Tüüpiline näide - ruutjuure leidmine.

Alamprogrammi töö tundmaõppimiseks ja tema adekvaatseks kasutamiseks on vaja nii üldiselt kui ka konkreetse keele kontekstis teada:

  • Alamprogrammi kirjeldamisest: kuidas ja kuhu panna kirja see, mida alamprogramm tegema peab.
  • Alamprogrammi kasutamisest: kuidas teha teises programmis (näit peaprogrammis) olles selgeks, et nüüd tahan alamprogrammi välja kutsuda.
  • Andmevahetusest: kuidas viia alamprogrammi lähteandmeid ja kuidas sealt kätte saada vastuseid; kuidas panna alamprogrammi peaprogrammi andmeid töötlema.

Lokaalsed ja globaalsed muutujad[edit]

Muutuja kehtivuspiirkond e. skoop (scope) – see osa programmist, milles antud muutuja väärtus kättesaadav on. Muutuja skoobi määratlus erinevates keeltes on erinev, kuid mingid üldised sarnased jooned siiski on ja nende alusel räägitakse lokaalsetest muutujatest ja globaalsetest muutujatest.

Lokaalne muutuja (local variable) - muutuja, mis on deklareeritud alamprogrammi sees, on selle alamprogrammi suhtes lokaalne. Teda saab kasutada ainult see sama alamprogramm. St tema skooobiks on vastav alamprogramm. Globaalne muutuja (global variable) - tavaliselt peaprogrammis kirjeldatud muutuja, mida saab kasutada peaprogramm, kuid ka otse peaprogrammist väljakutsutavad alamprogrammid. Seda ei peeta aga heaks tooniks ja nii võivad tekkida halvasti avastatavd vead.

Argumendid ja parameetrid[edit]

Alamprogrammides on tavaliselt vaja kasutada andmeid peaprogrammist (tihti ongi AP ülesandeks PP andmetega mingi oluline töö ära teha). Võimalused on järgmised:

  • Kasutame globaalseid muutujaid. Selline taktika pole hea, sest AP on halvasti dokumenteeritav ja pole korduvkasutatav. Raske leida vigu (nn kõrvalmõju (side-effect) tekkimise oht).
  • Kasutame parameetreid. Tundub esialgu keerulisem, kuid pikemas perspektiivis on mõistlikum ja kasulikum.
Parameeter
on väärtus, mis antakse alamprogrammile ette, et ta saaks oma töö ära teha.

Eristatakse

  • formaalseid parameetreid (formal, dummy), ka argument; paikneb alamprogrammi päises alamprogrammi andmevahetuse kirjeldamiseks (alati muutuja)
  • tegelikke parameetreid (actual, calling) alamprogrammi väljakutses tegelike väärtuste

edastamiseks (muutuja, avaldis, konstant)

Parameetrite edastamine[edit]

Parameetrite edastamine on tegevus, mille tulemusena alamprogrammi väljakutsesse kirjutatud tegelikud parameetrid alamprogrammi jõuavad ja seal (enamasti) järjekorra alused formaalsetele parameetritele väärtused annavad. Erinevad keeled võivad kasutada ühte või teist edastamistaktikat, kasutusel võib neid olla ka mitu. Parameetrite edastamisel (parameter passing) on levinud kolm peamist põhimõtet

  1. Väärtuskutse (Call by value) - APle edastatakse väärtus muutuja, konstandi või avaldisena. Edastatakse väärtus ise ja tänu sellele vastava parameetri väärtuse muutmine ei muuda tema väärtust väljakutse kohas.
  2. Viitkutse (Call by reference) - APle edastatakse mälupesaaadress, kus väärtus paikneb. Selle tulemusena tekib parameeter, mille väärtuse muutmisel alamprogrammis muutub sama väärtus ka väljakutsuvas programmis.
  3. Nimikutse (Call by name) - avaldis edastatakse AP-i, mitte stringina, vaid väikese masinkoodis programmikesena, mille väärtus igakordsel kasutamisel uuesti välja arvutatakse

Python kasutab 1. meetodit.

Alamprogrammide pikkuseks pakutakse 1 kuni 2 ekraanitäit. Selline mõõde peaks aitama säilitada ülevaatlikkust. Samal ajal võib AP olla ka palju lühem, eriti siis, kui tegemist mitmes kohas kasutatava protseduuriga.

Alamprogrammide korduvkasutamise (reuse) eelduseks on kindlasti globaalsete muutujate kasutamise vältimine ja alamprogrammi korrektne dokumenteeritus. Viimase alla kuuluv info peab olema selline, et alamprogrammi oleks võimalik kasutada ilma tema koodi uurimata:

  • parameetrite täpne kirjeldus;
  • eeltingimused (preconditions): millistel tingimustel (muutujate väärtused jms) tohib seda AP-i välja kutsuda; kirjeldada tuleb igasugused piirangud, näiteks võib AP mingite parameetriväärtuste korral mitte töötada;
  • järeltingimused (postconditions): mis on juhtunud muutujatega peale AP-i töö lõppu või mida muud märgatavat on AP korda saarnud;
  • AP sisu lühike kirjeldus: mida AP teeb, millise probleemi lahendab.

Kui AP kohta on tema kasutamiseks kogu info olemas ja puudub vajadus koodi lähemalt uurima hakata ning lisaks on protseduur tõesti vormistatud nii, et teda suvalises kohas kasutada saab, kutsutakse asja protseduurseks abstraktsiooniks (procedural abstraction).

Alamprogrammi loomise reeglid[edit]

  • Üks alamprogramm peaks lahendama ühe sisuliselt piiratud ülesande.
  • Alamprogramm peab olema ülevaatlik, st. lahendatav ülesanne ei tohi olla liiga keeruline või laialivalguv.
  • Mõistlik ei ole alamprogrammide arvu liiga suureks ajada, sest see muudab programmi vähem ülevaatlikuks.
  • Andmevahetus alamprogrammiga peab toimuma ainult ühel viisil, so alamprogrammi kirjelduses esitatud parameetrite loetelu kaudu (kui mingil põhjusel tahetakse otsustada andmevahetusel globaalsete muutujate kasuks, siis ei tohiks kasutada ühtegi argumenti-parameetrit).
  • Vahetatavate parameetrite hulk olgu nii väike kui võimalik.
  • Alamprogrammis kirjeldatud identifikaatoritel (muutujatel jms) on lokaalne skoop ja neid ei saa kasutada peaprogrammis.
  • Kui samal ajal on nähtavad lokaalne (alamprogrammi) ka globaalne samanimeline muutuja, siis kasutada saab vaid lokaalset muutujat.

Moodulid[edit]

Moodul (unit, library, module) on alaprogrammide, konstantide, andmetüüpide ja muutujate kogu, mis paikneb eraldi failis ja on tavaliselt eraldi kompileeritav; ta on loogiliselt eraldatud suurema programmi üks osa. Kogu programmi võib sel juhul vaadelda kui moodulite kollektsiooni.

Moodul koosneb kahest osast - avalikust osast e. liidesest (interface) ja varjatud osast e. realisatsioonist (implementation). Kõik see, mis on kirjas liidese osas, on kättesaadav mooduli kasutajale. Realisatsiooniosa otseselt kasutada ei saa. Sõltuvalt keelest võivad mooduli liides ja realisatsioon paikneda ühes failis või eraldi

Alamprogrammidest on kättesaadavad vaid need, mille päised/kirjeldused on dubleeritud liideses. Selline mooduli jagamine kaheks toetab protseduurse abstraktsiooni ideed ja peidab ära realisatsiooni üksikasjad.

< 10. nädala teemad