10. labor: menüü-programm

Teooriat ja meeldetuletusi

Tähemärk, sõne ja väljastusfunktsioonid

Kuigi sõnede juurde tuleme alles mõne nädala pärast võime mõnda omadust ikkagi vaadata.

Sõne (string) tähendab järjestatud tähemärkide jada. St selleks võib olla arusaadav sõna või lause, kuid võib olla ka arusaamatu erinevate sümbolite jada. Sõned on alati jutumärkide vahel.

Näited:

    • "a"
    • "Hello!"
    • "I do wish we could chat longer, but I'm having an old friend for dinner."
    • "lFRD=)m+0FDj2"

Üksikut tähemärki hoiame aga ülakomade vahel. Sõne koosneb sellistest tähemärkidest. NB! Kaldkriipsuga hakkavad erisümbolid (escape sequence) ja neid loetakse üheks tähemärgiks (nt \n  on üks tähemärk arvuti mälus).

Näited:

    • 'a'
    • 'y'
    • '\n'
    • '\t'

Funktsioonid mida saame kasutada teksti väljastamiseks

  • printf()  ehk print formatted. Tegu on kõige keerukamaga seniõpitutest, mille abil saame trükkida kujundatud teksti, mille abil saame ka kõiksugu muutujate sisu väljastada. Reavahetus käib käsitsi!
    Näiteks: printf("Hello, %s!\n", name);
  • puts()  ehk put string. Tegu on lihtsa funktsiooniga mis on mõeldud ühe tekstilõigu kuvamiseks. See ei toeta keerukaid formaate ega muutujatest teksti väljastamist. Reavahetus lisatakse automaatselt.
    Näiteks: puts("Hello, user!");
  • putchar()  ehk put character. See on kõige lihtsam funktsioon neist kõigist. Selle abil saab väljastada vaid ühe tähemärgi. Seda on mugav kasutada nt reavahetuse trükkimiseks.
    Näiteks: putchar('\n');

Massiivi edastamine funktsiooni

Massiive alamfunktsioonidesse edastades andsime edasi viite originaalile – st me saame edastatud massiivi muuta ilma tagastamata ja olenemata kohast.

Reeglina tuleb alati massiiviga koos edastada selle kõigi dimensioonide suurused. Pärast funktsiooni edastamist neid suurusi välja arvutada enam ei ole võimalik! Erandiks on sõned (string), millest räägime tulevikus.

