Olio-ohjelmointi

Tässä harjoituksessa ei vielä opiskella varsinaista olio-ohjelmointia, vaan tarkoituksena on kerrata ohjelmoinnin perusteita, kuten

  • muutujat
  • funktiot ja niiden kutsuminen
  • ehtorakenne
  • try-catch rakenne (uusi asia)

Jos haluat luoda funktioille erillisen header- ja cpp-tiedoston, katso video https://youtu.be/_-9QXP5T64M.

Harjoitus1 (cout, cin, funktio)

Kirjoita C++-sovellus, joka kysyy kaksi kokonaislukua (a ja b) ja tulostaa niiden summan ja osamäärän. Osamäärä tulostetaan kahdella desimaalilla.


OHJEET:

Luo C++-projekti nimeltään h1

Muokkaa main-funktiota seuraavasti:
  • Kysy luvut ja tallenna ne muuttujiin a ja b
  • käytä cin ja cout olioita
Lisää sovellukseen summan ja osamäärän laskemiseen ja tulostamiseen käytettävät funktiot:
  • funktio calcSum ottaa vastaan kaksi kokonaislukua ja tulostaa niiden summan, mutta ei palauta mitään.
  • funktio calcDiv ottaa vastaan kaksi kokonaislukua ja tulostaa niiden osamäärän, mutta ei palauta mitään.
  • jos jakaja on nolla calcDiv tulostaa virheilmoituksen.
  • kutsu em. funktioita mainissa antamalla niille argumenttina muuttujat a ja b.
Lisää sovellukseen toiset summan ja osamäärän laskemiseen ja tulostamiseen käytettävät funktiot:
  • funktio retSum ottaa vastaan kaksi kokonaislukua ja palauttaa niiden summan, mutta ei tulosta mitään
  • funktio retDiv ottaa vastaan kaksi kokonaisluka ja palauttaa niiden osamäärän (float), mutta ei tulosta mitään
  • jos jakaja on nolla retDiv funktiossa "aiheutuu runtime error" eli voit käyttää seuraavaa lausetta
        throw std::runtime_error("jakaja ei saa olla nolla!");    
        
  • kutsu em. funktioita mainissa, niin että annat niille argumenttina muuttujat a ja b ja tulosta niiden palauttamat arvot. Funktion retDiv-kutsu tulee tehdä try-catch- rakenteella seuraavasti:
        //jos try-lohkossa nousee runtime error, hypätään catch-lohkoon
        try {
            result = retDiv(a,b);
            cout << a << "/" <<  b << " = " << result << endl;
        } catch (runtime_error& e) {
            cout<<"Error: "<< e.what()<< endl;
        }
        

try-catch-rakenteella käsitellään poikkeuksia eli ohjelman suorituksen aikana havaittuja virhetilanteita. try-lohkoon kirjoitetaan koodi, joka voi heittää poikkeuksen throw-lauseella. Jos poikkeus heitetään, suoritus siirtyy sitä vastaavaan catch-lohkoon, jossa virhe käsitellään. Tässä esimerkissä retDiv heittää poikkeuksen, jos jakaja on nolla. Merkintä runtime_error& e tarkoittaa, että poikkeus otetaan vastaan viittauksena ja sille annetaan nimi e. Nimen e voi valita itse. Kun poikkeus heitetään lauseella throw std::runtime_error("jakaja ei saa olla nolla!");, teksti tallentuu poikkeusolioon. Kutsu e.what() palauttaa tämän saman tekstin. Jos poikkeusta ei synny, catch-lohko ohitetaan. Monet valmiit funktiot voivat heittää poikkeuksen virhetilanteessa. Tässä harjoituksessa opetellaan heittämään poikkeus itse kirjoitetusta funktiosta ja käsittelemään se kutsujan try-catch-rakenteessa.

Miksi try-catch eikä pelkkä if? Yksinkertaisessa tilanteessa pelkkä if-rakenne voi riittää. Tässä if tunnistaa nollan jakajana, mutta throw välittää tiedon virheestä funktion kutsujalle. Näin retDiv-funktion ei tarvitse itse tulostaa virheilmoitusta tai palauttaa virheen merkiksi jotakin lukua, joka voisi sekoittua oikeaan tulokseen. Kutsuja päättää catch-lohkossa, miten virhe käsitellään. Samalla try-catch-rakenteella voidaan käsitellä myös kutsuttujen kirjastofunktioiden heittämiä poikkeuksia, joita pelkkä if ei ota kiinni.

Lisätietoa try catch -rakenteesta https://www.w3schools.com/cpp/cpp_exceptions.asp



Toggle Menu