Ilkka Koivistoinen 13.02.2002

Edellinen

Seuraava

6. 3 Toistorakenteet
(Katso myös http://java.sun.com/docs/books/tutorial/java/nutsandbolts/while.html)

6.3.1 Yleistä

Toistorakenteella tarkoitetaan koodin osaa joka suoritetaan halutun monta kertaa eli kierrosta. Toistokertojen lukumäärää ilmoittaa usein integer muuttuja, jolle annetaan nimi "silmukkamuuttuja". Ensimmäisellä kierroksella silmukkamuuttujan arvo on 1, toisella 2 jne. Jokaisella kierroksella silmukkamuuttujan arvo kasvaa yhdellä. On myös mahdollista tehdä yleisempi silmukkamuuttuja, jossa silmukkamuuttuja saa arvot min .. max ja lisäys kullakin kierroksella on istep. Huomaa, että istep voi olla myös negatiivinen. Lisäksi silmukan lopetus voidaan toteuttaa ehdolla joka ei laisinkaan liity indeksimuuttujaan tai hypätä break –lauseella silmukkaa seuraavaan lauseeseen.

Päättymättömään silmukkaan joudutaan, mikäli toistojen lukumäärän asettava indeksimuuttuja käsitellään väärin toistolauseessa. Tämä näkyy ohjelman jumiutumisena ja windows –ikkuna joudutaan sulkemaan kesken kaiken esimerkiksi rastista tai tehtävänhallinnasta. Jos käy niin, että ohjelma kaappaa päättymättömän silmukan suorituksessa kaiken prosessoriajan (ts. ohjelma pyörii korkealla prioriteetilla ja windows ei ehdi reagoida edes hiiren liikkeisiin) . Tällöin voi yrittää lopettaa ohjelmaa tehtäväpalkin tehtävien hallinnasta tai mikäli sekään ei onnistu on kone äärimmäisessä tapauksessa käynnistettävä resetistä uudestaan. Tällöin on syytä toivoa, että NT suostuu käynnistymään uudestaan. Muista, että windows NT:tä ei pitäisi laittaa lennosta kiinni. NT käyttöjärjestelmän pitäisi osata käsitellä prosesseja siten, ettei resetin painamiseen jouduta.

6.3.2 Alkuehtoinen toisto - while

Ennalta määrättömän monta toistoa saadaan toteutettua while –lauseeella. Siinä yhtä lausetta (tai koottua lausetta) toistetaan niin kauan, kun toistoehto on tosi. Kun toistoehto saa arvon epätosi, hypätään toistolausetta seuraavaan lauseeseen.

  Syntaksi: 
  
    while (ehto)
        lause;

Ehto on samanlainen boolean -lause, mitä if – else –rakenteen yhteydessä opittiin. Lause voi olla yksi lause tai koottu lause (lausesulut { .. } ). Mikäli toistoehto ei ole voimassa while lauseeseen tultaessa, lausetta ei toteuteta kertaakaan. Ehdossa olevan indeksimuuttujan arvoa pitää muuttaa toistolauseessa, jotta toisto ei jatku loputtomiin.

Esimerkki 16.

    /*Tässä esimerkissä ei ole indeksimuuttujaa, vaan while lauseen
    toistomäärä rajoitetaan muuttujalla m. Huomaa, että m pitää
    kertalleen lukea ennen toistolauseeseen menoa, i on vain esimerkin vuoksi
    */
    import Lue;
    public class e16
    {
       public static void main(String args[])
       {
         String m="";  // jotta päästään silmukkaan voisi olla myös vaikkapa = "a";
         int i = 1; // Indeksimuuttuja on alustettava
         while (!m.equals("l"))
         { // muista että while toistaa vain yhden lauseen. Siksi koottu lause
             System.out.println("Toiston "+i+ ". kierros");
             System.out.println("Anna merkki. (l lopettaa)");
             m = Lue.rivi();
             i++; // tämä on sama kuin i = i+1 mutta nopeampi
         }
       }
    }

Esimerkki 17.

    /* Tässä esimerkissä indeksimuuttuja i lopettaa toiston. Toisto lopetetaan, kun
    indeksimuuttuja saa arvon 100*/;
    import Lue;
    public class e17
    {
       public static void main(String args[])
       {
         int i = 1; // Indeksimuuttuja on alustettava
         while (i<100)   // kokeile myös <=100
         { // muista että while toistaa vain yhden lauseen. Siksi koottu lause
             System.out.println(i+" Mukavaa toistaa saamaa asiaa");
             i=i+1; //tämä on sama kuin i++, mutta hitaampi
         }
       }
    }

Esimerkki 18.

import java.util.*; // satunnaislukuja varten
import Lue;
public class e18 // MaarittelemattomanMontaToistoa
{
  public static void main(String args[])
   {
     //Tässä esimerkissä toistokertojen määrää ei etukäteen tiedä *)
     Random satunnaisluku = new Random(); // Tyyppiä random oleva satunnaisluku
     // Koska (), satunnaisgeneraatorin siemenluku otetaan kellonajasta
     int luku, sluku = (int) (satunnaisluku.nextDouble() *10); // satunnainen kokonaisluku
     // välilllä [0 – 10]
     // System.out.println(sluku);
     System.out.println("Arvaa luku väliltä 0 - 10");
     luku = Lue.kluku();
     while (luku!=sluku)
     { // muista että while toistaa vain yhden lauseen. Siksi koottu lause
        System.out.println("Ei osunut, arvaa uudelleen ");
        luku=Lue.kluku();
     }
     System.out.println("Onneksi olkoon. Kysytty luku oli todella "+ sluku);
   }
}

 

 

Esimerkki 18 on kirjoitettu esimerkkiin 18a hieman toisin

import java.util.Random;
import Lue;

// joka kierroksella arvotaan uusi luku. Käyttäjä korvataan toisella satunnaisluvulla, joka arvotaan myös joka
// kierroksella

public class e18a {
  public static void main(String args[]){
    Random satunnaisluku = new Random();
    int sluku = 1; // alustetaan muuttujat siten, että päästään silmukkaan
    int luku = sluku + 1;
    int kierros = 0;
    while (luku != sluku) {
      kierros++;
      sluku = (int) ( satunnaisluku.nextDouble()*10 );
      luku = (int) ( satunnaisluku.nextDouble()*10 );
      System.out.println("Kierros "+kierros+ ". Arvattava luku ja ehdotettu luku ovat "+sluku+" "+luku);
    }
    System.out.println("Loppu");
  }
}

 

6.3.2.1 Tehtäviä.

  1. Tee ohjelma, joka kysyy Suomen pääkaupunkia kunnes vastaukseksi annetaan Helsinki. Tämän jälkeen ohjelma onnittelee oikeasta vastauksesta. (Miten hoidat isojen ja pienten kirjainten erot?)
  2. Korjaa edellistä ohjelmaa siten, että ohjelma antaa arvata vain viisi kertaa, jonka jälkeen vastaajaa pyydetään menemään takaisin maantiedon tunnille.
  3. Tee ohjelma, joka laskee 5:n näppäimistöltä luetun luvun summan. Ennen kuin aloitat, lue seuraava tehtävä.
  4. Tee ohjelma, joka laskee k:n näppäimistöltä luetun luvun summan, kun k kysytään ensin käyttäjältä. Käytä indeksimuuttujan lisäksi vain kahta muuttujaa summa ja luettava luku (Vihje: summa = summa+luku;).
  5. *)  Tee ohjelma, joka arpoo 100 000 satunnaislukua väliltä -10 - 10 ja laskee näiden summan. (Syntyykö vaaraa ylivuodosta?).
  6. Tee ohjelma, joka laskee k:n näppäimistöltä luetun luvun keskiarvon, kun k kysytään ensin käyttäjältä. Käytä indeksimuuttujan lisäksi vain kolmea muuttujaa.
  7. * Tee ohjelma, joka laskee luvun n kertoman. (1*2*3*4*…*n). Saitko aikaan ylivuodon? Kokeile.
  8. * Tee ohjelma joka piirtää *:stä 5 kertaa viiden tähden neliön.
  9. * Korjaa edellistä ohjelmaa siten, että ohjelma kysyy tähtien määrän. Yli 50:n tähden tapauksessa käyttäjää pyydetään miettimään tilannetta vielä kerran eikä piirtämistä aloiteta.
  10. * Tee ohjelma, joka piirtää tähdillä kolmion. Käyttäjältä pyydetään kolmiossa olevien rivien määrä. (Ohje: Tee kaksi sisäkkäistä while –silmukkaa)
  11. * Yritä selvittää Javan suurin mahdollinen int luku (maxint) (Vihje: Lisää Int –muuttujan arvoa yhdellä, kunnes luku vaihtaa ylivuodon takia merkkiään).

Vastaukset

Ilkka Koivistoinen 13.02.2002

Edellinen

Seuraava