Mõned eripärad edastamisel

  • Kui soovid edastada tervet massiivi, olenemata selle dimensioonide arvust, täpsustame vaid selle massiivi nime Func(numbers);
  • Kui soovid 1-dimensioonilisest massiivist int numbers[N];  edastada vaid ühe väärtuse, täpsustame selle indeksi Func(numbers[2]); . Funktsioonis käsitle seda ühte arvu  Func(int val);
  • Kui soovid 2-dimensioonilisest massiivist ( int numbers[N][M];  edastada rea alguse, täpsustame selle indeksi ja pikkuse Func(numbers[2], M); . Funktsioonis käsitle seda kui 1-dimensioonilist massiivi  Func(int numbs[], int n);
  • Kui soovid 2-dimensioonilisest massiivist int numbers[N][M];  edastada vaid ühe väärtuse, täpsustame selle indeksi Func(numbers[2][1]);

Kahe arvu omavahel vahetamine massiivis

Vahetamaks kahte arvu sobib lahenduseks mullsorteerimise tunnist õpitud vahetamise idee kasutades abimuutujat

Märkus: isegi kui soovid vahetada kahe rea või veeru väärtusi on ikkagi vaja vaid ühte muutujat.

Massiivi kasutamine abimuutuja asemel on mõistlik vaid paralleeltöötlust toetavatele protsessoritele programme kirjutades. Sellised protsessorid põhinevad SIMD (sing-instruction-multiple-data) arhitektuuril – näiteks graafikakaardid (GPU – graphics processing unit).

Massiivide algväärtustamine nulliks

Terve massiivi algväärtustamiseks nulliks paneme soovitud konstandi loogeliste sulgude vahele

Kui tegu on 2-dimensioonilise massiiviga, kasutame kahte komplekti loogelisi sulge.

Esitamisele kuuluvad ülesanded

Selles tunnis tegeleme programmiga, mis töötab senikaua kuniks kasutaja soovib sellest väljuda. Programmi raames tegeleme maatriksi manipuleerimisega.

Alusta näidisprogrammiga tutvumisest, misjärel mine edasi ülesande lahendamise kallale.

Tunnitöö näidisprogramm

Sulle on antud tänasest tunnitööst näidisprogramm. See on antud kompileeritud kujul, st saad selle käivitada ja testida milline selle lõpptulemus peaks välja nägema. Sinu loodav programm peaks lõpuks töötama sarnaselt.

Mõlemad näidisprogrammid on kompileeritud x86-64 arhitektuurile. Garanteeritud töötavad mõlemad laboriarvutitel, kuid peaksid ka töötama enamikel isiklikel arvutitel. Probleeme võib tekkida ARM protsessoritega arvutitel ilma x84-64 emulatsiooni kasutamata.

NB! Linuxil kasutamiseks pead andma failile käivitamisõigused (turvalisus ennekõike!). Õiguste muutmine on ühekordne tegevus. Selleks toimi nii:

See lisab (chmod – change mode) kasutajale (u – user) õigused programmi käivitada (x – execute). Pärast seda tohid programmi käivitada tavapäraselt, st ./program_name

Kirjeldus

Tänane tunnitöö on jaotatud kaheks eraldi hinnatavaks osaks, millele on võimalik juurde teha kolm lisaülesannet

Antud juhul on tegu programmiga, mis töötab kuniks kasutaja soovib sellest väljuda. Seetõttu peame me ka vajadusel jälgima mis seisundis meie maatriks parasjagu on.

Maatriksi maksimaalne suurus mälus on fikseeritud makrotega LIMIT_ROWS ja LIMIT_COLS , mis määravad vastavalt maksimaalse ridade ja veergude arvu. Neid pead eraldi kasutama!

Programmis võib vastavalt kasutaja soovile olla kasutusel parasjagu väiksem osa maatriksist – sellisel juhul jääb lihtsalt otsa maatriksist kasutamata. Seetõttu on funktsioonide prototüüpides igal pool 2 muutujat int rows  ja int cols , mis sisaldavad hetkel kasutusel oleva maatriksi piire.

Lae alla aluskood: https://blue.pri.ee/ttu/files/iax0583/aluskoodid/10_switch_basecode.c

Üldised nõuded

Need nõuded kehtivad olenemata millise osaga programmi lahendamisest tegeled.

  • Sinu lahendus peab võimalikult täpselt matkima etteantud näidisprogrammi.
  • Töö peab olema ehitatud etteantud aluskoodile.
    • Aluskoodi tohid mõistlikes piirides modifitseerida. Näiteks võib kasu olla tegevuste järjekorra muutmisest main() funktsioonis või funktsioonile GetIntInRange() täiendava parameetri lisamisest. Muudel juhtudel mõtle hoolikalt läbi kas muudatus on ikka mõistlik!
    • Aluskoodis on sinu jaoks juba valmis tehtud 2 funktsiooni, kasuta neid vastavalt vajadusele.
    • Aluskoodis on ette antud kahe esimese funktsiooni prototüübid millest peaksid lahendamist alustama tehes tunnitöö esimest osa.
  • Maatriksis olevad arvud on kõik vahemikus 0 – 99.
  • Kõik toimingud peavad olema korratavad ilma programmist väljumata.
  • Kõigi menüü valikute töötlev pool peab olema lahendatud eraldi funktsioonides.
    • switch()-i sees võid julgelt printida välja abiteksti, salvestada funktsioonidest tagastatavaid väärtusi jne. Äärmisel vajadusel võid ka mõne if lause sinna panna.
    • Täiendavaid tsükleid kindlasti main() funktsiooni kirjutada ei tohi!
  • Programm peab olema terviklik ja arusaadav ning töötama kuniks kasutaja soovib sellest ise väljuda.

Tunnitöö osa 1

Esimeses osas loome maatriksi kuvamise ja genereerimise.

Nõuded

  • Kasutaja saab genereerida n * m maatriksi
    • Maatriksi liikmeteks on juhuarvud vahemikus 0 – 99
    • n ja m on kasutaja poolt sisestatavad väärtused. Vajadusel loo piirangud kasutaja sisestusele
    • Genereerimise funktsioonis  GenerateMatrix()  tohid kasutada vaid do while()  tüüpi tsükleid.
    • Meeldetuletus: C funktsioonid on lihtsad ja teevad vaid ühte asja (ning teevad seda hästi)! Funktsioon GenerateMatrix() ei tohi tegeleda kasutajalt sisendi küsimisega!
  • Kasutaja saab kuvada maatriksit
    • Kuvamise funktsioonis tohid kasutada vaid while()  tüüpi tsükleid
    • Maatriks peab olema viisakalt joondus.
  • Kasutaja saab väljuda programmist

Tunnitöö osa 2

Teises tunnitöö osas loome funktsioonid ridade ja veergude omavahel vahetamiseks.

  • Kasutaja peab saama vahetada kaks enda valitud rida omavahel ära
    • Vahetamise funktsioonis tohid kasutada vaid for()  tüüpi tsükleid.
  • Kasutaja peab saama vahetada kaks enda valitud veergu omavahel

Tüüpilised vead

  • Copy-paste ehk korduv kood. Enamasti on selleks sisestus (nt sisesta ridade arv, sisesta veergude arv jne).
  • Off by one ehk ühega mööda. Meeldetuletuseks esimene rida on indeksiga 0.
  • Maagilised numbrid
  • Maatriksi operatsioonide lubamine enne maatriksi genereerimist. Näiteks sa ei saa kuvada maatriksid, mida ei ole veel genereeritud!
  • Vale tsükli tüübi kasutamine (Osa 1 ja 2 puhul on fikseeritud milliseid tsükli tüüpe tohid kasutada)
  • Ridade ja veergude arvu sassi ajamine. Proovi näiteks
    • genereerida 3 x 5 maatriks, vaheta ära read 1 ja 3
    • genereerida 5 x 3 maatriks, vaheta ära veerud 1 ja 3

Lisaülesanne 1: kustutamine

Lisame täiendava funktsionaalsuse olemasolevasse programmi

  • Kasutaja saab kustutada enda valitud rea.
  • Kasutaja saab kustutada enda valitud veeru.
  • Kustutatud rida või veerg eemaldatakse vahelt, mistõttu järgmised read või veerud tulevad varasemaks. Maatriksi suurus väheneb.
  • Lisa vajalik funktsionaalsus menüüsse.

Lisaülesanne 2: lisamine

Lisame täiendava funktsionaalsuse olemasolevasse programmi

  • Kasutaja saab soovitud asukohta lisada täiendava rea
  • Kasutaja saab soovitud asukohta lisada täiendava veeru
  • Kõik elemendid lisatavasse ritta või veergu genereeritakse juhuarvudega
  • Kõik read / veerud, mis paiknevad soovitud asukoha järel nihkuvad ühe võrra kaugemale. Maatriksi suurus suureneb.
  • Lisa vajalik funktsionaalsus menüüsse.

Lisaülesanne 3: transponeerimine

Lisame täiendava funktsionaalsuse olemasolevasse programmi

  • Kasutaja saab maatriksit transponeerida
  • Lisa vajalik funktsionaalsus menüüsse.

Pärast seda tundi peaksid

  • Oskama luua lõputult kestvaid menüü-programme
  • Teadma täiendavaid käske teksti väljastamiseks

Täiendav materjal