750 likes | 912 Views
Ehto- ja toistolausekkeet. Ehto- ja toistolausekkeet. Seuraavaksi tutkimme ohjelmointilausekkeita / rakenteita, jotka mahdollistavat meille: Päätösten tekemisen ohjelman suorituksen aikana (esim. kyllä/ei päätös) Toistaa käskyjä silmukassa (loopissa) Kappale 4 keskittyy seuraaviin:
E N D
Ehto- ja toistolausekkeet • Seuraavaksi tutkimme ohjelmointilausekkeita / rakenteita, jotka mahdollistavat meille: • Päätösten tekemisen ohjelman suorituksen aikana (esim. kyllä/ei päätös) • Toistaa käskyjä silmukassa (loopissa) • Kappale 4 keskittyy seuraaviin: • boolean ilmaisut • ehtolauseet • tiedon vertailu • toistolauseet • iteraattorit
Missä ollaan? if lauseet ja ehdot Muut ehtolausekkeet Tiedon vertailu while lause Iteraattorit Muut toistolauseet
Kontrollivirta • Jos ei muuta määritetä lauseiden suoritusjärjestys metodin sisällä on lineaarinen (ylhäältä alas): lauseke toisensa jälkeen • Tietyt ohjelmointilausekkeet mahdollistavat meille: • Päättää, jos tietty lauseke suoritetaan vai ei • Suorittaa lause uudelleen ja uudelleen, toistuvasti • Nämä päätökset perustuvat boolean lausekkeisiin (tai ehtoihin) jotka evaluoituvat true tai false arvoihin • Lauseiden suoritusjärjestystä kutsutaan kontrollivirraksi (flow of control)
Ehtolausekkeet • Ehtolause mahdollistaa meille valinnanmahdollisuuden koskien sitä, mikä käsky suoritetaan seuraavaksi • Ehtolauseita kutsutaan välillä valintalauseiksi (selection statements) • Ehtolauseet antavat meille voiman tehdä perutavaalaatua olevia päätöksiä • Javan ehtolauseet ovat: • if lause • if-else lause • switch lause
ehto pitää olla boolean lause. Sen pitää evaluoitua joko todeksi tai epätodeksi. if on Javan varattu sana Jos ehto on tosi, käsky suoritetaan. Jos se on epätosi, käskyn yli hypätään. if lause • if lauseella on seuraava syntaksi: if ( ehto ) käsky;
ehdon evaluointi true false käsky if-lauseen logiikka
Boolean lauseet • Ehtolauseet käyttävät usein Javan yhtäsuurus tai vertailuoperaattoreita, jotka kaikki palauttavat boolean arvoja: == yhtäsuurikuin (matematiikan =) != erisuurikuin < pienempikuin > suurempikuin <= pienempi- tai yhtäsuurikuin >= suurempi- tai yhtäsuurikuin • Huomaa ero yhtäsuuruusoperaattorin (==) ja sijoitusoperaattorin välillä (=)
if lause • Esimerkki if lauseesta: if (sum > MAX) delta = sum - MAX; System.out.println (“Summa on " + sum); • Ensin ehto evaluoidaan - sum-muuttuja on jokosuurempi kuin MAX-muutujan tai ei ole • Jos ehto on tosi, sijoitusoperaatio suoritetaan – jos näin ei ole, sijoitusoperaatio ohitetaan • Oli tilanne kumpi tahansa, kutsu println metodin suorittamiseksi ajetaan seuraavaksi
Sisentäminen (tab->space) • Lause(et), jota if-lause kontrolloin sisennetään ilmentämään tätä suhdetta • Konsistentti sisentämistyyli tekee ohjelmasta helpomman lukea ja ymmärtää • Vaikka asialla ei ole väliä kääntäjälle, oikeas sisentäminen on äärettömän tärkeää "Always code as if the person who ends up maintaining your code will be a violent psychopath who knows where you live." -- Martin Golding
if lause • Mitä seuraavat lauseet tekevät? if (top >= MAXIMUM) top = 0; Asettaa top muuttujaan nollaksi jos tämänhetkinen arvo top muuttujassa on suurempi tai yhtäsuurikuin MAXIMUM if (total != stock + warehouse) inventoryError = true; Asettaa error-lipun todeksi, jos total muuttujan arvo ei ole sama kuin stock ja warehouse muuttujien summa • Aritmeettisen operaattorin presedenssi on suurempi kuin yhtäsuuruus- ja vertailuoperaattoreiden
Loogiset operaattorit • Boolean lauseet voivat käyttää myös seuraavia loogisia operaattoreita: !Looginen EI (NOT) &&Looginen JA (AND) ||Looginen TAI (OR) • Nämä kaikki ottavat vastaan boolean operandeja ja palauttavat boolean tuloksia • Looginen EI on unaarinen operaattori (se toimii yhden operandin kanssa) • Loogiset JA ja looginen TAI ovat binaarisiä operaattoreita (toimivat kahden operaattorin kanssa)
Looginen NOT • loogista NOT operaatiota kutsutaan myös loogiseksi negaatioksi tai loogiseksi komplementiksi (vrt. komplementtikulma) • Jos joku boolean ehto a on tosi, silloin !a on epätosi; jos a on epätosi, silloin!a on tosi • Loogiset ilmaisut voidaan esittää totuusarvotaulukon avulla
Looginen AND ja looginen OR • Looginen AND (JA) ilmaisu a && b on tosi, jos sekä a että b ovat tosia, epätosi muuten • Looginen OR (TAI) ilmaisu a || b on tosi, jos a tai b tai molemmat ovat tosia, epätosi muuten (eli silloin kun a ja b ovat molemmat epätosia)
Loogiset operaattorit • Ilmaisut, jotka käyttävät loogisia operaattoreita voivat muodostaa monimutkaisia lausekkeita if (total < MAX+5 && !found) System.out.println ("Processing…"); • Kaikilla loogisilla operaattoreilla on alheisempi presedenssi kuin vertailuoperaattoreilla • Loogisella NOT:lla on korkeampi presedenssi kuin loogisella AND:lla ja loogisella OR:lla
Loogiset operaattorit • Totuusarvotaulukko näyttää kaikki mahdolliset tosi-epätositilanteet esim. kahden operandin tilanteessa • Koska && ja ||:lla kummallakin on kaksi operandia, on olemassa neljä mahdollista kombinaatiota kullakin ehdolla a ja b
Boolean lauseet • Minkä tahansa monimutkaisemmankin lauseen voi evaluoida totuusarvotaulukon avulla (opiskelija menee helposti sekaisin, jos tarkistamista ei suoriteta totuusarvotaulukon avulla)
Laiska evaluointi (short cirquit, lazy,…) • Loogisen AND:n ja loogisen OR:n prosessointi on ns. “laiskaa” • Jos vasen operaattori on tarpeeksi tuloksen määrittämiseen (lähinnä || tilanne, miten?), oikeaa operandia ei huomioida enää mitenkään (ollenkaan) if (count != 0 && total/count > MAX) System.out.println ("Testing…"); • Monimutkaisemmissa lauseissa voi helposti tulla ongelmia, && ja || menevät opiskelijalla helposti sekaisin (“tuli laitettua jostain syystä ||, kun piti olla && tai toisinpäin…”). Käytä monimutkaisia lauseita, jotka ovat short cirquit tyyppisiä varovasti.
Missä ollaan? if lauseet ja ehdot Muut ehtolausekkeet Tiedon vertailu while lause Iteraattorit Muut toistolauseet
if-else lause • else lause voidaan lisätä if lauseeseen, kun halutaan tehdä if-else lause (hyvä ohjelmointitapa, vs. “tyhmät” ohjelmanne käyttäjät) if ( ehto ) lause1; else lause2; • Jos ehto on tosi (true), lause1 suoritetaan; jos ehto on epätosi, lause2 suoritetaan • Ensimmäinen tai toinen suoritetaan, mutta ei molempia
ehto evaluoidaan true false lause1 lause2 if-else lauseen logiikka
Coin luokka • Seuraavaksi tutkimme luokkaa, joka esittää kolikkoa (joka voidaan heittää) -> kruuna vai laava • Instanssitietoa (attribuutteja) käytetään ilmoittamaan kumpi kolikon puoli (kruuna tai laava) on sillähetkellä näkyvissä
Lisää sisennyksestä • Huomaa, että sisennykset ovat ihmistä varten: tietokone ignoroi kaikki sisennyksesi ja voit saada ongelmia {}-sulkeiden puuttumisen vuoksi: if (total > MAX) System.out.println ("Error!!"); errorCount++; Huolimatta siitä, miten sisennyksien perusteella koodin olisi haluttu toimiva, inkrementointi tapahtuu jokatapauksessa: oli ehto sitten tosi tai epätosi
Lauseblokit • Useita ohjelmarivejä voidaan yhdistää kirjoittamalla lauseblokkeja, jonka alkuun laitetaan avaava ja loppuun sulkeva aaltosulku • Lauseblokkia voidaan käyttää missätahansa on ohjelmarivejä (lauseblokki voi olla tyhjäkin, mutta siinä ei ole paljonkaan järkeä) if (total > MAX) { System.out.println("Error!!"); errorCount++; }
Lauseblokit • if-else rakenne, if osuus, else osuus, tai molemmat, voivat aloittaa lauseblokin if (total > MAX) { System.out.println("Error!!"); errorCount++; } else { System.out.println("Total: " + total); current = total*2; }
Ehto-operaattori • Javassa on ehto-operaattori, joka käyttää boolean ehtoa päättääkseen kumpi kahdesta mahdollisesta lauseesta evaluoidaan • Ehto-operaattorin syntaksi on: ehto ? lause1 : lause2 • Jos ehto on tosi, lause1 evaluoidaan; jos se on epätösi, lause2 evaluoidaan • Koko ehto-operaattorin arvo on sama kuin valitun lauseen loppuarvo
Ehto-operaattori • Ehto-operaattori on sama kuin if-else lause, paitsi että se on operaatio, joka palauttaa arvon • Esimerkiksi: larger = ((num1 > num2) ? num1 : num2); • Jos num1 on suurempikuin num2, silloin num1 sijoitetaan larger muuttujaan; muussatapauksessa, num2 sijoitetaan larger muuttujaan • Ehto-operaattori on tertiaarinen, koska se vaatii kolme operandia (vertaa unaarinen, binaarinen)
Ehto-operaattori • Toinen esimerkki: System.out.println (“Vaihtorahasi on " + count + ((count == 1) ? “Euro" : “Euroa")); • Jos count on 1, silloin “Euro" tulostetaan • Jos count on mitätahansa muuta kuin 1, silloin “Euroa” tulostetaan (monikkomuoto)
Sisäkkäiset if-lauseet • Lause, joka suoritetaan if- tai else-lauseen seurauksena voi olla toinen if-lause • Näitä kutsutaan sisäkkäisiksi if-lauseiksi • else lause saa parikseen viimeisen ei-mätsätyn if:n (sisennyksillä ei ole väliä. Kokeile textpadin ctrl-n toimiston aaltosulun vastaparin löytämiseksi) • Aaltosulkuja voidaan käyttää määrittämään minkä if-lauseen parina else-lause toimii
switch lause • switch lause mahdollistaa toisen tavan päättää mikä lause suoritetaan seuraavaksi • switch lause evaluoi ehtolauseen, sitten yrittää mätsätä tulosta yhteen erityisistä caseista • Jokaisella casella on arvo ja lista lauseita, jotka ko. tapauksessa suoritetaan • Kontrolli hyppää ko. lauseen suorituksessa sille riville missä ensimmäisenä mätsää ko. casen arvo ja vertailumuuttujan arvo
switch ja case ovat varattuja sanoja Jos ehto mätsää arvonarvo2, kontrolli hyppääsinne The switch Statement • Yleinen switch lauseen syntaksi on: switch ( ehto ) { case arvo1: lause-lista1 case arvo2: lause-lista2 case arvo3 : lause-lista3 case... }
switch lause • Usein break lausetta (lue: lähes aina) käytetään casen lauserivin viimeisenä rivinä • break lauseesta seuraa kontrollin siirtyminen switch lauserakenteen loppuun • Jos break lausetta ei käytetä, kontrolli siirtyy vain järjestyksessä seuraavaan caseen switch-case rakenteessa • Joskus tämä voi olla haluttua, mutta usein haluamme suorittaa vain tiettyyn caseen kuuluvat lauseet
switch lause • Esimerkki switch lauseesta: switch (option) { case 'A': aCount++; break; case 'B': bCount++; break; case 'C': cCount++; break; }
switch lause • switch lauseella voi olla optionaalinen defauls case (vertaa if-silmukan else-osaan…) • Default casella ei ole siihen liittyvää arvoa (pivot) ja default case tehdään yksinkertaisesti varatulla sanalla default • Jos default case on tehty, kontrolli siisrtyy siihen mikäli mikään muu case tapaus ei mätsää muuttujan arvoa • Jos default casea ei ole, ja mikään arvo ei sovi, kontrolli putoaalauseen läpi switchin jälkeen
switch lause • Ehdon vasemman operandin switch lauseessa täytyy olla kokonaislukutyyppiä, siis byte, short, int,long tai char (!) • Se ei voi olla boolean arvo tai desimaaliluku (float tai double) • Implisiittinen boolean ehto switch-lauseessa on yhtäsuuruus (==). Muut boolean operaattorit eivät ole mahdollisia • Et voi suorittaa kahden operandin vertailutestejä switch lauseessa
Missä ollaan? if lauseet ja ehdot Muut ehtolausekkeet Tiedon vertailu while lause Iteraattorit Muut toistolauseet Päätökset ja grafiikka Lisää komponentteja
Tiedon vertailu • Kun tietoa vertaillaan käyttäen boolean ilmaisujam on tärkeää ymmärtää muutamia tietotyyppien nyansseja • Tarkastelemme muutamia avaintilanteita • Desimaalilukujen vertailu samansuuruisuutta etsittäessä • Merkkien vertailu • Stringien vertailu (aakkosellinen järjestys) • Olion vertaaminen olion viittaustyyppiin
Desimaalilukujen vertailu • Sinun kannattaa harvoin käyttää yhtäsuuruusoperaattoria (==) kun vertailet kahta desimaalilukua (tyyppiä float tai double) • Kaksi desimaalilukua ovat samat vain jos niiden alapuolella olevat binääriesitykset mätsäävät • Laskutoimituksessa tulee usein pieniä laskuvirheitä (luokkaa 0.00000000000001), jotka voivat olla irrelevantteja • Monissa tilantessa voit pitää kahta desimaalilukua “tarpeeksi yhtäsuurina”, vaikka ne eivät olisikaan täsmällään samanarvoisia
Desimaalilukujen vertailu • Kahden desimaaliluvun yhtäsuurudeen selvittämiseksi, voit haluta käyttää seuraavaa tekniikkaa: if (Math.abs(f1 - f2) < TOLERANCE) System.out.println ("Essentially equal"); • Jos kahden desimaaliluvun välinen ero on vähemmän kuin toleranssi, näitä kahta desimaalilukua pidetään yhtäsuurina • Toleranssi voidaan asettaa mihintahansa sopivaan arvoon – esimerkiksi 000001
Merkkien vertailu (chars) • Kuten olemme todenneet, Javan merkistö pohjautuu Unicode merkistöön • Unicode asettaa tietyn numeerisen arvon kyllekin merkille, ja täten merkkien järjestyksen (case-sensitive) • Me voimme käyttää vertailuoperaattoreita charreille tämän suuruusjärjestyksen mukaan (esim. Aakkostaminen) • Esimerkiksi, merkki '+' on vähemmän kuin Unicode-merkki 'J' koska sen arvon on Unicode merkkitaulukossa ennen J:tä • Kirjan liite C tarjoaa yleiskatauksen Unicodesta
Merkkien vertailu (char) • Unicodessa numeromerkit (0-9) ovat vierekkäin ja järjestyksessä • Samallatavalla, isot kirjaimet (A-Z) ja pienet kirjaimet (a—z) ovat vierekkäin ja järjestyksessä (siis myöskin aakkosten mukaan)
Merkkijonojen vertailu • Muista että Javan merkkijono (String) on olio • equals metodia voisaan kutsua String-oliolle, jotta voidaan tarkistaa sisältäväktö kummatkin Stringit samat kirjaimet täsmällään samassa järjestyksessä • equals metodi palauttaa boolean arvon if (name1.equals(name2)) System.out.println ("Same name");
Merkkijonojen vertailu • Me emme voi käyttää tavallisia vertailuoperaattoreita (==, >, <, yms.) verrataaksemme Stringejä • String luokka sisältää metodin nimeltään compareTo sen päättämiseen tuleeko jokin stringi ennen jotain toista stringiä (aakkosissa) • Kutsu name1.compareTo(name2) metodille • Palauttaa nolla, jos name1 ja name2 ovat identtiset ( sisältävät samat merkit) • Palauttaa negatiivisen arvon, jos if name1 on pienempikuin name2 • Palauttaa positiivisen arvon, jos name1 on suurempi kuin name2
Merkkijonojen vertailu if (name1.compareTo(name2) < 0) System.out.println (name1 + "comes first"); else if (name1.compareTo(name2) == 0) System.out.println ("Same name"); else System.out.println (name2 + "comes first"); • Koska merkkijonojen ja Stringien vertailuy perustuu merkistöön (esim. ASCII-8bit), sitä kutsutaan leksikograagiseksi järjestämiseksi
Leksikograaginen järjestäminen • Leksigograafinen järjestäminen ei ole tiukasta aakkosjärjestyksen mukainen niissä tapauksissa kun isoja kirjaimia ja ja pieniä kirjaimia sekotetaan keskenään • Esimerkiksi, String "Great" tulee ennen merkkijonoa "fantastic" sillä kaikki isot kirjaimet tulevat ennen pieniä kirjaimia (koskien kaikkia kirjaimia unicodessa) • Lisäksi, lyhyet stringit tulevat ennen pidempiä stringejä (jos esim. Samat prexit) (leksikograafisesti) • Siksi "book" tulee ennen "bookcase“ nimistä muuttujan sisältöä
Olioiden vertailu • == operaattoria voidaan käyttää primitiivityyppisille muuttujille – ko. operaatio palauttaa true, mikäli kaksi referenssiä (operandit) ovat toistensa aliakset • equals metodi on määritelty kaikille olioille, mutta jollemme uudelleenmääritä (override) sitä kun kirjoitamme luokan, sillä on sama semantiikka kuin == operaattorilla (ei sentään sama syntaksi…) • Equals-metodi on uudelleenmääritelty esimerkiksi String luokassa: operandistringien merkkejä (chars) on vertailtava kokonaisuutena • Kun kirjoitat luokkaa, voit uudelleenmäärittää equals –metodin palauttamaan true aivan missä tilanteessa haluat (mikä sopii ohjelman logiikkaan)
Missä ollaan? if lauseet ja ehdot Muut ehtolausekkeet Tiedon vertailu while lause Iteraattorit Muut toistolauseet Päätökset ja grafiikka Lisää komponentteja
Toistolauseet • Toistolauseet mahdollistavat meille lauseen suorittamisen useita kertoja (0,*) • Niistä puhutaan usein nimellä looppi tai silmukka • Kiten ehtolauseita, näitäkin lauseita kontrolloidaan boolean ilmaisuiden avulla • Javassa on kolmenlaisia toistolausekkeita: • while silmukka • do silmukka • for silmukka • Ohjelmoijan pitäisi valita ko. tilanteeseen parhaiten sopiva silmukka
while lause • while lauseella on seuraava syntaksi: while ( ehto ) lauseet; • Jos ehto on tosi (true), lauseet suoritetaan • Ehdo evaluoidaan uudestaan, ja jos ehto on edelleen tosi, lauseet suoritetaan taas • Lauseita suoritetaan toistuvat niin kauan kunnes ehdosta tulee epätosi (false)
ehdon evaluointi true false lauseet while lauseen logiikka