PR1ET5: Massiivid

Praktikumi materjal

Esitamisele kuuluvad ülesanded

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 [W05-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!

Lae alla ülesande aluskood: https://blue.pri.ee/ttu/files/iax0583/aluskoodid/5_minmax_template.c

Nõuded
  • Esimene ülesande osa peab loogilisel tasemel 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 arvu kokku kasutajalt oodatakse
  • Massiivist leitakse ja väljastatakse suurim sisestatud arv. Tulemus tuleb leida funktsioonis ning tagastada. Tulemuse väljastus toimub main() funktsioonis
  • Massiivist leitakse ja väljastatakse vähim sisestatud arv. Tulemus tuleb leida funktsioonis ning tagastada. Tulemuse väljastus toimub main() funktsioonis
  • Väljasta eraldi funktsioonis kõik sisestatud massiivi liikmed
Ü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.

  1. Alusta funktsiooni  ReadIntArray()  lahendamisest. See on esimene funktsioon kohe pärast main() funktsiooni. Selleks kirjuta tsükkel, mille igal kordusel küsitakse kasutajalt väärtus, mis salvestatakse massiivi.
  2. Testimaks, kas see töötab, pead selle funktsiooni välja kutsuma. Selleks pead esmalt deklareerima massiivi, 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.
  3. 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.
  4. Nüüd tuleb sul veel viimased kaks funktsiooni lõpetada. Mõlemad on kirjeldatud kommentaaridena aluskoodis. Lõpeta funktsioonid ja väljasta tulemused.
    NB! min ja max väärtusi leidvatel funktsioonidel ei tohi olla kõrvalmõjusid, tulemused väljasta main() funktsioonis. 
Testimine

Test 1: min esimene, max viimane

Test 2: min viimane, max esimene

Test 3: Negatiivne min. Min ja max on massiivi keskel.

Ülesanne 1 osa 2 [W05-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 suurim väärtus. Tulemus väljastatakse funktsiooni sees, mis positsioone leiab.
  • Kuva kõik positsioonid, kus asus massiivi vähim väärtus. Tulemus väljastatakse funktsiooni sees, mis positsioone leiab.
  • Kuva, mitu korda suurim ja vähim väärtus massiivis eksisteerib. Tulemus tuleb leida eraldi funktsioonis, tagastada ning seejärel väljastada main()  funktsioonis.
  • Kuvatavad positsioonid peavad olema vastavuses sisestusega.
  • Kõigil funktsioonidel su koodis peavad olema funktsiooni kommentaarid (st funktsioonile eelnev kommentaar)
Ü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.

Testi funktsiooni tööd enne lahendamise jätkamist!

Teine funktsioon saab olema vägagi sarnane eelmisele. Sel korral aga peame loendama (st ühte täisarvulist muutujat suurendama sobilikul hetkel) väljastamise asemel. Funktsioon peab oma tulemuse tagastama. Tulemus väljastatakse main() funktsioonis.

Testimine

Test 1: min ja max on ühekordsed

Test 2: min ja max korduvad

Lisaülesanne 1 [W05-3]: 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.

Lisaülesanne 2 [W05-4]: 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 kasutav 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 int numbers[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 lubatud sisestuse vahemiku määramiseks
    • Funktsioon, mille lood, peab olema korduvkasutatav teistes sarnastes situatsioonides (erinev lubatud numbrivahemik)
  • 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

Pärast tundi peaksid

  • 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.
  • Teadma, mis asi on massiiv
  • Oskama massiivi deklareerida
  • Oskama massiivi algväärtustada
  • Oskama indekseerida igat massiivi liiget
  • Oskama indekseerida massiive kasutades tsükleid
  • Oskama leida ekstreemväärtusi arvujadast

Täiendav materjal