Demo 5

Demoryhmä Päivä Aika Sali
Ryhmä 1 ma 10.6. 14.15 - 16.00 Ag B111.1
Ryhmä 2 ma 10.6. 18.15 - 20.00 Ag B112.1

HUOM 1:Tehtävissä esiintyy vielä tuntemattomia C++-kielen rakenteita, mutta älä anna sen häiritä!

  1. Suorita aloitustoimenpiteet
    1. Kirjoittaudu sisään mikroon.
    2. Tee kiintolevylle C oma hakemistosi alihakemiston C:\MyTemp alle.
    3. Kopioi edellisissä demoissa 4 tehdyt C++ ohjelmatiedostot omaan hakemistoosi.
    4. Vaihda oma hakemistosi WinCD-ohjelmalla nykyhakemistoksi.

  2. Käynnistä Borland C++ 3.1.

    Avaa edellisissä demoissa tehty tiedosto SUMMAA.CPP. Editointi-ikkunassa pitäisi olla seuraavaa.

    /*
      SUMMAA.CPP  Ohjelma lukee kokonaislukuja, laskee niiden summan
                  ja tulostaa sen.
    */
    #include <iostream.h>
    int main(void)
    {
      int luku = 0, summa = 0;
      do {
        summa = summa + luku;
        cout << "Anna kokonaisluku (0 lopettaa syötön) > ";
        cin >> luku;
      } while (luku != 0);
      cout << "Luettujen lukujen summa = " << summa << endl;
      return 0;
    }
    
  3. Avaa tarvittaessa tulostusikkuna ja tarkista, että ohjelma toimii.
    Muutetaan jatkossa tämä ohjelma seuraavaksi sellaiseksi, että se laskee luettujen lukujen summan ja keskiarvon ja myös tulostaa nämä arvot.


  4. Ensimmäisessä vaiheessa muokataan ohjelma sellaiseksi, että syötön lopettava luku luetaan ennen varsinaisten lukujen syötön aloittamista.(Täten nollasta tulee tarvittaessa sallittu luku.)

    Talleta ensin tämä tiedosto nimellä LSUMMAA.CPP.
    Korjaa kommentti.
    Lisää seuraava muuttujan määrittelyrivi ohjelmassa jo olevan muuttujan määrittelyrivin alle.

      int lopetusluku;    // syötön lopettava luku
    
    Kopioi rivit
      cout << "Anna kokonaisluku (0 lopettaa syötön) > ";
      cin >> luku;
    
    leiketaulun kautta do-sanalla alkavan rivin yläpuolelle: siis merkitse rivit, suorita näppäinkomento Ctrl+Insert, vie kursori do-rivin vasempaan reunaan ja suorita näppäinkomento Shift+Insert.
    Aseta näiden rivien tekstit alkamaan samasta sarakkeesta kuin do.

    Muuta tämän juuri kopioidun cout-alkuisen lauseen lainausmerkeissä oleva merkkijono muotoon

    "Anna syötön lopettava kokonaisluku > "
    
    ja muuta myös kopioidussa cin-alkuisessa lauseessa tunnus luku muotoon lopetusluku.

    Muuta rivi

      cout << "Anna kokonaisluku (0 lopettaa syötön) > ";
    
    muotoon
      cout << "Anna kokonaisluku (" << lopetusluku << " 
    lopettaa syötön) > ";
    
    Korjaa vielä lopetustesti while-rivillä muotoon
      } while (luku != lopetusluku);
    
    Talleta ohjelma ja testaa sitä.


  5. Lisätään seuraavaksi ohjelmaan luettujen lukujen lukumäärän ja keskiarvon laskeminen.

    Talleta ohjelmasi aluksi nimellä KESKIA.CPP.

    Korjaa kommentti.
    Lisää seuraava muuttujan määrittelyrivi ohjelmassa jo olevien muuttujan määrittelyrivien jälkeen.

      int lkm;    // luettujen lukujen lukumäärä
    
    Lisää alkuun cout-rivi, joka tulostaa mitä ohjelma tekee.

    Lisää rivin summa = summa + luku; alle uusi rivi,jossa kasvatetaan lukumäärää yhdellä eli

        lkm++;
    
    Kopioi ennen return-lausetta oleva tulostusrivi (cout alkava) leiketaululle ja liimaa se sieltä uudeksi riviksi juuri kopioidun rivin alle. Muuta kopioitu lause vielä muotoon
    cout << "Luettujen lukujen keskiarvo = " << summa/lkm << 
    endl;
    
    Talleta ohjelma ja käännä se. Jos tulee vain yksi varoitus niin jatka kohdasta 6.


  6. Tarkastellaan muuttujan lkm arvoa debuggerin eli virheenjäljittimen avulla. Valitse ensin Debug (Alt+d), sitten Watches ja lopulta Add Watch tai suoraan näppäinkomennolla Ctrl+F7. Kirjoita avautuneeseen ikkunaan lkm ja valitse OK.

    Suoritetaan sen jälkeen ohjelmaa rivi kerrallaan: Aseta editointi-ikkuna aktiiviseksi ja valitse sitten Run (Alt+r) ja Step over tai suoraan F8.
    Editointi-ikkunassa näkyy palkki aina seuraavaksi suoritettavan rivin kohdalla. Jatka suoritusta rivi kerrallaan painamalla F8. Syötöt annetaan normaaliin tapaan. Seuraamalla muuttujan lkm arvoa voi heti alkuvaiheessa havaita, että muuttujan alustus nollaksi on unohtunut.

    Keskeytä ohjelman suoritus; valitse Run (Alt+r) ja Program reset tai näppäinkomento Ctrl+F2.
    Sulje Watch-ikkuna.

    Korjaa virhe alustamalla muuttuja lkm määrittelyn yhteydessä arvoon 0.
    Talleta ohjelma ja testaa sitä uudestaan. Kun havaitset suoritusaikaisia virheitä niin jatka kohdasta 6.

  7. Avaa uudestaan Watch-ikkuna ja laita sinne tarpeen mukaan yksi kerrallaan muuttujat luku, summa ja lkm.
    Laita kursori riville summa = summa + luku;.
    Pysäytetään ohjelman suoritus tälle riville; valitse valikosta Run (Alt+r) ja Go to cursor tai suoraan F4.
    Jatka muutama rivi eteenpäin (F8) ja tarkkaile muuttujien arvoja. Voidaan havaita, että muuttujan lkm arvoa kasvatetaan yhdellä, vaikka summaan ei ensimmäisellä kierroksella vielä lisätä mitään luettua lukua. Tässä on tyypillinen virhe, joka näyttäisi laskevan yhden liian paljon.
    Keskeytä ohjelman suoritus ja sulje Watch-ikkuna.


  8. Lisää rivin cin >> luku; alle uusi rivi, joka on muotoa
    if (luku != lopetusluku)
    
    Tämän jälkeen siirry riville lkm++;. Leikkaa koko rivi leiketaululle ja liimaa se leiketaululta juuri kirjoitetun if-alkuisen rivin alle uudeksi riviksi.

    Talleta ohjelma ja testaa sitä.
    Kokeile antamalla lopetusluvuksi 1 ja anna syöttönä kaksi lukua 4 ja 5 ja sitten lopetusluku.
    Voidaan havaita, että keskiarvon laskeminen ei onnistu vieläkään?

    Suoritetaan nyt virheenjäljitys seuraavasti:
    laita kursori riville cout << "Luettujen lukujen summa jne.
    Laitetaan tälle riville keskeytyskohta; valitse Debug (Alt+d) ja sitten Toggle breakpoint tai suoraan näppäinkomennolla Ctrl+F8. Keskeytyskohtaa kuvaava palkki tulee näkyviin.
    Tämän jälkeen suorita ohjelma eli Ctrl+F9 ja käytä samoja syöttötietoja kuin juuri edellä.
    Suoritus pysähtyy keskeytyskohtaan. Katso muuttujien summa ja lkm arvoja esimerkiksi avaamalla Watch-ikkuna. Niiden tulisi olla aivan oikein eli virhe tulee keskiarvon laskennassa tai tulostuksessa. Syynä onkin kokonaislukujakolaskussa tapahtuva katkaisu kokonaisluvuksi.

    Keskeytä ohjelman suoritus, sulje Watch-ikkuna ja poista keskeytyskohta-asetus.
    Korjaa ohjelma muuttamalla muuttujan summa tyypiksi double.
    Muuta lisäksi muuttujan luku nimeksi luettu_luku Search (Alt+s) and Replace komennolla: katso huolellisesti kaikki valinnat ja tee toiminto alarivin valinnalla Change All ja vahvista kaikki korvaukset erikseen.

    Talleta ohjelma ja testaa sitä. Kokeile myös siten, että et anna yhtään lukua.
    Korjaa vielä tämä nollalla jako tapaus pois seuraavanlaisella silmukkaa seuraavalla tulostusrakenteella:

    if (lkm == 0)
      cout << "Et antanut yhtään lukua." << endl;
    else {
      cout << "Luettujen lukujen summa = " << summa << endl;
      cout << "Luettujen lukujen keskiarvo = " << summa/lkm 
    << endl;
    }
    

    Talleta ohjelma ja testaa sitä.

    Malliratkaisu:
    
    /*
      KESKIA.CPP Kysyy ja laskee lukujen summan ja keskiarvon.
    */
    
    #include <iostream.h>
    
    int main (void)
    {
     int luettu_luku = 0;
     double summa = 0.0;
     int lopetusluku;
     int lkm = 0;
     cout << "Ohjelma laskee antamiesi lukujen summan ja keskiarvon." << endl;
     cout << "Anna syötön lopettava kokonaisluku >";
     cin >> lopetusluku;
     do {
       summa = summa + luettu_luku;
       cout << "Anna kokonaisluku (" << lopetusluku << " lopettaa syötön) >";
       cin >> luettu_luku;
       if (luettu_luku != lopetusluku)
         lkm++;
     } while (luettu_luku != lopetusluku);
     if (lkm == 0)
        cout << "Et antanut yhtään lukua." << endl;
     else {
        cout << "Luettujen lukujen summa = " << summa << endl;
        cout << "Luettujen lukujen keskiarvo = " << summa/lkm << endl;
     }
     return 0;
    }
    
    
  9. Tehdään lopuksi vielä ohjelma, joka lukee vuosiluvun ja tulostaa tiedon siitä onko kyseessä karkausvuosi vai ei.

    Tässä voidaan käyttää pohjana edellisissä demoissa tehtyä ohjelmaa LUEJATUL.CPP, joten avaa se vanhan editointi-ikkunan ohjelman tilalle eli valitse avattaessa vaihtoehto Replace.

    Talleta sitten tämä tiedosto nimellä KARKAUSV.CPP.
    Korjaa ohjelman kommentti.
    Muuta muuttujan luku nimeksi vuosi käyttämällä Search and Replace toimintoa.
    Määrittele uusi int-muuttuja karkausvuosi.
    Lisää alkuun ohjelman tarkoituksen tulostava lause.
    Muuta syöttöpyyntö "Anna kokonaisluku > " pyynnöksi "Anna vuosiluku > ".

  10. Käytetään karkausvuoden tutkimisen pohjana seuraavaa algoritmia:

  11. Jos (vuosiluku on jaollinen 400:lla) niin
       on karkausvuosi
    muutoin jos (vuosiluku on jaollinen 100:lla) niin
       ei ole karkausvuosi
    muutoin jos (vuosiluku on jaollinen 4:llä) niin
       on karkausvuosi
    muutoin
      ei ole karkausvuosi.
    

    Kirjoita siis cin-alkuisen rivin jälkeen seuraavat rivit, joilla testataan karkausvuosiominaisuutta:

    if (vuosi%400 == 0)
      karkausvuosi = 1;    // on karkausvuosi
    else if (vuosi%100 == 0)
      karkausvuosi = 0;    // ei ole karkausvuosi
    else if (vuosi%4 == 0)
      karkausvuosi = 1;    // on karkausvuosi
    else
      karkausvuosi = 0;    // ei ole karkausvuosi
    

    Muuta tulostusrivi vielä seuraavien neljän rivin muotoon

    if (karkausvuosi == 1)
      cout << "Vuosi " << vuosi << " on karkausvuosi." 
    << endl;
    else
      cout << "Vuosi " << vuosi << " ei ole karkausvuosi." 
    << endl;
    

    Talleta ohjelma ja testaa sitä.

  12. Muutetaan karkausvuosiohjelmaa vielä siten, että karkausvuoden selvittäminen tehdään omassa funktiossa.

    Korjaa kommentti ja muuta ohjelman alkuosa muotoon

    #include <iostream.h>
    
    /* onkoKarkausvuosi  - funktio, joka tutkii onko vuosi karkausvuosi
    *                    - vuosi, int parametrina tuotu tutkittava vuosi
    *                    - paluuarvo 0, jos vuosi ei ole karkausvuosi
    *                                1, jos vuosi on karkausvuosi.
    */
    int onkoKarkausvuosi(int vuosi)
    {
      int karkausvuosi;
    
      return karkausvuosi;
    }
    
    int main(void)
    

    Leikkaa sitten edellä karkausvuoden selvittämiseksi kirjoitettu 8 rivin if-lause leiketaululle ja liimaa tämä juuri kirjoitetun onkoKarkausvuosi-funktion aaltosulkujen väliin jätetyn tyhjän rivin tilalle.

    Muuta main-funktion if-lauseessa oleva ehto (karkausvuosi == 1) muotoon (onkoKarkausvuosi(vuosi)) .

    Poista main-funktiosta muuttuja karkausvuosi.

    Talleta ohjelmasi ja testaa sitä.

    Halutessasi voit nyt testata virheenjäljittimen (Debugger) näppäimien F7 ja F8 välisiä eroja.

  13. Lopeta Borland C++ .


  14. Suorita lopetustoimenpiteet käyttäen joko DOS-komentoikkunaa tai Windows Exploreria.
    1. Kopioi kaikki haluamasi C++-kieliset ohjelmat levykkeellesi sopivaan alihakemistoon tai Agoranetin tietokoneiden U-asemalle. Siis ei kannata kopioida muita kuin .CPP-tarkentimen omaavat tiedostot.
    2. Tyhjennä omalla nimellä oleva hakemistosi.
    3. Kirjoittaudu ulos: Valitse Start|Log Off käyttäjätunnus.
    4. Älä sulje konetta äläkä näyttöä.
http://appro.mit.jyu.fi/2002/kesa/johdatusohjelmointiin/demot/demo5/index.html
© Juha Kajava () & Miika Nurminen ()
Perustuu osittain Hans Björnin kurssisivustoon ja teksteihin.
Viimeksi päivitetty: 7.05.2002 15:33:45