Selle ülesande raames simuleerime läbi lihtsa kassasüsteemi rakenduse, eesmärgiga harjutada tingimuslausete koostamist. Juhindu etteantud aluskoodis olevatest kommentaaridest ning kirjuta vajalikud koodiread pärast kommentaari!
Nõuded
Programm peab loogiliselt olema üks-ühene etteantud algoritmiga
Programm peab olema ehitatud etteantud aluskoodi põhjale. Sinu ülesanne on lisada vajalikud
printf ,
scanf laused, arvutustehted ja tingimuslaused sinna kuhu vaja. Juhindu kommentaaridest ja etteantud UMList.
Ära muuda muutujate nimetusi ega programmi struktuuri.
Soovitus: Kontrollimaks, et programm käitub korrektselt ja muutujad omavad neid väärtusi, mida ootad, tasub lisada vahele mõni täiendav
printf lause.
Kui soovid abi mõne käsu kohta, siis selleks on sul 3 peamist meetodit. Kolmas ja mõneti kõige aeglasem on internetist otsimine, seega seda me siin ei kajasta. Ülejäänud 2 infoallikat on aga kättesaadavad otse käsurealt.
tldr (simplified community-driven man pages)
See on Linuxi kasutajate poolt kokku pandud “käsiraamat”, mille eesmärk on kiiresti ja lihtsalt kirjeldada iga programmi kõige levinumad ja olulisemad kasutusviisid. Seetõttu on aga puudujäägiks sageli vajaliku detailsuse või selgituste puudumine.
Vaikimisi seda Linuxitega kaasa ei tule aga oleme selle tööriista laboriarvutitesse paigaldanud.
Näiteks lugemaks kuidas faile kopeerida kirjuta
tldr cp
man pages
man ehk manual pages on Linuxiga kaasa tulev manuaal. Siin on olemas manuaalid käskudele, teekidele, süsteemi käskudele jne. Enamasti on iga programmi manuaalis kirjeldatud kogu tema funktsionaalsus. Kasutamiseks kirjuta
man käsu_nimi
Näiteks lugemaks kuidas faile kopeerida kirjuta
man cp
Manuaali sulgemiseks kasuta klahvi
q . Manuaalist otsimiseks sisesta
/ ning seejärel mida otsida soovid. Abi teiste käskude näed kui vajutad
h klahvi.
man eelis
tldr ees on põhjalikkus – üldiselt on selgitused väga detailsed ning mõeldud kogenud kasutajale (professionaalile). Sageli on need algajale liialt mahukad.
Esitamisele kuuluvad ülesanded
Selles laboris on kaks ülesannet, millest mõlemat lõppevad lõppevad veebivormiga, mis tuleb täita ja esitada! Eraldi ülesande lahendusi ette näitama ei pea.
Ülesanne 1: käsurea kasutamine
Selle ülesande raames tutvume väga põgusalt käsurea kasutamisega. Ülesanne lõppeb veebivormiga, mis tuleb täita. Veebivormi esitamine kinnitab ülesande lahendamist.
Kasutatavad terminid:
Käsuviip – Käsurea alguses olev informatsioon näitamaks ära kasutajanime ja asukohta failisüsteemis.
Käsurida / käsuaken / terminal – Programm, kus me oma käske jooksutame, nn terminal. Sisaldab käskude ajalugu, käsuviipa, võimalust käsku sisestada jms.
Vali viis ülesande lahendamiseks
Enne kui ülesande juurde saad minna oleks vaja meil Linux keskkonda ja käsuakent. Valikud pakun välja neli.
Lahenda ülesanne luues SSH tunnel kooliarvutisse ning tehes kõik üle tunneli Juhend: SSH ühenduse loomine
Ülesande lahendamine
Ülesanne on kirjeldatud samm-sammulise töövoona. Kõik tegevused tuleb lahendada kasutades käsurida. Ülesande lõpus tuleb sul esitada oma käskude ajalugu!
Samm 1: Vali kaust kus labori faile hoiad
Esmalt peaksid otsustama kuhu paned selle labori jaoks vajalikud failid. Tõenäoliselt võiks see olla midagi sarnast nagu
~/P/iax0583/labor11 .
Järgnevad käsud aitavad sind nagiveerimisel ja kausta loomisel:
Käsk
pwd näitab kus kaustas hetkel asud
Käsk
cd võimaldab kaustade vahel liikuda
Käsk
mkdir abil saad luua uue kausta
Käsk
ls näitab mis praeguse kausta sees asub. kasuta täiendavaid argumente detailide nägemiseks.
Käsk
mv lubab kaustasid ja faile ümber nimetada ja liigutada.
Kasuta
tldr käsk või
man käsk , et näha abi käsu kasutamise kohta.
Liigu käsureaga kausta, kus ülejäänud labori teha kavatsed!
Samm 2: Lae alla testprogramm
Labori kulgemist jälgib testprogramm. Programm on kokku pakitud kujul.
Failide allalaadimiseks kasutatakse tööriista nimega
wget . lae seda kasutades testprogramm alla. Selleks käivita järgnev käsk:
1
wget blue.pri.ee/lt.zip
Samm 3: Paki testprogramm lahti ja käivita see
Tegu kokku pakitud zip arhiiviga. Kasuta programmi
unzip selle lahti pakkimiseks. Jälgi hoolikalt arhiivi lahti pakkimise käigus tekkivat väljundit. See on oluline, et teaksid mis lahti pakiti ja kuhu! Soovitavalt tee topeltkontroll kasutades
ls -i, et veenduda selles.
Võimalik, et pead ka programmi käivitatavaks muutma
Mõnel juhul võib osutuda, et programmi ei pakitud lahti käivitusõigustega. Kui see nii juhtus (kontrolli esmalt), tuleb käivitusõigus lisada. Selleks saad kasutada käsku
chmod .
Käivita testprogramm
Nüüdsest on sul võimalik testprogrammi käivitada. Tee seda kohe – pane käima alla laetud programm!
Programm kontrollib labori kulgemist ja jääb seisma kohe kui märkab täitmata nõuet. Edaspidi jooksuta testprogrammi iga kord kui oled järgneva sammu ära teinud.
Praegu peaksid nägema järgmist väljundit:
1
2
3
4
5
6
7
8
Hello user risto.heinsar
You seem to be from: risto-wk-tux
Starting testing procedure!
Attempting to check for VIM configuration!
Error! VIM configuration not found!
Exiting!
Samm 4: Lae alla Vimi seadefaili
NB! Kui oled juba Vim-i kasutaja ning omad kodukataloogis seadefaili, jäta see samm vahele!
Vim on üks klassikalistest käsureal töötavatest tekstiredaktoritest. Sel on suur kogus erinevaid laiendusi ja seadistusvõimalusi võrreldes primitiivsete tekstiredaktoritega nagu nt nano.
Laeme alla seadefaili, mis teeb selles koodi redigeerimist veidi mugavamaks – nt lisab koodi värvimise, automaatse tabuleerimise jne. Vim’i seadefail tuleb laadida enda kasutaja kodukataloogi – sealt otsib vim seda automaatselt.
1. Mine käsuaknas oma kodukataloogi. Selleks kasuta käsku
cd . Kodukataloogi sümboliks on
~ .
2. Kasuta programmi
wget seadefaili allalaadimiseks. Seadefail asub aadressil
blue.pri.ee/.vimrc
Kasuta testprogrammi kontrollimaks, et seadefaili allalaadimine õnnestus!
Samm 5: Kopeeri üle andmefail, mis sisaldab saladust
Mine M kettale (~/M/). Leia sealt üles oma praktikumi juhendaja kaust ja mine sinna sisse. Selle kausta sees on üks peidetud alamkaust – otsi see üles ja mine sinna sisse. Peidetud alamkausta nimi algab punktiga. Peidetud kausta seest leiadki puuduoleva faili.
Nüüd tuleb sul see fail endale kopeerida. Kopeeri see samasse kausta kus asub su testprogramm! Kopeerimiseks pead kasutama käsku
cp . Määra ära mida soovid kopeerida ja kuhu!
Nüüd on aeg jälle testprogramm käivitada ja vaadata kas saladus leiti.
Samm 6: Järgmiseks pead looma tekstifaili oma matriklinumbriga
Loodava faili nimeks on
matricula . See loo samasse kausta kus on ülejäänud failid. Selleks pakun välja 2 võimalust.
1. võimalus: Ava endale meelepärane tekstiredaktor, loo seda kasutades antud fail ning kirjuta sisse oma matriklinumber.
Vim-i juhis:
Käivita programm kirjutades
vim matricula . See käivitab Vim-i ja avab (vajadusel loob) sealjuures faili nimega matricula.
Vajuta klahvi ’i’, et minna sisestamise režiimi (insert mode).
Nüüd kirjuta sisse oma matriklinumber.
Seejärel vajuta klahvi ‘esc’, et tühistada kirjutamisrežiim.
Nüüd kirjuta seal aknas
:wq . w ütleb Vim’ile, et muudatused tuleb faili kirjutada ja q ütleb, et seejärel tuleb programm sulgeda. Neid saab ka eraldi kasutada.
2. võimalus: See on see, mida enamik ninapidi asjas olevad inimesed tegelikult teeksid sellise lühikese faili kirjutamiseks. Kasutusele võetaks käsk echo, mis kuvab sellele antud teksti terminaliekraanile tagasi. Echo väljundvoog (stdout) aga suunataks ümber faili, mille tulemusena vajaminev fail valmis kirjutatakse – nt
echo "tekst" > fail
Samm 7: Kirjuta programm, mis väljastab “Hello world!”
NB! Enne selle sammu teostamist meenuta mis asi on faili laiend (file extension) ning mis laiendeid kasutatakse C-programmeerimiskeele lähtekoodi failidel ning millist programmidel Linuxi keskkonnas.
Taaskord, kasuta koodi loomiseks käsurea tekstiredaktorit. Meie soovitame
Vim i kuna see toetab C koodi aga sa võid kasutada ka mõnda teist tekstiredaktorit.
Kui sul on programmi kood kirjutatud, tuleb see kompileerida (meenuta, mis meie kompilaatori programmi nimi oli!). Kasuta kompilaatorile lipuna
-o hello , et määrata väljundprogrammi nimeks “hello”.
Hoiatus: Ära mingil juhul kirjuta -o järele oma lähtekoodi (.c) faili nime. Sedasi kirjutad sa oma lähtekoodi üle.
Nüüd on aeg taas jooksutada meie antud testprogrammi! Kui kõik on edukalt sooritatud, loob see sulle uue faili mille sisse on kirjutatud juhised. Jälgides neid juhiseid saad ülesande esitada.
Ülesanne 2: Andmete otsimine ja veebikodu
Selle ülesande raames tutvume tööriistaga, mida kasutatakse laialdaselt oluliste andmete otsimiseks suurematest andmekogudest ning tutvustame sulle kus asub sinu veebikodu. Lisaks vaatleme ka kuidas töötab toru ehk ühe programmi standardse väljundvoo (stdout) suunamist teise programmi standardsesse sisendvoogu (stdin).
Lähteandmed
Olen genereerinud täiesti juhuslike andmetega tekstifaili, mis võiks matkida roboti poolt tekitatud logisid. Sellised failid on loomult pikad (tavaliselt olulisemalt pikemad kui minu poolt antav) ning enamasti vajame neid vaid siis, kui midagi läheb valesti. Sellisel juhul on aga vaja paljude andmete hulgast just meile vajalik info kätte saada.
Pikkade tekstifailide filtreerimiseks on väga hõlbus abiline programm nimega
grep . Sellele programmile on võimalik anda parameetrina otsitav muster ning programm kuvab ekraanile ainult need read, mis sisaldavad otsitud mustrit. Ülejäänud ridu ei näidata.
Mustrid võivad olla lihtsad – näiteks ühesõnalised nagu
SENSOR ,
ERROR ,
firefox jne. Sellisel juhul käivitamegi programmi kirjutades
grep muster .
Mustrid võivad olla aga ka keerulisemad – need saavad koosneda regulaaravaldistest (regular expression). Regulaaravaldiste kasutamiseks lisame käivitamisel argumendi
-E . Näiteks kirjutades
grep -E sensor[1-3]: leitakse meile kõik read, mis on vastavalt kas
sensor1: ,
sensor2: või
sensor3: . Märka, et ka koolon on otsitav.
NB! Kui sa oma veebikodu aadressi tuvastada ei suuda või tekivad tehnilised probleemid, anna meile pärast vormi täitmist märku ja näita oma faili asukohta ning aadresse mis proovisid.
Baasülesande nõuded
Sinu ülesandeks on leida üles minu antud failist kõik read, mille teabetase on viga ehk ERROR ja sensoriks on sinu
matriklinumber % 10 .
Näide:
Üliõpilaskood 123456IACB, matrikkel seega 123456.
123456 % 10 on 6
Järelikult tuleb otsida kõik veaolukorrad SENSOR6 kohta. Mõned näited oodatavatest ridadest:
C
1
2
Mar 14 03:53:34 ERROR: SENSOR6: No response within hard limit!
Mar 14 03:54:19 ERROR: SENSOR6: No response within hard limit!
Ülesannet võid lahendada kirjutades kõik käsud ühele reale või tehes seda mitmes osas.
Kirjuta väljund faili, kasutades selleks väljundvoo ümbersuunamist. Loodava faili nimeks peab olema sinu üliõpilaskood.txt – näiteks kui su üliõpilaskood on 123456IACB, siis sa kirjutad tekstifaili 123456iacb.txt
Lisaülesande nõuded
Sinu ülesandeks on leida üles minu antud failist kõik read, mille teabetase on viga ehk ERROR. Ositavad read sisaldavad veateadet kas sensorilt sinu
matriklinumber % 10 või mootorilt sinu
matriklinumber % 4 .
Leitud read peavad jääma samasse ajalisse järjestusse nagu nad on antud sisendfailis.
Näide:
Üliõpilaskood 123456IACB, matrikkel seega 123456.
123456 % 10 on 6
123456 % 4 on 0
Järelikult tuleb otsida kõik veaolukorrad SENSOR6 või MOTOR0 kohta. Mõned näited oodatavatest ridadest:
C
1
2
3
4
Mar 14 03:51:46 ERROR: MOTOR0: Temperature critical! (104 C, LIMIT: 90 C)
Mar 14 03:53:34 ERROR: SENSOR6: No response within hard limit!
Mar 14 03:54:19 ERROR: SENSOR6: No response within hard limit!
Mar 14 04:04:09 ERROR: MOTOR0: No response within hard limit!
Ülesannet võid lahendada kirjutades kõik käsud ühele reale või tehes seda mitmes osas.
Kirjuta väljund faili, kasutades selleks väljundvoo ümbersuunamist. Loodava faili nimeks peab olema sinu üliõpilaskood.txt – näiteks kui su üliõpilaskood on 123456IACB, siis sa kirjutad tekstifaili 123456iacb.txt
Veebiketta kasutamine
NB!
NB! Osadel tudengitel on veebiketas miskil põhjusel katki! Kui tundub, et teed kõik õigesti aga brauser viskab 404, siis anna meile märku ja me vaatame üle, et kõik paistab õige – kui tegid kõik õigesti, siis paneme eraldi kirja, et labori mõttes midagi katki ei jääks. Vorm ülesande täitmise kohta tuleb ikkagi täita, sisestades oletatava aadressi kus fail peaks olema.
Selles laboris on kaks ülesannet. Teisele üelsandele on pakutud kaks lisaülesannet.
Ülesanne 1: Maatriksist tulemuste leidmine
Selle ülesande raames harjutame maatriksis nagiveerimist ja sealt tulemuste leidmist.
Ülesannet hinnatakse kolmes eraldi osas! Loe lähemalt peatükist “Hinnatavad osad” . Ülesanne tuleb ette näidata kasutades voo suunamist etteantud sisendandmete failiga.
Ülesandega alustamiseks lae alla järgnevad lähtefailid
Ülesande jaoks on sulle antud aluskood ja tekstifail sisendiga
Programmi jooksuta kasutades voo suunamist.
Lisa programmi algse maatriksi väljatrükk. Väljatrükk peab olema joondatud samamoodi nagu näidisel.
Leia järgnevad tulemused
Peadiagonaalil olevate negatiivsete arvude summa
Kõrvaldiagonaali kohal (kõrvaldiagonaalist kõrgemal) olevate positiivsete arvude korrutis
Iga rea suurim arv
Kõik väärtused tuleb salvestada täisarvulistesse andmetüüpidesse. Andmetüübid nagu float, double jne ei ole lubatud.
Kui soovid kasutada väiksemaid või suuremaid andmetüüpe kui 32-bitised, peavad need olema määratud täpselt (nt
inttypes.h teegi abil). Tüübid nagu
long ja
long longei ole lubatud
Lahendus peab olema ühilduv erinevatel platvormidel. Formaadid nagu
%ld ja
%lldei ole lubatud
Ülesande raames tuleb sul luua nõutud funktsioonid. Loetelu nendest on kirjeldatud järgnevas punktis.
Nõutud funktsioonid
Programmi tuleb lisada kokku 5 funktsiooni. Vajadusel võid neid lisada täiendavalt juurde.
Maatriksi lugemine. Funktsiooni töö käigus loetakse maatriks mällu. Tagastust ei ole. Funktsioon on lahendatud sinu eest aluskoodis.
Maatriksi väljatrükk. Funktsiooni käigus trükitakse maatriks ekraanile samamoodi nagu näidisel. Tagastust ei ole. Funktsiooni prototüüp antud aluskoodis.
Peadiagonaalil olevate negatiivsete arvude summa. Funktsioon tagastab summa
main() funktsiooni, kus see välja trükitakse. Kõrvalmõjud on keelatud! Funktsiooni prototüüp antud aluskoodis. NB! Ettevaatust liiasusega! Vaata millistel indeksitel arvud asuvad ning sea tsükliloendurid täpselt nendele positsioonidele. Käia läbi 49-kohaline maatriks ainult 7 arvu leidmiseks ei ole okei. Kujuta ette kui nt tegu oleks 1000 x 1000 maatriksiga – sellisel juhul käiksid läbi miljon arvu selleks, et leida vaid nendest tuhat. Kogu tööst oleks kasulik sellisel juhul vaid 0.1% (väheneb eksponentsiaalselt)
Kõrvaldiagonaali kohal (kõrvaldiagonaalist kõrgemal) paiknevate positiivsete arvude korrutis. Funktsioon tagastab korrutise main() funktsiooni, kus see välja trükitakse. Kõrvalmõju ei ole.
Rea-kaupa suurimate arvude leidmine. Disain on sinu enda otsustada. Kõrvalmõjud on lubatud, tulemused võib printida soovi korral funktsiooni sees. Võid lisada ka mõne täiendava abifunktsiooni.
Hinnatavad osad
Sellel ülesandel on 3 hindamiskohta, vastavalt pärast iga tulemuse edukat leidmist.
Kohustuslik, olenemata millist alamosa näitad:
Programmi tuleb jooksutada kasutades voo suunamist
Sisestatud maatriksi väljatrükk
Eraldi hinnatavad alamosad:
Osa 1: Peadiagonaalil olevate negatiivsete arvude summa.
Osa 2: Kõrvaldiagonaali kohal (kõrvaldiagonaalist kõrgemal) olevate positiivsete arvude korrutis.
Osa 3: Iga rea suurim arv.
Vihjeid
Vaata kuidas
ReadMatrix() funktsioon on kirjutatud. Sedasi saad ka oma ülejäänud funktsioonide parameetrid kujundada.
Väljatrükk: Jällegi, vaata funktsiooni ReadMatrix(). Tsüklite struktuur on juba tehtud selliselt, et see käib läbi kõik maatriksi positsioonis. Peaksid lugemise asendama väljastusega. Reavahetuseks mõtle mis eesmärki omab sisemine tsükkel ja mis eesmärki välimine (ning kus paikned maatriksi suhtes enne ja pärast välimist tsükli töötamist ning kus asud enne ja pärast sisemise tsükli töötamist).
Osa 1: Kirjuta endale välja maatriksi liikmete indeksid, mida sul on vaja summeerida. Vaadates nende indeksite väärtusi mõtle mitut erinevat muutujat nende jaoks on vaja (ning samaaegselt ka tsüklit).
Osa 2: Meenuta mis juhtus täisarvu ületäitumisel.
Osa 3: Maatriksi ühte rida on võimalik edastada funktsiooni. Selleks määrame ära soovitud reaindeksi ning anname kaasa ka rea pikkuse. Nii saad korduvkasutada juba varasemas laboris valmis tehtud funktsiooni. Nt
FindMaxValue(matrix[rowIndex],rowLength)
Testimine
Võrdle oma tulemust allolevaga nende õigsuses veendumiseks!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Sisestatud maatriks:
10 9 8 0 -10 8 5
7 6 9 1 -7 -9 4
-5 5 -5 5 -5 5 -5
8 7 6 5 4 3 2
1 2 3 4 5 6 7
-1 -2 -3 -4 -3 -2 -1
0 0 0 0 0 0 0
Peadiagonaali negatiivsete elementide summa on -7
Korvaldiagonaali kohal olevate positiivsete arvude korrutis on 36578304000
1 rea suurim oli 10
2 rea suurim oli 9
3 rea suurim oli 5
4 rea suurim oli 8
5 rea suurim oli 7
6 rea suurim oli -1
7 rea suurim oli 0
Ülesanne 2: Kinosaal
Meile on antud kinosaali plaan, mis on kujutatud 2-dimensioonilise maatriksina. Sinu peamiseks ülesandeks on väärtuste tõlgendamine antud maatriksist.
Kõik istekohad on kodeeritud järgnevate täisarvuliste numbritega:
0 – istekoht puudub
1 – istekoht on vaba
2 – istekoht on hõivatud
Maatriksis positsioonil (0, 0) asub saali ülemine vasak istekoht.
Kuva saali plaan. Programmi väljund peab olema samasugune nagu etteantud näidistel, sh
Vasakul ääres on rea numbrid.
Kõik read algavad esimesest istekohast, kuid arvestada tuleb, et saal on eest kitsenev (vt näide)
Ekraani asukoht on näidatud
Vabad istekohad kuvatakse numbritena
Hõivatud istekohad kuvatakse suure X tähena
Puuduvaid istekohti ei kuvata
Küsi kasutajalt soovitud istekoht ning väljasta kas koht eksisteerib, on vaba või mitte.
Minimaalselt loo 2 funktsiooni peale main funktsiooni. Üks saaliplaani kuvamiseks, teine istekoha saadavuse kontrolliks. Võid julgelt ka rohkem funktsioone luua.
Töövoo soovitus
Prindi saaliplaan tavalise maatriksina. Ära veel väljundit kohandama hakka. Veendu, et saad numbrid kätte ja vormindatud.
Nüüd hakka väljundit kohandama (tõlgendama maatriksis olevaid väärtusi korrektselt). Loo tingimuslause, mille abiga tuvastada kui koht maatriksis puudub ja väljasta “tühjus” seal oleva numbri asemel.
Seejärel jätka teiste kodeeritud väärtuste tõlgendamist ja visuaali loomist.
Kui saaliplaan on valmis, prindi saaliplaani kõrvale rea numbrid.
Küsi kasutajalt tema soovitud istekoha asukoht. Kontrolli, et väärtused oleksid “mõistusepärased” (nn sanity check).
Rea numbri maatriksis saad välja arvutada koheselt. Tulba numbri leidmiseks pead arvestama ka puuduvate istekohtadega.
Väljasta maatriksis leitud indeksid veendumaks, et leidsid õige asukoha!
Nüüd lõpeta ülejäänud programm.
Vihjeid
Saali plaan on peegeldatud kujul võrreldes massiivi tegelike indeksitega. Abiks võib olla kui joonistad endale välja ja märgid ära esimese ja viimase rea asukohad.
Rida 14 asub massiivis indeksiga 0
Rida 1 asub massiivis indeksiga 13
Istekoha kontrollis trüki välja massiivi indeksite väärtused (pildil rida algusega DEBUG)
Kasuta istekohtade loendamiseks eraldi loendurit.
Sellist kodeeritud täisarvu on hea lahendada kasutades
switch() lauset.
Programmi testimine ja näide
NB! Näidistel on kasutatud ka värve, seda sinu lahenduses olema ei pea (kuid võib 🙂 )
Näidises on samuti lisatud silumiseks DEBUG rida, kus kuvatakse massiivi asukoht kust istekohta otsiti. Sedasi on lihtsam oma programmi õigsust kontrollida.
Ava mind pildi nägemiseks
Lisaülesanne 1: mitu piletit
Lisame võimaluse kasutajal osta mitu piletit korraga.
Kasutaja saab sisestada soovitud piletite arvu
Kõik istekohad peavad paiknema kõrvuti, samas reas
Lähtepunktiks on kasutaja sisestatud istekoht. Täiendavad kohad võivad paikneda sellest nii vasakul kui paremal pool (sh mõlemal pool korraga).
Kuva kasutajale pakutavad istekohad.
Lisaülesanne 2: ostukinnitus
Lisame kasutajale võimaluse ümber mõelda oma piletiostu soovi.
Selle ülesande eelduseks on esimese lisaülesande lahendus.
Pärast istekohtade pakkumist tuleb kasutajalt küsida kinnitust kas ta soovib pakutavaid istekohti.
Kui kasutaja keeldub pakutavatest kohtadest või ei olnud võimalik soovitud asukohas istekohti pakkuda kuvatakse kasutajale uuesti saali plaan ning pakutakse talle võimalust uuesti istekohti valida
Vihje: Algses maatriksis on pakutud välja 3 kodeeritud väärtust. Võid neid soovi korral lisada. Alternatiivina saad teha algsest maatriksist koopia.
Programmi näide
Näide on koostatud pärast mõlema lisaülesande lahendamist.
Ava mind pildi nägemiseks
Pärast tundi peaksid oskama järgmist
Peaksid oskama erineva pikkusega arve kasutama koodis, sh 64-bitist täisarvu.
Mõistma mis hetkel täisarvu ületäitumised juhtuvad koodis
Olema suuteline visualiseerima kahedimensioonilist massiivi (maatriksit)
Suutma deklareerida ja indekseerida kahedimensioonilist massiivi
Suutma indekseerida kindlaid osi kahedimensioonilisest massiivist (nt esimene või viimane rida, kolm esimest rida, teine element kolmandast reast jne)
Mõistma ja olema suuteline kasutama maatriksi diagonaalide omadusi
Suutma käia maatriksit läbi nii rida-rea haaval kui ka veerg-veeru haaval.
Selles tunnis on üks tunnitöö millele on välja pakutud kaks lisaülesannet.
Tunnitöö: Mullsorteerimine
Tunnitöö raames sorteerid kasutaja poolt sisestatud arvujada kasutades mullsorteerimise algoritmi.
Nõuded
Kasutajalt küsitakse 5 täisarvu, mis salvestatakse massiivi.
Sorteeri massiiv kasutades mullsorteerimise algoritmi.
Optimeeri tsüklite kestvust sedasi, et asjatult võrdlusi ei sooritataks – just nii nagu oli slaidil näidatud. Veendu, et kirjutad optimeeringu nii sisemisse kui välimisse tsüklisse!
Loenda ja kuva mitu korda arve võrreldi omavahel. Kui tegid optimeerimise korrektselt, peaksid saama täpselt 10 võrdlust.
Kuva massiiv kasvavas järjekorras.
Kuva massiiv kahanevas järjekorras.
Sorteerida tohid kogu programmi vältel massiivi vaid ühel korral! Teises suunas massiivi kuvamiseks uuesti seda sorteerida ei tohi!
Luua tuleb neli funktsiooni. Loetelu nõutud funktsioonidest on loetletud allpool.
Meeldetuletuseks!
Muutujad
lowerCamelCase
Funktsioonid
UpperCamelCase
Makrod
SCREAMING_SNAKE_CASE
Maagilised numbrid koodist asendatud makrotega
Massiivi pikkus antakse funktsiooni alati kaasa
Vasta küsimusele: jälgida saab nii võrdluste kui vahetuste arvu. Kumb neist meie optimeeringu tulemusel väheneb, kumb jääb samaks?
Lahenduses nõutavad funktsioonid
Selles programmis tuleb sul kokku luua 4 funktsiooni
Numbrite lugemiseks massiivi
Massiivi sorteerimiseks
Kaks funktsiooni massiivi kuvamiseks
Vihjed
Sa saad juba alustada eelmisel nädalal kirjutatud funktsioo! Eelmise nädala tunnitöödest on sul mõned funktsioonid juba olemas. Kopeeri sisse ja vajadusel modifitseeri neid, lisa juurde mis puudu.
Mullsorteerimise funktsioon on järjekordne funktsioon mille peaksid oma varasalve panema. Kui funktsiooni endale talletad, võta sealt vahetuste loendamine ära – mida vähem kõrvalmõjusid funktsioonidel on seda parem.
Test 1: Tagurpidine järjestus
Tegu on kõige keerulisema juhuga mullsorteerimiseks. Suurim on esimene, vähim viimane.
Sample: sort
1
2
3
4
5
6
7
8
9
10
11
12
This program takes 5 numbers from the user and sorts them. Output is given in both ascending and descending order.
Enter number 1 / 5: 5
Enter number 2 / 5: 4
Enter number 3 / 5: 3
Enter number 4 / 5: 2
Enter number 5 / 5: 1
Comparisons made during sorting: 10
Numbers in ascending order: 1 2 3 4 5
Numbers in descending order: 5 4 3 2 1
Test 2: Juhuslik massiiv
Juhuslik järjekord. Võrdluste arv jääb samaks. Testib ka kitsaid piirjuhte osadel arvutisüsteemidel kui massiivi piirest üle minnakse. Tegu ei ole põhjaliku ja tõendusliku testiga (selleks on spetsiaalsed tööriistad) aga võib mõnel juhul vea nähtavaks tuua.
Sample: sort
1
2
3
4
5
6
7
8
9
10
11
12
This program takes 5 numbers from the user and sorts them. Output is given in both ascending and descending order.
Enter number 1 / 5: -5
Enter number 2 / 5: 3
Enter number 3 / 5: 9
Enter number 4 / 5: 2
Enter number 5 / 5: -5
Comparisons made during sorting: 10
Numbers in ascending order: -5 -5 2 3 9
Numbers in descending order: 9 3 2 -5 -5
Lisaülesanne 1: tsüklite täiendav optimeerimine
Algselt kirjeldatud algoritmi üks puudustest on olukord kui massiiv saab oluliselt varem sorteeritud kui algoritmi täielik tööaeg ette näeb. Sellist olukorda on võimalik tuvastada ning ära kasutada.
Kui massiiv saab sorteerituks enne viimast välimise tsükli läbikäiku, peata sorteerimine. Väldi tühja töö tegemist
Vihjeks: mõtle millised tegevused tehakse sorteerimise käigus ning mida ei tehta arvude puhul mis on juba sorteeritud.
Kaitsmisel: Selgita milliste sisendandmete puhul optimeeritud algoritm parema tulemuse annab ning tõesta seda oma tulemusega.
Lisaülesanne 2: Maatriksi sorteerimine
Selles ülesandes hüppad veidike teemades ette ning pead omapäi tutvuma 2-dimensioonilise massiivi ehk maatriksiga.
Lahenda ülesanne eraldi programmina, kasutades varasemalt tehtud põhjana. Jäta algne lahendus alles! Varem tehtud funktsioonid kuluvad tulevikus ära!
Antud lisaülesande võid lahendada funktsioonideta kuna me pole veel maatriksi edastamisest funktsioonidesse rääkinud.
Massiivi asemel tuleb sorteerida 5 x 5 maatriks
Sorteerimine toimub rida-rea haaval.
Maatriks peab olema algväärtustatud. Kasuta järgnevat maatriksit testimiseks
Soovid oma juba loodud mullsorteerimise funktsiooni ära kasutada? C keeles on võimalik edastada funktsiooni maatriks “rea-kaupa” (tegelikkus on veidi keerulisem aga täidab meie eesmärki. Selleks kutsu funktsioon nii: SortArray(numbers[rowIndex],rowLength);
Sedasi näeb su kood oluliselt ilusam välja.
Pärast tundi peaksid oskama järgmist
Peaksid saama aru mis asi arvu alus on
Peaksid teadma enimlevinuid arvusüsteeme, muuhulgas kahend- ja 16ndsüsteemi.
Peaksid aru saama mis vahe on positsioonilisel ja mittepositsioonilisel arvusüsteemil.
Peaksid aru saama mis asi on bitt ja bait ning mitu bitti on baidis.
Sageli võib tekkida olukord, kus funktsioon ise oleks justkui kenasti korduvkasutatav, kuid kasutajale kuvatav tekst ei sobi. See on tüüpiline üldiste sisend- ja väljundfunktsioonide puhul.
Üks viis seda lahendada on see mida varem tegid – trükkisid teksti enne sisendi/väljundiga tegeleva funktsiooni väljakutset (nt loe arv, loe massiiv, väljasta massiiv). See jääb jätkuvalt mu soovituseks enamikes olukordades. Sedasi on sul vähem keerukust funktsioonis ja funktsioon jääb kergemini korduvkasutatavaks.
Teise valikuna pakun välja alternatiivi, mis on funktsioonide koostamise mõttes üsna tavapärane. Vaatame ühte põhilist ideed millal funktsioon luua – Kui kahe koodilõigu vahel on marginaalne erinevus, mis sunnib sind koodi kopeerima, siis lahenda erinevused kasutades funktsiooni parameetreid. See saab meie ka meie lahenduseks – me saame väljastatava teksti või osa tekstist (nt sõna) edastada parameetrina.
Selline meetod töötab üsna hästi kui kasutajale on vaja selgitada mida ta sisestama peab (st mida programm ootab temast). Samuti sobib see enamasti ka näiteks massiivi väljastamisel kui on vaja väljastuse ette panna kirjeldus.
NB! Kaks olulist mõtet veel! Mõlemast neist räägime süviti semestri teises pooles.
Tekst on samamoodi massiiv – see on tähemärkidest koosnev massiiv. Igal tähemärgil on kusjuures oma indeks.
Erinevalt numbrimassiividest ei ole tekstimassiivi puhul meil selle väljastamiseks vajalik pikkust eraldi kaasa anda (pärast viimast sümbolit kasutatakse erisümbolit, mis annab märku kui string ehk sõne lõpeb).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#define DEFINED_STRING "Passing by using a macro"
voidPrintPassedText(chartext[]);
intmain(void)
{
PrintPassedText("Passing by using a constant");
PrintPassedText(DEFINED_STRING);
charinputString[]="Passing by using a variable";
PrintPassedText(inputString);
}
voidPrintPassedText(chartext[])
{
/* To print double quotes, they need to be escaped first! */
printf("Text passed to this function: \"%s\"\n",text);
}
Teooriakild 2: Massiivi vs massiivi liikme edastamine
Eelmises tunnis tutvustasime kuidas peaks massiivi edastamine funktsiooni. Oluline oli
Massiiv edastatakse alati viitena originaal asukohale
Massiivi sisu saime muuta ka alamfunktsioonides, kehtis kõikjal
Massiiviga tuleks kaasa anda selle pikkus
Massiivi edastades kasutame vaid selle nime, ilma ühegi täiendava märgendita.
Samuti meeldetuletuseks, kasutades massiivi nime järel kantsulge keset koodi indekseerime me selle massiivi konkreetset liiget.
Siit saame kokku ka järgmise näite, kus võrdleme massiivi vs üksiku liikme edastust massiivist.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#define ARR_LEN 5
voidPrintNum(intnum);
voidPrintIntArray(intarr[],intlen);
intmain(void)
{
intnums[ARR_LEN]={9,24,-2,3,25};
/* Passing an entire array */
PrintIntArray(nums,ARR_LEN);
/* Passing the second number in the array */
PrintNum(nums[1]);
/* Passing the fourth number in the array */
PrintNum(nums[3]);
}
voidPrintNum(intnum)
{
printf("Passed number: %d\n\n",num);
}
voidPrintIntArray(intarr[],intlen)
{
printf("Numbers are: ");
for(inti=0;i<len;i++)
{
printf("%d ",arr[i]);
}
printf("\n\n");
}
Esitamisele kuuluvad ülesanded
Selles tunnis tuleb lahendada kaks ülesannet. Täiendavalt on pakutud välja lisaülesanded täiendavate punktide teenimiseks.
Selle algoritmi lahendus on sulle ette antud. Ülesandele on lisatud algoritmis puuduvaid täiendusi.
Algoritm
Nõuded
Programm peab põhinema etteantud algoritmil.
Kasutajalt loetakse 6 arvu ja salvestatakse need massiivi
Programmi vältel koostatakse teine samapikk massiiv põhimõttel negatiivsed numbrid ettepoole, positiivsed nende järel. Arvu 0 loetakse positiivseks arvuks.
Programmi vältel koostatakse ka kolmas massiiv, kuhu kuuluvad vaid nullist suuremad arvud. Massiivi pikkus võib osutuda lühemaks algsest massiivist.
Pärast massiivide koostamist väljastatakse järjest kõik 3 massiivi.
Programm peab endas sisaldama kokku nelja funktsiooni – arvude lugemiseks kasutajalt, arvude ekraanile väljastamiseks, positiivsetest arvudest koosneva massiivi koostamiseks ning etteantud algoritmi alusel järjestatud massiivi koostamiseks.
Kõik enda loodud funktsioonid peavad olema välja kutsutud
main() funktsioonist.
Soovitusi ja vihjeid
Alusta programmi koostamist sisestusest ja massiivi ekraanile kuvamisest. Seda oled juba eelmine kord teinud. Loo vajalik massiiv ja korduvkasuta varasemalt tehtud funktsioone. Kopeerides funktsioone ära unusta ka nendele eelnevat kommentaari kopeerida!
Nüüd lähme ümberjärjestamise juurde. Loo uus massiiv (lisaks olemasolevale), kuhu koostame ümberjärjestatud arvujada. Uue massiivi pikkus on sama nagu esmase massiivi pikkus. Meenuta, et funktsioonist massiivi tagastada ei ole võimalik, seega massiiv tuleb deklareerida
main() funktsioonis ja edastada funktsioonile. Ümberjärjestamise ülesande lahendamiseks jälgi etteantud algoritmi, mis oli esitatud veidi ülevalpool.
Seejärel kutsu uuesti välja massiivi väljastamise funktsioon, sel korral ümberjärjestatud massiivi väljastamiseks. St kood võiks funktsiooni väljakutsete mõttes näha välja umbes sarnane (nimed ei ole olulised):
Siinkohal kui soovid oma
main() funktsiooni puhtamaks saada, siis tasuks massiivi väljastuse ette minev tekst parameetriga kaasa anda. Selleks vaata esimest teooriakildu!
Nüüd liigu viimase funktsiooni juurde, mis peaks ainult positiivsetest arvudest massiivi koostama. Struktuurilt on koostamine on üsna sarnane eelnevalt tehtud ümberjärjestusele, kuid mõned erinevused siiski eksisteerivad. Kui ümberjärjestatud massiiv oli liikmete arvult samapikk algse massiiviga, siis positiivsete arvude massiiv tuleb suure tõenäosusega lühem. Mõtle, kuidas saada koostatud massiivi pikkus alamfunktsioonist välja,
main() funktsiooni! Kui pikkus käes, kutsu jälle
main() funktsioonist välja massiivi väljatrükk, et ka kolmas massiiv ekraanile väljastada.
Testimine
Esimese testina proovime tavapärast juhtu, kui arvude hulgas on nii positiivseid kui negatiivseid numbreid.
Sample 1: Min ind 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Enter number 1 / 6: 6
Enter number 2 / 6: -9
Enter number 3 / 6: 3
Enter number 4 / 6: -12
Enter number 5 / 6: 0
Enter number 6 / 6: 4
The original array
6 -9 3 -12 0 4
The rearranged array
-9 -12 6 3 0 4
The positive number array
6 3 4
Arvesta, et antud olukorras võivad ka positiivsed numbrid puududa. Väljastus peaks jääma jätkuvalt arusaadavaks.
Sample 1: Min ind 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Enter number 1 / 6: -1
Enter number 2 / 6: -4
Enter number 3 / 6: -66
Enter number 4 / 6: -97
Enter number 5 / 6: -3
Enter number 6 / 6: -5
The original array
-1 -4 -66 -97 -3 -5
The rearranged array
-1 -4 -66 -97 -3 -5
The positive number array
Empty array
Ülesanne 2: kahe arvu võrdlus
Loe 5 täisarvu klaviatuurilt
Küsi kasutajalt kaks indeksit / järjekorranumbrit.
Kontrolli, et need oleksid sobilikus vahemikus enne jätkamist! Vajadusel küsi uuesti.
Numeratsioon peab olema sama nagu sisendit küsides.
Soovitus: Kontrollimaks et leidsid õiged numbrid, trüki need välja.
Leia sisestatud positsioonide põhjal nendele vastavad arvud algsest massiivist. Kasutades neid arve tee järgnevat:
Võrdle neid kahte arvu ning kuva nende omavaheline suhe (väiksem, suurem, võrdne)
Koosta jagamistehe ning kuva selle vastus. Tehe tuleb koostada sedasi, et suurem arv on jagatav ning väiksem arv on jagaja.
Vastus anna ühe komakohaga
Ülesandes on vaja luua neli funktsiooni. Funktsioonid on sulle vähemal või rohkemal määral kirjeldatud järgnevas peatükis.
Loodavad funktsioonid
1. Massiivi lugemine. Selleks korduvkasuta koodi varasematest programmidest. Kopeeri funktsioon koos sellele eelneva kommentaariga.
2. Indeksi lugemine. Selleks tuleks luua uus funktsioon. Loome korduvkasutatava funktsiooni, mida saad tulevikus kasutada igal korral, kui on vaja kasutajalt lugeda täisarv kindlas vahemikus (nt 0 … 5, -10 … 10 jne). Kui tegid eelmine nädal lisaülesande ära, on sul see funktsioon suure tõenäosusega juba olemas.
Pakun välja kaks funktsiooni varianti, Vali kumb meelepärasem tundub ja realiseeri see.
Esimene versioon eeldab, et kasutajale esitatav küsimus küsitakse väljaspool seda funktsiooni.
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Description: Asks the user for an integer in between the given limits.
* Repeats until requirements are met and returns the number.
*
* Parameters: min - lower bound for the user input (inclusive)
* max - upper bound for the user input (inclusive)
*
* Return: number within the specified limits
*/
intGetIntInRange(intmin,intmax)
{
}
Teine versioon eeldab, et küsimus saadetakse funktsiooni kaasa ja väljastatakse selle sees. Vaata esimest teooriakildu.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Description: Asks the user for an integer in between the given limits.
* Repeats until requirements are met and returns the number.
*
* Parameters: min - lower bound for the user input (inclusive)
* max - upper bound for the user input (inclusive)
* prompt - prompt for user input, printed before entry
*
* Return: number within the specified limits
*/
intGetIntInRange(intmin,intmax,charprompt[])
{
}
3. Arvude võrdlemine. Siia funktsiooni tuleks edastada 2 arvu, mida võrreldakse omavahel ning väljastatakse kumb neist oli suurem (või olid nad võrdsed). Väljastus toimub funktsioonis sees. Väljastus on kujul “a < b”, “a > b” või “a = b”
NB! Arvude edastamiseks siia funktsiooni vaata teist infokildu!
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Description: Compares the given values (val1 and val2) and prints
* results of the comparison (which is greater; or equal)
*
* Parameters: val1 - first value being compared
* val2 - second value being compared
*
* Return: -
*/
voidCompareValues(intval1,intval2)
{
}
4. Jagatise teostamine. Siia funktsiooni edastatakse samamoodi kaks arvu. Taaskord toimub arvude võrdlemine nagu ka eelmine kord, kuid sel korral määrab võrdluse tulemus jagamistehte operandide järjekorra.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Description: Compares the given values (val1 and val2). Performs the
* division by dividing greater number with the smaller number.
* Both division operation and result are printed.
*
* Parameters: val1 - first value
* val2 - second value
*
* Return: -
*/
voidDivideValues(intval1,intval2)
{
}
Näide lahendusest
NB! Näites on nähtavale jäetud silumiseks kasutatavad read (algusega DEBUG), mida soovitan ka sinul alguses teha. Kui oled indeksite põhjal arvude valimises kindel ja kõik töötab, soovitan need välja kommenteerida.
Sample 1: Min ind 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Enter number 1 / 5: 5
Enter number 2 / 5: -5
Enter number 3 / 5: 24
Enter number 4 / 5: 9
Enter number 5 / 5: 1
Enter first index: -5
Error! Index must be within 1 and 5!
Enter first index: -7
Error! Index must be within 1 and 5!
Enter first index: 0
Error! Index must be within 1 and 5!
Enter first index: 4
DEBUG: Corresponding value: 9
Enter second index: 3
DEBUG: Corresponding value: 24
9 < 24
24 / 9 = 2.7
Testid
Järgnevalt pakun välja osalise loetelu testidest:
Proovi koodi sisenditega, mis peaksid andma tulemuse ilma ühegi veata.
Proovi indekseid, mis on massiivi piiridest väljas. Katseta seda nii esimese kui teise sisendiga.
Proovi massiivi piiridest välja jäävaid indekseid korduvalt, et programm ei läheks edasi enne kui sobilik sisend on saadud.
Proovi piirjuhtusid
Kui loendasid 0 – 4, proovi -1, 0, 4, 5
Kui loendasid 1 – 5, proovi 0, 1, 5, 6
Proovi sisendeid, mis testiksid läbi kõik 3 võrdlusjuhtu (<, >, ==)
Proovi nulliga jagamist. NB! Nulliga jagamine on defineerimata operatsioon. Nulliga jagamine võib jooksutada programmi või isegi kogu arvuti kokku (mikrokontrollerite puhul on tavapärane, et terve seade taaskäivitab end nulliga jagamise tulemusel). Nulliga jagamistehet ei tohi sooritada!
Lisaülesanne 1: ühekordsed numbrid
Ülesanne on tunnitöö #1 laiendus.
Nõuded
Ülesanne peab olema tehtud laiendusena baasülesandele. Baasülesande funktsionaalsus peab säilima täies ulatuses.
Lahenduses võivad korraga esineda mõlema edasijõudnute ülesande tulemused.
Loo uus massiiv olemasolevate arvude põhjal. Uus massiiv tuleb luua põhimõttel, et kõik numbrid tohivad esineda vaid ühekordselt.
Näide lahendusest
Sample 1: Min ind 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Enter number 1 / 6: -5
Enter number 2 / 6: 3
Enter number 3 / 6: 9
Enter number 4 / 6: 3
Enter number 5 / 6: -5
Enter number 6 / 6: 5
The original array:
-5 3 9 3 -5 5
The rearranged array:
-5 -5 3 9 3 5
The positive number array:
3 9 3 5
The nonrecurrent array:
-5 3 9 5
Lisaülesanne 2: paarid
Ülesanne on tunnitöö #1 laiendus.
Nõuded
Ülesanne peab olema tehtud laiendusena baasülesandele. Baasülesande funktsionaalsus peab säilima täies ulatuses.
Lahenduses võivad korraga esineda mõlema edasijõudnute ülesande tulemused.
Leia ja kuva massiivis olevate arvude ja nende vastandarvude paarid.
Oskama edastada nii terviklikku massiivi kui üksikut massiivi liiget funktsiooni
Teadma ja oskama koostada ning kasutada massiive, kus massiivi kõik liikmed (kohad) ei ole kasutusel.
tundma end mugavamalt massiivi käsitledes ka juhtudel, kus läbikäik pole esimesest viimase elemendini.
oskama kopeerida ühest massiivist arve teise massiivi, kusjuures kasutades kahte erinevat indeksit ühes samas tsüklis erinevate massiivide indekseerimiseks.
Tundma ennast juba natuke kodusemalt funktsioone kasutades.
Selle nädala tunnitöö on jupitatud kaheks osaks. Alguses lahenda esimene osa ja esita oma lahendus. Seejärel laienda lahendust teise osaga ning esita oma lahendus uuesti. Baasülesandele on sel korral pakutud 2 laiendavat lisaülesannet.
Ülesanne 1 osa 1: ekstreemumite leidmine
Ülesande esimene osa on tunnis tehtud UML tegevusdiagrammi realisatsioon C programmikoodina. Esimeses osas pead sa kokku looma 4 funktsiooni lisaks
main() funktsioonile!
Esimene ülesande osa peab vastama tunnis tehtud UML tegevusdiagramile.
Ülesande lahendamiseks pead looma 4 funktsiooni. Funktsioonid on aluskoodis kirjeldatud kommentaaridena. Kirjuta oma funktsioon kohe kommentaari järgi. Lisa puuduvad elemendid nagu makrod, muutujate deklaratsioonid, funktsioonide prototüübid ja väljakutsed.
Klaviatuurilt loetakse 6 täisarvu, mis salvestatakse massiivi.
Sisestuse kulg peab olema kasutajale arusaadav, näidates mitmendat arvu parasjagu sisestatakse ning mitu kokku kasutajalt oodatakse.
Massiivist leitakse ja väljastatakse suurim sisestatud arv. Vähim arv tuleb leida funktsioonis, mis tagastab tulemuse. Tulemuse väljastus toimub main() funktsioonis.
Massiivist leitakse ja väljastatakse vähim sisestatud arv. Suurim arv tuleb leida funktsioonis, mis tagastab tulemuse. Tulemuse väljastus toimub main() funktsioonis.
Väljastatakse algselt sisestatud massiivi kõik liikmed. Väljastus loo eraldi funktsioonis.
Ülesande lahendamise juhend
NB! Enne funktsioonide loomist loe läbi aluskoodis olev funktsiooni kirjeldus ja veendu, et saad sellest aru (st mida funktsioon teeb, mis on selle parameetrid ja kas ning mida see funktsioon tagastab. Iga funktsioon tuleb realiseerida ettekirjutatud funktsiooni kommentaari järel.
Alusta funktsiooni
ReadIntArray() lahendamisest. See on esimene funktsioon kohe pärast main() funktsiooni. Sul tuleb kirjutada tsükkel, mille igal kordusel küsitakse kasutajalt väärtus ning seejärel loetakse see massiivi.
Testimaks kas see töötab, pead selle funktsiooni välja kutsuma. Selleks pead esmalt massiivi deklareerima kus arve hoida. Seejärel kutsu funktsioon
ReadIntArray() välja, andes talle kaasa loodud massiiv ning selle pikkus.
Eeldusel, et pikkust kirjeldav makro nimi on
NUM_CNT ja massiivi nimi on
numbers , võiks selle funktsiooni väljakutse näha välja midagi sarnast:
ReadIntArray(numbers, NUM_CNT); Proovi nüüd kas massiivi arvude lugemine toimis.
Veendumaks, et numbrid ka korrektselt loetud said peaksid massiivi sisu välja trükkima. Selleks realiseeri funktsioon
PrintArray() ja kutsu see välja main() funktsioonist. Sel korral pead tagastuse tüübi ja parameetrid ise valima. Kui funktsioon tehtud ja välja kutsutud, peaksid nägema oma massiivi sisestatud numbreid.
Nüüd tuleb sul veel viimased kaks funktsiooni lõpetada. Mõlemad on kirjeldatud kommentaaridena aluskoodis. Lõpeta funktsioonid ja väljasta tulemused. NB! Tulemust tohid väljastada vaid main() funktsioonis. Min ja max väärtuste leidmiste funktsioonides väljastada tulemust ei tohi! Selleks pead tulemuse nendest funktsioonidest esmalt tagastama.
Testimine
Test 1: min esimene, max viimane
Sample 1: Min ind 0
1
2
3
4
5
6
7
8
9
10
11
12
Enter number 1 / 6: 1
Enter number 2 / 6: 2
Enter number 3 / 6: 3
Enter number 4 / 6: 4
Enter number 5 / 6: 5
Enter number 6 / 6: 6
Entered numbers:
1 2 3 4 5 6
Min value is 1
Max value is 6
Test 2: min viimane, max esimene
Sample 2: max is ind 0
1
2
3
4
5
6
7
8
9
10
11
12
Enter number 1 / 6: 6
Enter number 2 / 6: 5
Enter number 3 / 6: 4
Enter number 4 / 6: 3
Enter number 5 / 6: 2
Enter number 6 / 6: 1
Entered numbers:
6 5 4 3 2 1
Min value is 1
Max value is 6
Test 3: Negatiivne min. Min ja max on massiivi keskel.
Sample 2: min and max in the middle
1
2
3
4
5
6
7
8
9
10
11
12
Enter number 1 / 6: 1
Enter number 2 / 6: 2
Enter number 3 / 6: 3
Enter number 4 / 6: 4
Enter number 5 / 6: -933
Enter number 6 / 6: 1
Entered numbers:
1 2 3 4 -933 1
Min value is -933
Max value is 4
Ülesanne 1 osa 2: asukohtade ja korduste arvu leidmine
Ülesande esimeses osas leidsid massiivist ekstreemväärtused. Teises osas tuleb leida nende positsioonid ning mitu korda väärtused massiivis esinesid.
Nõuded
Kuva kõik positsioonid, kus asus massiivi suurem väärtus. Tulemus tuleb leida ja väljastada eraldi funktsioonis
Kuva kõik positsioonid, kus asus massiivi väikseim väärtus. Tulemus tuleb leida ja väljastada eraldi funktsioonis
Kuva mitu korda suurim ja suurim väärtus massiivis eksisteeris. Tulemus tuleb leida eraldi funktsioonis, tagastada ning seejärel väljastada
main() funktsioonis.
Kuvatavad positsioonid peavad olema vastavuses sisestusega.
Ülesande lahendamise juhend
Selle osa lahendamiseks pead looma kokku kaks funktsiooni. Mõlemad funktsioonid on kirjeldatud funktsiooni kommentaaridena. Kopeeri funktsiooni kommentaar enda koodi ja kirjuta lahendus selle järel
Esimene funktsioon väljastab eelnevalt leitud ekstreemumväärtuse kõik asukohad massiivis. Selle lahendamiseks pead looma tsükli, mis käib läbi kõik massiivi liikmed. Iga kord, kui massiivi liikme väärtus on sama kui sinu otsitav (nt minimaalne väärtus massiivis), pead väljastama ekraanile oma praeguse asukoha tsüklis (tsükli praeguse korduse väärtus on seotud massiivi positsiooniga). St kogu funktsioon sisaldab ühte tsüklit, ühte tingimuslauset ja ühte väljastuslauset – ongi kõik.
Loodavat funktsiooni pead korduvkasutama (st 2x välja kutsuma) nii minimaalse kui maksimaalse väärtuse asukohtade kuvamiseks! Tulemustele eelnev tekst (nt “Min value position(s)”) tuleks väljastada main() funktsioonis, enne selle funktsiooni väljakutset.
1
2
3
4
5
6
7
8
9
10
/**
* Description: Prints all positions of val in the array. Shows positions
* (starting from 1), instead of indexes.
*
* Parameters: nums - values that are checked
* len - length of the array
* val - value for which the positions will be printed
*
* Return: -
*/
Kui funktsioon valmis, kontrolli, et see töötab enne kui lähed järgmist funktsiooni lahendama!
Teine funktsioon saab olema vägagi sarnane eelmisele. Sel korral aga peame loendama (st ühte täisarvulist muutujat suurendama sobilikul hetkel) väljastamise asemel. Väljastust selles funktsioonis teha ei tohi! Funktsioon peab oma tulemuse tagastama. Tulemus väljastatakse main() funktsioonis.
1
2
3
4
5
6
7
8
9
/**
* Description: Counts the number of times val is present in the array
*
* Parameters: nums - values that are checked
* len - length of the array
* val - value to search for
*
* Return: number of times val occurred in array
*/
Testimine
Test 1: min ja max on ühekordsed
Sample: min and max single occurrence
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Enter number 1 / 6: 10
Enter number 2 / 6: 11
Enter number 3 / 6: 12
Enter number 4 / 6: 13
Enter number 5 / 6: 14
Enter number 6 / 6: 15
Entered numbers:
10 11 12 13 14 15
Min value is 10
Min value position(s): 1
Min value occurred 1 time
Max value is 15
Max value position(s): 6
Max value occurred 1 time
Test 2: min ja max korduvad
Sample: min and max multiple occurrence
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Enter number 1 / 6: 10
Enter number 2 / 6: 13
Enter number 3 / 6: 12
Enter number 4 / 6: 10
Enter number 5 / 6: 13
Enter number 6 / 6: 13
Entered numbers:
10 13 12 10 13 13
Min value is 10
Min value position(s): 1 4
Min value occurred 2 times
Max value is 13
Max value position(s): 2 5 6
Max value occurred 3 times
Lisaülesanne 1: Tulemuste leidmine massiivist
Selles osas leiame kolm täiendavat tulemust massiivist
Nõuded
Loo kolm funktsiooni, vastavalt summa, korrutise ja aritmeetilise keskmise leidmiseks.
Aritmeetilise keskmise funktsiooni sisuks ei tohiks olla koopia summa funktsioonist (väldi koodi kopeerimist!). Selle asemel kasuta summa leidmise funktsiooni keskmise leidmise osana.
Kõik kolm funktsiooni saavad parameetriteks massiivi ja selle pikkuse ning peavad oma tulemused tagastama. Tulemused väljastatakse
main() funktsioonis.
Kuva aritmeetiline keskmine kolme komakohaga
Testimine
Selle ülesande kõige suuremaks komistuskiviks on õige aritmeetilise keskmise leidine.
Sample: precision test for avg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Enter number 1 / 6: 1
Enter number 2 / 6: 1
Enter number 3 / 6: 1
Enter number 4 / 6: 1
Enter number 5 / 6: 1
Enter number 6 / 6: 3
Entered numbers:
1 1 1 1 1 3
Min value is 1
Min value position(s): 1 2 3 4 5
Min value occurred 5 times
Max value is 3
Max value position(s): 6
Max value occurred 1 time
Sum is 8
Product is 3
Arithmetic mean is 1.333
Lisaülesanne 2: n-arvu sisestus
Pakkumaks kasutajale veidi kasulikumat programmi, peaks kasutaja saama otsustada mitme numbri pealt ta statistikat soovib leida. Pakume kasutajale võimaluse sisestada sisestatavate arvude koguse.
NB! Kuigi suur osa C keele kompilaatoritest toetab muutuva pikkusega massiivide (VLA – variable length array) kasutamist, ei ole see kõigi C standardite kohustusliku osana. St tugi võib kompilaatoris puududa täielikult)
Täiendavalt on VLAde puhul ka teisi probleeme – nt on need sageli aeglasemad kui staatilise suurusega massiivid. VLAd sisaldav kood sisaldab rohkem käske, mis omakorda vajab rohkem protsessori tsükleid (aega) rakenduse jooksutamiseks. Samuti kui ühtegi rangelt nõutud piirangut ei ole, siis on üsna lihtne kogu programm kokku jooksutada, andes ette lihtsalt suurema numbri (nt tahan sisestada 1 000 000 numbrit).
Seetõttu ei ole sul sel korral lubatud kasutada massiive, mille pikkus on määratud teise muutuja kaudu (nt
intnumbers[numberCount]; , kus
numberCount on täisarvuline muutuja, mis saab oma väärtuse programmi töö ajal). Standardis toetatud universaalne lahendus on kasutada dünaamilist mälu, kuid seda vaatame Programmeerimine 2 aine raames.
Selle ülesande raames peaksid leidma ja määrama maksimaalse võimaliku suuruse, millest kasutaja rohkem numbreid sisestada ei saa. See tähendab, et suure tõenäosusega jääb suur osa massiivi pesadest kasutama. Õnneks on suurused väikesed, seega märkimisväärset probleemi see ei tekita meile.
NB! Enamjaolt on selles aines VLAde kasutamine lubatud. Piirang on seatud ülesandepõhiselt.
Nõuded
Luba kasutajal pärast programmi käivitamist otsustada mitme numbriga programm töötab.
Piira programmi poolt toetatud numbrite kogust vastavalt loodud massiivi suurusega,
Kasutaja poolt sisestuse küsimine peab olema teostatud eraldi funktsioonis, mille pead looma selle ülesande jaoks. Funktsioon tohib alles siis tagastada, kui sisestatud number on sobilik.
Kasuta funktsiooni parameetreid piirangute seadistamiseks.
Funktsioon mille lood peaks olema korduvkasutatav teistes sarnastes situatsioonides (kuid teiste piirangutega)
Numbrite vahemiku võid ise otsustada mõistlikus vahemikus (nt kuni 50 numbrit).
Ebasobiva numbrite arvu korral loo veakäitumine.
Muutuva pikkusega massiivi (VLA – variable length array) kasutada ei tohi.
NB! Vaata üle ka koodimisstiil! Muutuja ei tohi olla kirjutatud samas stiilis nagu makro (tüüpviga).
Testimine
Testi hoolikalt kindlasti järgmist
Minimaalne lubatud numbrite arv
Maksimaalne lubatud numbrite arv
Numbrite arv, mis on erinev algsest
Sample: testing of user entered n
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Enter number count (up to 50): 127
Error! Invalid number count!
Enter number count (up to 50): 3
Enter number 1 / 3: 5
Enter number 2 / 3: 1
Enter number 3 / 3: 2
Entered numbers:
5 1 2
Min value is 1
Min value position(s): 2
Min value occurred 1 time
Max value is 5
Max value position(s): 1
Max value occurred 1 time
Sum is 8
Product is 10
Arithmetic mean is 2.667
Pärast tundi peaksid
Tutvuma kodutöö 1 nõuete ja tutvustavate videotega
Teadma mida tähendab tüübiteisendus ning kuidas seda kasutada (type casting)
Teadma mis asi on murdarvude esitustäpsus ning mis probleeme sellega esineda võib
Teadma mis asi on püsikomaarv (fixed point notation) ja mis on ujukomaarv (floating point notation).
Teadma mis asi on matemaatika teek (math.h), kuidas seda kasutada, mis seal sees on ning kuidas lisada kompilaatorile täiendav lipp, et see ka kompileeruks.
Selles laboris on 2 baasülesannet, mille raames lood kokku 5 programmi. Täiendavalt on laboris 2 lisaülesannet, mis tohib olla kirjutatud ühe programmina.
Ülesanne 1: 5-arvu summa.
Selle ülesande raames tuleb sul luua programm, mis leiab viie kasutaja poolt sisestatud arvu summa. Programm tuleb sul luua 3 korda – üks programm iga tsükli tüübi kohta. Kõik kolm loodavat programmi täidavad sama ülesannet.
Näidis oodatavast tulemusest
Näide: 5-arvu summa programm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
See programm liidab kokku 5 kasutaja poolt sisestatud arvu ning kuvab jooksvalt vahesummasid.
Sisesta arv 1 / 5
9
Vahesumma on 9
Sisesta arv 2 / 5
3
Vahesumma on 12
Sisesta arv 3 / 5
2
Vahesumma on 14
Sisesta arv 4 / 5
1
Vahesumma on 15
Sisesta arv 5 / 5
5
Lõppsumma on 20
Nõuded
Programm küsib kasutajalt 5 arvu.
Pärast arvu sisestamist kasutaja poolt tuleb väljastada praegune summa.
Pärast viimase arvu sisestamist kuvatakse lõppsumma. Vahesummat enam ei kuvata.
Programm peab andma kasutajale arusaadava väljundi mida temast oodatakse.
Programmis ei tohi olla maagilisi arve.
Programmi disain peab olema selline, et kui sama ülesannet tuleks teha 10, 20 või ka 1000 arvu korral, siis selleks peaksid muutma programmikoodis vaid ühte numbrit! Testi seda enne esitamist – tehes muudatuse vaid ühes kohas kogu programmis peab see töötama näiteks 7 arvuga.
Vihjeid
Mõtle hoolikalt läbi milliseid muutujaid sul vaja on! Olenemata sellest mitme arvu summat sa leiad on muutujate arv alati sama.
Tsüklite puhul on soovitatav loendamist alustada nullist. Seda kuna arvutite puhul hakatakse loendama nullist ning väga paljud süsteemid sõltuvad sellest. Tavaline arvutikasutaja aga hakkab loendama ühest. Selleks
(i + 1) võtab muutuja i väärtuse ning kasutab seda suurendatud väärtust konkreetse tehte juures. Küll aga ei suurenda see i enda väärtust. Sedasi saame ajutiselt kasutada ühe võrra suuremat väärtust. Näiteks
printf("%d",i+1);
Operatsioonid nagu i++, ++i, i += 1 ja i = i + 1 jällegi suurendavad i väärtust jäädavalt.
Ülesanne 2: kassasüsteem tsüklitega
Selle ülesande juures lisame mõned elementaarsed veakontrollid eelmisel nädalal tehtud tunnitööle. Aluskoodiks võid kasutada nii enda eelmise nädala programmi kui ka meie poolt antud valmislahendust.
Selles laboris kuulub enamik tööd koos läbi tegemisele. Laboris kuulub esitamisele üks baasülesanne ja üks lisaülesanne.
Ülesanne 1: Paarsuse kontroll (baasülesanne)
Nõuded
Kasutajalt küsitakse ja seejärel loetakse sisse täisarv.
Programm väljastab kas sisestatud arv oli paaris või paaritu.
Pseudokood
Pseudokood on üks võimalus kirjeldada algoritme. Pseudokood on sarnaselt programmile struktuurne, kuid ei hõlma endas programmeerimiskeeltele omaseid reegleid ning jääb seega inimloetavaks.
1
2
3
4
5
6
Kasutaja sisestab täisarvu
Kui sisestatud arv on paaris:
Trüki: „Sisestatud arv on paaris!“
Muul juhul
Trüki: „Sisestatud arv on paaritu!“
Programmi lõpp
Ülesande taust
Mooduljagamine on laialdaselt kasutusel kõiksugu kontrollkoodide arvutamisel. Näiteks kontrollimaks kas isikukood või pangakaardi number on korrektne.
Meie ülesande jaoks rakendame mooduljagamist kahega ehk teostame paarsuse kontrolli – kas arv on paaris või paaritu. Paarsuse kontroll on üks lihtsamatest veakontrollidest näiteks andmesides – kas väärtusega ‘1’ bittide arv andmepaketis on paaris või paaritu? Sedasi on võimalik näiteks kontrollida kas andmete ülekandmisel ühest arvutist teise tekkis viga (ja nagu öeldud, vaid väga lihtsad juhud).
Testimine
Sellel programmil on 2 võimalikku tulemust – arv on paaris või paaritu. Programmi põhjalikuks testimiseks tuleb testida eraldi mõlemat juhtu.
Test 1: paarisarv
Sample 1: even integer test
1
2
3
Please enter an integer:
2
The number 2 is an even number.
Test 2: Paaritu arv
Sample 2: odd integer test
1
2
3
Please enter an integer:
19
The number 19 is an odd number.
Ära unusta oma tunnitööd ette näitamast!
Lisaülesanne: Kolme ja viiega jagamine
Enne edasijõudnute ülesande tegemist lahenda ära tavaülesanne!
Kasutajalt küsitakse ja seejärel loetakse sisse täisarv
Programm väljastab kas arv jagus kolmega, viiega, mõlemaga neist või mitte kummagagi ning väljastab leitu.
Programm leiab jagatise täisosad ja jäägid sellest arvust jagades seda nii kolme kui viiega. Kõik neli tulemust väljastatakse olenemata sisendist.
Arvutustehteid (nt jagamisi) tohid teha vaid ühekordselt. Kui tulemust läheb vaja kasutada mitmes kohas, tuleb need eelnevalt salvestada muutujatesse.
Ülesande taust
Ülesanne põhineb klassikalisel intervjuuküsimusel mida kasutakse tarkvaraarendajate värbamisel. Tegu on nn FizzBuzz ülesande muudetud versiooniga.
Testimine
Lähtuvalt koostatud tingimustest peab ülesandel olema 4 erinevat võimalikku tulemust.
Test 1: Arv, mis jagub nii kolme kui viiega
Sample 1: divisible by both
1
2
3
4
Enter a number to check: 15
Divisible by both 3 and 5.
By dividing 15 with 3, we get 5 multiples of 3 and a remainder of 0.
By dividing 15 with 5, we get 3 multiples of 5 and a remainder of 0.
Test 2: Arv mis jagub ainult kolmega
Sample 2: divisible by 3 only
1
2
3
4
Enter a number to check: 27
Divisible by 3 only.
By dividing 27 with 3, we get 9 multiples of 3 and a remainder of 0.
By dividing 27 with 5, we get 5 multiples of 5 and a remainder of 2.
Viimased 2 testi mõtle ise välja. Veendu, et lahendus töötab korrektselt kõigil juhtudel.
Pärast seda tundi peaksid
Mõistma ainega seotud nõudeid, sh kuidas saada aines hinne.
Oskama sisse logida Linuxisse ülikooli arvutis
Teadma mis on peamised rakendused mida kasutame
Teadma kust vajalikku materjali leiab
Teadma mis on C keel ja kus seda peamiselt kasutatakse
Teadma milline on programmi struktuur ning olema võimeline ka selles lihtsa programmi kirjutama ning käivitama. Peaksid mõistma järgmiseid programmeerimisega seotud mõisteid ja kontseptsioone
#include preprotsessori käsklus
Mis on main() funktsioon, miks ta eriline on
Kuidas deklareerida muutujat, mis on andmetüüp
Kuidas trükkida teksti kasutades printf funktsiooni, vahetada rida, printida välja ühe või mitme muutuja sisu.
Klaviatuurilt väärtuste lugemine ja salvestamine (printf funktsioon)
Elementaarsed matemaatika operatsioonid
Kergemad tingimuslaused (if/else)
Täisarvu jagatis, moodularvutus
Mõistma mis asi on algoritm
Mõistma, mis asi on UML ja miks seda kasutatakse. Saama aru selle algsetest elementidest (algus, lõpp, tegevus, hargnemine, koondumine). Pead olema võimeline lihtsama UML diagrammi kokku panna.
Miks on oluline, et algoritmid on kirjeldatud sedasi, et nad on kõigile üheselt arusaadavad.
Youtube: Exact Instructions Challenge – THIS is why my kids hate me. | Josh Darnit https://www.youtube.com/watch?v=cDA3_5982h8