Luokan operaatiot. Osoittimet ja viittaukset luokan olioihin

Koko: px
Aloita esitys sivulta:

Download "Luokan operaatiot. Osoittimet ja viittaukset luokan olioihin"

Transkriptio

1 Luokan operaatiot 13 Luokan operaatiot Luokkien olioiden luomiseen ja tuhoamiseen liittyy monia hienouksia, joista sinun tulee olla selvillä, jotta luokkiesi olioiden operaatiot toimivat turvallisesti ja tehokkaasti. Tässä luvussa käsittelemme luokan olioiden luomista ja tuhoamista. Tehdäksemme selväksi, että tietyt asiat täytyy tehdä tietyssä järjestyksessä, rakennamme luokkiamme tässä ja seuraavassa luvussa lisäämällä niihin uusia ominaisuuksia. Käymme läpi välivaiheita, joissa on heikkouksia, jotka täytyy ratkaista. Luvun aiheita ovat: Miten osoittimia ja viittauksia käytetään luokkatyypeissä Mikä on luokan tuhoajafunktio ja milloin sellainen tulisi tehdä Miten luokissa käytetään dynaamista muistia Milloin tulee tehdä kopiomuodostin ja miten se tehdään Miten luokkaan käsiksi pääsemistä rajoitetaan Mikä on sisäkkäinen luokka Osoittimet ja viittaukset luokan olioihin Edellisessä luvussa näimme, kuinka osoittimia ja viittauksia luokan olioihin esiteltiin ja käytettiin samaan tapaan kuin niitä käytettiin perustietotyyppienkin kohdalla. Osoittimet ja viittaukset luokan olioihin ovat olio-ohjelmoinnin tärkeimpiä ominaisuuksia ja niillä on kummallakin omat etunsa. Seuraavassa on kolme tilannetta, joissa voit käyttää osoittimia luokkaolioon: Olion operaation käynnistämiseen - eli kutsumalla funktiota jäseneen viittaus - operaattorilla -> Funktion parametrinä Luokan jäsenmuuttujana 497

2 C++ Ohjelmoijan käsikirja Ensimmäinen näistä on tapa, joka mahdollistaa funktion kutsumisen polymorfismin avulla, eli kun kutsuttava funktio riippuu osoitettavasta oliosta. Tätä ominaisuutta käsittelemme laajasti luvussa 16. Olion osoittimen välittämisellä funktiolle parametrinä vältetään arvoparametrimekanismin mukainen automaattinen kopiointi. Tämä saattaa ratkaisevasti parantaa ohjelmasi suorituskykyä - varsinkin jos oliot ovat suuria, koska suurten olioiden kopiointi vie runsaasti suoritusaikaa. Jos luokka sisältää jäsenmuuttujanaan osoittimen olioon, voidaan useita olioita linkittää yhteen; näin voidaan yhdistää myös erityyppisiä olioita. Tämä on tärkeää, jotta tietoa voidaan organisoida esimerkiksi graafeihin tai puihin, tai linkitettyihin listoihin, joita käsittelimme lyhyesti luvussa 11. Palaamme linkitettyihin listoihin aivan pian. Viittauksilla olioihin on tärkeä asema funktion parametrin tyyppinä. Yleisesti ottaen olion välittäminen funktiolle viittauksena on huomattavasti nopeampaa kuin arvoparametrinä välittäminen, koska tällöin vältämme kopioinnin. Viittaus on myös oleellisessa asemassa kopiomuodostimen toteutuksessa - kuten tulemme huomaamaan. Osoittimet jäsenmuuttujina! Osoittimen esittely luokan jäsenmuuttujaksi on varsin yksinkertaista. Seuraavassa näemme, miten osoitintyyppisiä jäsenmuuttujia käytetään käytännössä. Katsotaan luvussa 11 esitettyä esimerkkiä: olioiden linkitetty lista. Voimme käyttää tätä ideaa rakentaessamme esimerkkiä, jossa käytetään osoitintyyppistä jäsenmuuttujaa. Samalla yhdistämme siihen joitakin luvussa 12 esitettyjä ominaisuuksia. Lisäksi näemme, miten hyvin pienikin luokka voi saada aikaan odottamattomia ongelmia, jotka meidän tulee pystyä tunnistamaan ja käsittelemään. Tässä kohtaa haluan sanoa, että sinun ei tarvitse luoda omia linkitetty lista-luokkia; standardikirjastossa on varsin joustava versio valmiina käytettäväksi, kuten tulemme näkemään. Voimme kuitenkin oppia paljon, jos yritämme muodostaa omat luokkamme tähän tarkoitukseen. Lisäksi saamme runsaasti tietoa linkitettyjen listojen toiminnasta. 498 Määrittelemme luokan, joka mallintaa mielivaltaisen kokoisen Laatikko-olioiden kokoelman (Laatikko-luokka on sama luokka kuin määrittelimme luvussa 12). Laatikko-olio kuvaa toimitettavaa tuotetta ja Laatikko-olioiden kokoelma kuvaa autokuormallista Laatikko-olioita, joten kutsumme luokkaa nimellä AutoKuorma. AutoKuorma-luokka auttaa meitä suunnittelemaan, miten auto tulisi kuormata, jotta kuljettaja voi purkaa toimitettavat tuotteet oikeassa järjestyksessä. Lopulta tätä ohjelmaa voitaisiin käyttää esimerkiksi yrityksen jakelukeskuksessa. Keskus voi esimerkiksi ottaa vastaan tuotteiden tilauksia ja järjestää niiden toimituksen. Toimitustapa on autokuljetus. Tässä mallissa auton lastausjärjestys on ratkaiseva, koska kuljettajan täytyy pystyä purkamaan laatikot oikeassa järkestyksessä reittinsä varrella.

3 Luokan operaatiot Linkitetty lista on sopiva tähän tarkoitukseen. Voisimme käyttää taulukkoa, mutta linkitetyllä listalla on kaksi merkittävää etua. Ensimmäkin, taulukon koon täytyy olla kiinteä kun esittelemme sen, kun taas linkitetty lista voi olla niin pitkä tai lyhyt kuin haluamme - tämä mahdollistaa tehokkaan muistin käytön. Toiseksi, koska jakelukeskus käsittelee jokaisen toimitettavan tuotteen erikseen, tuote täytyy pystyä lisäämään listan alkuun, loppuun tai keskelle. Tämä voidaan toteuttaa tehokkaasti linkitetyllä listalla, mutta ei taulukolla. Haluamme, että uusi AutoKuorma-olio voidaan luoda yksittäisestä Laatikko-oliosta tai Laatikkoolioiden taulukosta. Haluamme myös, että AutoKuorma-olioon voidaan lisätä Laatikko-olioita ja että kaikki AutoKuorma-olion Laatikko-oliot voidaan saada selville. Rakennetaan luokka nyt askelittain. Meidän tulee ensin miettiä, miten yhdistämme Laatikko-oliot toisiinsa, jotta ne muodostavat yhtenäisen kokonaisuuden - autokuorman. Tarvitsemme ohjelmointikeinon, jolla voidaan yhdistää mielivaltainen määrä Laatikko-olioita toisiinsa. Laatikko-oliolla ei ole mitään omaa sisäistä valmiutta linkittämiseen ja Laatikko-luokan muuttaminen tällaista linkittämistä varten olisi ristiriidassa laatikon idean kanssa - laatikot eivät ole sellaisia. Yksi tapa yhdistää Laatikko-olioita on määritellä toinen olio, jota kutsumme nimellä Paketti. Paketilla on kaksi ominaisuutta - se voi sisältää Laatikko-olion ja se voidaan linkittää toiseen Paketti-olioon. Paketti-olio Laatikkoolio Osoitin toiseen Paketti-olioon toinen Paketti-olio Paketti-olio voi sisältää Laatikko-olion ja voidaan linkittää toiseen Paketti-olioon, joka sisältää toisen Laatikko-olion. Kaavio näyttää kuinka jokainen Paketti-olio sisältää Laatikko-olion ja muodostaa Pakettiolioiden ketjun, joka muodostuu osoittimien avulla. Eli Paketti-olio on yksinkertaisesti osa, joka muodostaa listan. Laatikko/Paketti -yhdistelmä havainnollistaa sitä, että jos haluamme organisoida olioita rakenteisiin, meidän tulee välttämättä tehdä myös toinen olio, joka ikäänkuin sisältää toisen olion ja voimme näin muodostaa linkkejä olioiden välille. 499

4 C++ Ohjelmoijan käsikirja Tässä tapauksessa Paketti-olioiden, joista jokainen sisältää Laatikko-olion, kokoelma luodaan ja hallitaan AutoKuorma-olion avulla. AutoKuorma-olio mallintaa autokuormallista laatikoita - autokuormassa voi olla kuinka monta laatikkoa tahansa. Paketti-olio sisältää mekanismin, jonka avulla AutoKuorma-olio voi pitää kirjaa sisältämistään Laatikko-olioista. Näiden olioiden välinen suhde kuvataan alla olevassa kaaviossa: AutoKuorma-olio Paketti-olio Laatikko ltk; Paketti* pseurt; Paketti-olio Laatikko ltk; Paketti* pseurt; Paketti-olio Laatikko ltk; Paketti* pseurt; 0 Kaavio sisältää AutoKuorma-olion, joka sisältää Paketti-olioiden listan: jokainen Paketti-olio sisältää Laatikko-olion ja osoittimen seuraavaan Paketti-olioon. Tämä AutoKuorma-olio sisältää kolme Paketti-oliota, mutta se voisi yhtä hyvin sisältää yhden olion tai tuhat oliota. Tässä alkeellisessa toteutuksessa lisäämme olioita vain listan perään. Tällöin Paketti-luokan muodostinfunktion tulee luoda olio, joka on irti listasta - eli sisältää null-osoittimen. Lisätäksemme Paketti-olion listan perään, voimme lisätä Paketti-luokkaan funktion, jonka avulla listan viimeisen olion pseur-osoitin muutetaan uuden olion osoitteeksi. Tämä tapahtuu AutoKuorma-luokassa, joka mallintaa listan. Kehittyneemmässä toteutuksessa olisi varsin helppoa toteuttaa funktio, jolla Pakettiolio voitaisiin lisätä mihin kohtaan listaa tahansa. Standardikirjaston linkitetty lista, list, tukee tätä ominaisuutta. Paketti-luokan määrittely Edellä olleen perusteella ensimmäinen tehtävä Paketti-luokan rakentamisessa on suunnitella luokka, jossa on kaksi jäsenmuuttujaa, yksi Laatikko-tyyppinen ja toinen osoitin Paketti-olioon : class Paketti public: Paketti(Laatikko* pltk): ltk(*pltk), pseur(0) // Muodostinfunktio Laatikko haeltk() const return ltk; // Luetaan ltk-olio Paketti* haeseur() const return pseur; // Seuraavan paketin osoite void asetseur(paketti* ppaketti) pseur = ppaketti; // Lisätään paketti listaan 500

5 Luokan operaatiot private: Laatikko ltk; Paketti* pseur; ; // Laatikko-olio // Osoitin seuraavaan pakettiin Ennen kuin tutustumme tämän luokan muihin ominaisuuksiin, meidän tulisi vakavasti harkita tämän luokan toteutuksen seurauksia. Kun Paketti-luokan muodostinfunktio luo Paketti-olion Laatikko-oliosta, se alustaa jäsenmuuttujan ltk parametrinsa mukaan. Tähän liittyy erittäin tärkeä asia: nimittäin se, että Paketti-luokan muodostinfunktio luo kopion Laatikko-oliosta. Mietitään tätä hieman tarkemmin. Paketti-luokan muodostinfunktio luo Paketti-olion kopioimalla Laatikko-olion (joka on jo olemassa) ja lisää osoittimen Paketti-olioon. Tämän ensimmäinen ongelma on ilmeinen muistin tuhlaus: miksi Paketti-oliolla tulee olla oma kopio Laatikko-oliosta, joka on jo olemassa? Toinen ongelma on varsin käytännönläheinen ja liittyy tähän kopiointiin. Joka kerta, kun luomme Paketti-olion, Laatikko-olio kopioidaan tavu tavulta alkuperäisestä sijaintipaikasta uuteen olioon. Kopiointiprosessi vie yleensä aikaa. Jos kopioitavat oliot ovat suuria tai jos kopioidaan useita olioita samassa ohjelmassa, ohjelmamme on todennäköisesti varsin tehoton. Jos tarkoituksenamme on laajentaa ohjelmaa jatkossa, tästä tulee suuri ongelma. Kolmas ongelma on myös käytännönläheinen: jos meillä on monta kopiota yhdestä Laatikkooliosta, miten tiedämme, että niissä kaikissa on samat arvot? Oletetaan, että jostain syystä yhden Laatikko-olion arvoja pitäisi muuttaa. Jos yrittäisimme löytää ja muuttaa kaikki Laatikko-olion kopiot, ohjelman koodista tulisi varsin kömpelöä ja suorituskyky heikkenisi edelleen. Myös virheiden mahdollisuus kasvaisi. Seuraava kaavio selventää, mitä tapahtuisi, jos yrittäisimme toteuttaa tämän version Pakettiluokasta. Kuten huomaat, jokaisesta Laatikko-oliosta on olemassa useita kopioita. Yksi kopio muodostuu Paketti-luokan muodostinfunktiossa. Huomaa, että myöskin haeltk()-jäsenfunktio (joka mahdollistaa jäsenmuuttujan private ltk arvon lukemisen luokan Paketti ulkopuolelta) muodostaa kopion ltk-jäsenmuuttujasta joka kerta, kun sitä kutsutaan. ltk Alkup. Laatikko-olio Kun luot Paketti-olion, välität &ltk muodostinfunktiolle Luotu Paketti-olio sisältää kopion alkuperäisestä Laatikko-oliosta Paketti-olio ltk-olion kopio ltk:n kopio Jäsenen lueltk() kutsuminen luo kopion kopioidusta ltk -oliosta.. Pakettimuodostinfunktio lueltk()- funktio 501

6 C++ Ohjelmoijan käsikirja On vähättelyä, jos sanomme, että tämä on varsin sekavaa. On selvää, että emme voi toteuttaa Paketti-luokkaa siten, että se sisältää kopion alkuperäisestä Laatikko-oliosta. Meidän tulee miettiä luokan suunnitelma uudelleen. Yhtenä ratkaisuna olisi suunnitella Paketti-luokka sellaiseksi, että se sisältää osoittimen alkuperäiseen Laatikko-olioon (Laatikko-olion kopion sijaan). Luokan määrittely olisi tällöin seuraava: class Paketti public: Paketti(Laatikko* puusiltk): pltk(puusiltk), pseur(0) // Muodostinfunktio Laatikko* haeltk() const return pltk; // Luetaan ltk-olio Paketti* haeseur() const return pseur; // Seuraavan paketin osoite void asetaseur(paketti* ppaketti) pseur = ppaketti; // Lisätään paketti listaan private: Laatikko* pltk; Paketti* pseur; ; // Laatikko-olio // Osoitin seuraavaan pakettiin Nyt käsittelemme Laatikko-olion osoittimia, eivätkä listassa olevat Laatikko-oliot ole kopioita. ltkolio ltkolio ltkolio Paketti-olio Osoitin ltk- olioon Osoitin toiseen Paketti-olioon Paketti-olio Osoitin ltk- olioon Osoitin toiseen Paketti-olioon Paketti-olio Osoitin ltk- olioon Osoitin toiseen Paketti-olioon Paketti -olio sisältää nyt vain osoittimia. Laatikko-oliot ovat itsenäisiä ja Paketti-olioiden ulkopuolella haeltk()-funktion avulla päästään luokan ulkopuolelta käsiksi Paketti-luokan yksityiseen Laatikko*-jäseneen. Kun funktiota haeseur() kutsutaan halutun Paketti-olion kanssa, se palauttaa listan seuraavan Paketti-olion (tai null-osoittimen, jos saavutetaan listan pää). Jotta voimme päivittää osoittimen listan seuraavaan Paketti-olioon, olemme määritelleet asetaseur()-funktion, joka asettaa parametrinään saamansa arvon pseur-osoittimeen. Lisätäksesi uuden Paketti-olion listan perään, välität yksinkertaisesti sen osoitteen asetaseur()-funktiolle.

7 ! Luokan operaatiot Paketti-luokka sisältää nyt riittävästi toiminnallisuutta tämänhetkisiin tarpeisiimme. Voimme nyt käyttää sitä AutoKuorma-luokan listan toteutuksessa. Kun teemme säiliöluokkia, kuten AutoKuorma-luokka, sinun tulee tarkasti miettiä pitäisikö luokan jäsenmuuttujien olla kopioita alkuperäisistä luokista vai ei. Joskus sillä ei ole mitään välia, mutta yleensä on - jos et huomio tätä, saatat saada ohjelmaasi varsin epämääräisiä virheitä. Kun käytät säiliöitä, on usein viisasta välttää kopiointia. Osoittimien käyttö, kuten teimme tässä, ei kuitenkaan ole ainut ratkaisutapa. Myöhemmin näemme, kuinka voimme käyttää viittauksia välttääksemme olioiden kopioinnin. AutoKuorma-luokan määrittely AutoKuorma-luokka mallintaa Paketti-olioiden listan. Luokan tulee sisältää kaikki tarpeellinen listan luomiseen ja laajentamiseen, sekä tavan, jolla Laatikko-olioita voidaan lukea. Jos talletamme listan ensimmäisen Paketti-olion osoitteen AutoKuorma-olioon, pääsemme käsiksi kaikkiin muihinkin listan Paketti-olioihin seuraamalla pseur-osoittimien muodostamaa ketjua käyttämällä Paketti-luokan haeseur()-funktiota. Viimeisen Paketti-olion osoitteen tallettaminen on myös hyödyllistä, koska sen avulla listan loppuun on helppo lisätä uusia olioita. Pakettien lista 0 Listan ensimmäinen paketti Listan viimeinen paketti AutoKuorma-olio Viimeksi käsitelty paketti Paketti*pAlku; Paketti*pNykyinen; Paketti*pHanta; Mietitään hieman, kuinka Laatikko-olion lukemisen pitäisi toimia. Alkukohtana on listan ensimmäinen olio - joten tarvitsemme AutoKuorma-luokkaan funktion, joka palauttaa tämän. Kutsumme sitä nimellä haeensimmainen(). Jos pidämme kirjaa AutoKuorma-luokasta viimeksi haetusta Paketti-oliosta, voimme käyttää haeseuraava()-funktiota hakemaan Laatikko-olion listan seuraavasta Paketti-oliosta ja päivittää viimeksi haetusta Paketti-oliosta kirjaa pitävää muuttujaa. 503

8 C++ Ohjelmoijan käsikirja Toinen tärkeä ominaisuus on Laatikko-olion lisääminen listaan, jota varten tarvitsemme myöskin jäsenfunktion - kutsumme sitä nimellä lisaaltk(). Seuraavassa on AutoKuorma-luokan alkuperäinen määrittely, joka perustuu juuri käsittelemiimme ideoihin: class AutoKuorma public: AutoKuorma(Laatikko* pltk = 0, int lkm = 1); // Muodostinfunktio Laatikko* haeensimmainen(); Laatikko* haeseuraava(); void lisaaltk(laatikko* pltk); private: Paketti* palku; Paketti* phanta; Paketti* pnykyinen; ; // Haetaan ensimmainen laatikko // Haetaan seuraava laatikko // Lisää listaan uuden laatikon // Listan ensimmäinen // Listan viimeinen // Viimeksi käsitelty Olemme esitelleet kaikki jäsenmuuttujat yksityisiksi, koska niiden ei tarvitse olla käytettävissä luokan ulkopuolella. Olemme myöskin määritelleet luokalle yhden muodostinfunktion, jonka parametreillä on oletusarvot, joten sitä voidaan kutsua kolmella eri tavalla. Jos jätät molemmat parametrit pois, se toimii oletusmuodostinfunktiona ja luo tyhjän listan. Jättämällä vain lkmparametrin pois, se luo listan, jossa on yksi Laatikko-olio, koska ltk:n oletusarvo on 1. Jos määrittelemme molemmat parametrit, funktio luo listan, jossa on haluttu määrä (lkm) Laatikkoolioita pltk-taulukosta. Näemme hetken päästä, kuinka nämä toteutetaan AutoKuorma-luokan muodostinfunktiossa. Laatikko-olioiden haku toteutetaan jäsenfunktioilla haeensimmainen() ja haeseuraava(). Kummankin näistä tulee muuttaa pnykyinen-osoitinta, joten emme voi esitellä niitä const-tyyppisiksi jäsenfunktioiksi. Myöskin lisaaltk()-funktio muuttaa listaa, joten sitäkään ei voida toteuttaa const-tyyppiseksi. Kaikki jäsenfunktiomme tarvitsevat ulkoisia määrittelyjä, joten katsotaan seuraavaksi, kuinka rakennamme ne yhteen. 504 AutoKuorma-luokan toteutus Voimme aloittaa muodostinfunktiosta. Se luo joko yhden tai useamman Paketti-olion Laatikkoolioiden listasta, tai sitten se luo tyhjän listan: AutoKuorma::AutoKuorma(Laatikko* pltk, int lkm) palku = phanta = pnykyinen = 0; if((lkm > 0) && (pltk!= 0)) for(int i = 0 ; i<lkm ; i++) lisaaltk(pltk+i);

9 Luokan operaatiot Tämä asettaa luokan jäsenmuuttujien arvoiksi nollat, jotta aloitamme tyhjästä listasta. Jos listaan tulee lisätä olioita, pltk on nullista poikkeava ja lkm on positiivinen, joten tarkastamme tämän if-lauseessa. Jos molemmat ehdot ovat true, lisäämme Laatikko-olion käyttämällä lisaaltk()- jäsenfunktiota, jonka määrittelyyn palaamme hetken päästä. Jokainen lisaaltk()-funktion kutsu luo Paketti-olion, joka sisältää Laatikko-olion, johon funktion parametri osoittaa, ja lisää tämän Paketti-olion listaan. Eli for-silmukassa lisäämme listaan ensin Laatikko-olion osoitteessa pltk, sitten pltk+1, sitten pltk+2 ja niin edelleen. Palauta mieleen, että osoittimen kasvattaminen yhdellä siirtää sen osoittamaan seuraavaan olioon, joten pltk:n osoitetta kasvatetaan arvolla sizeof(laatikko). Jäsenfunktioiden määrittely Määritellään ensiksi lisaaltk()-funktio, koska kutsumme sitä muodostinfunktiosta: void AutoKuorma::lisaaLtk(Laatikko* pltk) Paketti* ppaketti = new Paketti(pLtk); // Luodaan paketti if(palku) phanta->asetaseur(ppaketti); else palku = ppaketti; phanta = ppaketti; // Tarkistetaan, että lista ei ole tyhjä // Lisätään uusi olio häntään // Lista on tyhjä // joten uusi olio on alku // Lisätään sen osoite häntään Funktio luo uuden Paketti-olion vapaasta muistista ja tallettaa palautetun osoitteen paikalliseen muuttujaan ppaketti. On olemassa mahdollisuus, että new-operaattori ei pysty varaamaan tarvittavaa muistia, mutta emme käsittele tätä ongelmaa tässä. Näemme, miten tällainen tilanne käsitellään, kun käsittelemme poikkeusten käsittelyä luvussa 17. Kun lisäämme olion listaan, meidän tulee tutkia, onko lista tyhjä. Jos palku on null-arvosta poikkeava, lista ei ole tyhjä, ja voimme lisätä uuden olion listan loppuun tallettamalla sen osoitteen nykyisen phanta-olion jäseneen pseur. Jos palku on null, lista on tyhjä ja voimme tallettaa uuden olion listan ensimmäiseksi jäseneksi. Tässä esimerkissä uusi Paketti-olio lisätään aina listan loppuun, joten phanta-jäsentä päivitetään tätä vastaavasti. Funktion haeensimmainen() määrittely on lasten leikkiä: Laatikko* AutoKuorma::haeEnsimmainen() pnykyinen = palku; return pnykyinen->haeltk(); Listan ensimmäinen Paketti-olio on talletettu osoitteeseen palku, joten talletamme tämän osoitteen jäsenmuuttujaan pnykyinen. Tämän jälkeen kutsumme Paketti-olion haeltk()-funktiota, joka hakee Laatikko-olion osoitteen, jonka palautamme. haeseuraava()-funktion tulee päästä käsiksi seuraavaan Paketti-olioon viimeksi haetun Pakettiolion haeseur()-funktion avulla, mutta meidän tulee huomioida myös tilanne, että pnykyinen on null. haeseuraava()-funktion määrittely on seuraava: 505

10 C++ Ohjelmoijan käsikirja Laatikko* AutoKuorma::haeSeuraava() if(pnykyinen) pnykyinen = pnykyinen->haeseur(); else pnykyinen = palku; // pnykyinen ei ole null -> seuraavaksi // pnykyinen on null // joten asetetaan ensimmäiseksi return pnykyinen? pnykyinen->haeltk() : 0; Normaalissa suoritusjärjestyksessä, kun pnykyinen sisältää Paketti-olion olemassa olevan osoitteen, kutsumme nykyisen Paketti-olion haeseur()-funktiota saadaksemme selville seuraavan osoitteen. Jos pnykyinen on null, palaamme yksinkertaisesti listan alkuun. Kaikki tämä hoidetaan if-else -lauseessa. On tietysti mahdollista, että olemme ohittaneet listan lopun, jolloin pnykyinen on null; palautamme tässä tapauksessa arvon 0 ehto-operaattorin avulla. Jos yrittäisimme kutsua haeltk()-funktiota, kun pnykyinen on null, ohjelman suoritus päättyy virheeseen (emme ole käsitelleet alkioiden poistamista listasta, mutta kun niin teemme, voimme päätyä tilanteeseen, että lista on tyhjä). Palautuvan null-arvon avulla huomaat, että listan loppu on saavutettu: yksinkertaisesti tarkistat haeseuraava()-funktion palauttaman osoittimen. Vaikka olemme nyt koonneet kaikki listan luonnissa ja käytössä tarvittavat palaset yhteen, huomaamme pian, että AutoKuorma-luokassamme on vakava virhe. Jätetään tämä varoitus kuitenkin huomioimatta ja kokeillaan esimerkkiämme ja palataan ongelmaan myöhemmin. Kokeile itse - Linkitetyn listan käyttö Sijoitamme Laatikko-luokan täydellisen määrittelyn otsikkotiedostoon Laatikko.h: // Laatikko.h - Laatikko-luokan määrittely #ifndef LAATIKKO_H #define LAATIKKO_H class Laatikko public: Laatikko(double apituus = 1.0, double asyvyys = 1.0, double akorkeus = 1.0); //Muodostinfunktio double tilavuus() const; // Laskee laatikon tilavuuden double luepituus() const; double luesyvyys() const; double luekorkeus() const; int vertaatilavuuksia(const Laatikko& toinenltk) const; // Vertailee laatikoiden tilavuuksia 506 private: double pituus; double syvyys; double korkeus; ; #endif

11 Luokan operaatiot Olemme lisänneet funktiot, joilla luemme Laatikko-olion mitat, koska tarvitsemme niitä esimerkissämme. Määrittelemme muodostinfunktion ja funktiot erilliseen.cpp-tiedostoon Laatikko.cpp: // Laatikko.cpp Laatikko-luokan toteutus #include "Laatikko.h" // Muodostinfunktio Laatikko::Laatikko(double apituus, double asyvyys, double akorkeus) pituus = apituus > 0.0? apituus : 1.0; syvyys = asyvyys > 0.0? asyvyys : 1.0; korkeus = akorkeus > 0.0? akorkeus : 1.0; // Funktio, joka laskee laatikon tilavuuden double Laatikko::tilavuus() const return pituus*syvyys*korkeus; // luexxx() -funktiot double Laatikko::luePituus() const return pituus; double Laatikko::lueSyvyys() const return syvyys; double Laatikko::lueKorkeus() const return korkeus; // Funktio, joka vertailee kahta Laatikko-oliota // Jos nykyinen laatikko on suurempi kuin parametrin laatikko, palautuu 1 // Jos ne ovat yhtä suuret, palautuu 0 // Jos nykyinen laatikko on pienempi kuin parametrin laatikko, palautuu -1 int Laatikko::vertaaTilavuuksia(const Laatikko& toinenltk) const double til1 = tilavuus(); // Nykyisen laatikon tilavuus double til2 = toinenltk.tilavuus(); // Parametrilaatikon tilavuus return til1>til2? 1 : (til1<til2? -1 : 0); Voimme sijoittaa linkitetyn listan toteuttavan kahden luokan määrittelyt samaan otsikkotiedostoon Lista.h. Johdonmukaisuuden vuoksi järkestämme Paketti-luokan määrittelyn siten, että muodostinfunktio ja funktiot määritellään ulkoisesti. Tiedoston sisältö on: // Lista.h Linkitettyä listaa tukevat luokat #ifndef LISTA_H #define LISTA_H #include "Laatikko.h" // Listan alkio -luokan määrittely class Paketti public: Paketti(Laatikko* puusiltk); Laatikko* haeltk() const; Paketti* haeseur() const; void asetaseur(paketti* ppaketti); private: Laatikko* pltk; Paketti* pseur; ; // Muodostinfunktio // Haetaan laatikko-osoitin // Haetaan seuraava laatikko // Lisätään listan loppuun // Osoitin laatikkoon // Osoitin seuraavaan pakettiin 507

12 C++ Ohjelmoijan käsikirja // AutoKuorma-luokan määrittely - toteuttaa listan class AutoKuorma public: AutoKuorma(Laatikko* pltk = 0, int lkm = 1); // Muodostinfunktio Laatikko* haeensimmainen(); Laatikko* haeseuraava(); void lisaaltk(laatikko* pltk); // Haetaan ensimmäinen laatikko // Haetaan seuraava laatikko // Lisää listaan uuden laatikon private: Paketti* palku; // Listan ensimmäinen Paketti* phanta; // Listan viimeinen Paketti* pnykyinen; // Viimeksi käsitelty ; #endif Huomaa, että Paketti-luokan määrittely on AutoKuorma-luokan määrittelyn edellä. Jos järjestys olisi toisinpäin, koodi ei kääntyisi, koska AutoKuorma-luokka viittaa Paketti-tyyppiin. Joskus voit ajautua tilanteeseen, jossa kahden luokan A ja B määrittelyt viittaavat toisiinsa. Tällaisessa tilanteessa A täytyy esitellä ennen kuin luokka B määritellään; tämän jälkeen myös luokka A voidaan määritellä. Luokan A esittely voidaan tehdä seuraavalla lauseella: class A; Tämä kertoo kääntäjälle, että A on luokka - eli kääntäjä voi jatkaa eteenpäin ja kääntää luokan B; tämän jälkeen kääntäjä tietää myös luokan B ja luokan A määrittely voidaan näin kääntää. Jäsenfunktioiden määrittelyt voidaan sijoittaa Lista.cpp-tiedostoon: // Lista.cpp #include "Laatikko.h" #include "Lista.h" // Paketti-luokan määrittelyt // Paketti-luokan muodostinfunktio Paketti::Paketti(Laatikko* puusiltk): pltk(puusiltk), pseur(0) // Haetaan Laatikko-osoitin Laatikko* Paketti::haeLtk() const return pltk; // Haetaan seuraavan paketin osoite Paketti* Paketti::haeSeur() const return pseur; // Lisätään paketti listan loppuun void Paketti::asetaSeur(Paketti* ppaketti) pseur = ppaketti; // AutoKuorma-luokan määrittelyt 508 // AutoKuorma-luokan muodostinfunktio AutoKuorma::AutoKuorma(Laatikko* pltk, int lkm) palku = phanta = pnykyinen = 0;

13 Luokan operaatiot if((lkm > 0) && (pltk!= 0)) for(int i = 0 ; i<lkm ; i++) lisaaltk(pltk+i); // Haetaan ensimmäinen laatikko Laatikko* AutoKuorma::haeEnsimmainen() pnykyinen = palku; return pnykyinen->haeltk(); // haetaan seuraava laatikko Laatikko* AutoKuorma::haeSeuraava() if(pnykyinen) pnykyinen = pnykyinen->haeseur(); else pnykyinen = palku; // pnykyinen ei ole null -> seuraavaksi // pnykyinen on null // joten asetetaan ensimmäiseksi return pnykyinen? pnykyinen->haeltk() : 0; // Lisätään listaan uusi laatikko void AutoKuorma::lisaaLtk(Laatikko* pltk) Paketti* ppaketti = new Paketti(pLtk); // Luodaan paketti if(palku) // Tarkistetaan, että lista ei ole tyhjä phanta->asetaseur(ppaketti); // Lisätään uusi olio häntään else // Lista on tyhjä palku = ppaketti; // joten uusi olio on alku phanta = ppaketti; // Lisätään sen osoite häntään! Jäsenfunktiot, jotka on esitelty const-tyyppisiksi luokan määrittelyssä, täytyy määritellä const-tyyppisiksi myös niiden määrittelyssä. const kuuluu funktion allekirjoitukseen - tämä tarkoittaa sitä, että jos unohdat määritellä ne consttyyppisiksi funktion määrittelyssä, kääntäjä tulkitsee ne eri funktioiksi kuin luokan esittelyssä olevat. Huomaa, että tiedosto Lista.h sisältää #include-esikäsittelijäkomennon Laatikkoluokan määrittelyä varten. Itse asiassa otsikkotiedostoissa on useita #includeesikäsittelijäkomentoja. Erityisesti Lista.cpp sisältää #include-esikäsittelijäkomennot otsikkotiedostoille Laatikko.h ja Lista.h. Luvussa 10 käsittelemämme #ifndef/#endif -esikäsittelijäkomennot on jokaisessa otsikkotiedostossa - ne estävät määrittelyjen tulemisen mukaan useamman kerran. Ilman niitä Lista.cpp ei käänny, koska se sisällyttäisi Laatikko.h:n kahteen kertaan: kerran suoraan ja kerran Lista.h:n kautta. Esimerkin Prog13_1.cpp main()-funktiossa voimme luoda joitakin Laatikko-olioita ja järjestää ne linkitettyyn listaan. Luomme kaksi listaa: yhden, jonka rakennamme yhden Laatikko-olion sisältämästä listasta lisäämällä uusia olioita ja toisen Laatikko-olioiden taulukosta. Voimme käyttää luvussa 10 kirjoittamaamme satunnaisluku()-funktiota generoimaan laatikon mitat. Listan testausta varten haemme kummastakin listasta suurimman Laatikko-olion. Seuraavassa on koodi: 509

14 C++ Ohjelmoijan käsikirja // Esimerkki 13.1 Linkitetyn listan käyttö #include <iostream> #include <cstdlib> // satunnaislukugeneraattoria varten #include <ctime> // time-funktiota varten using namespace std; #include "Laatikko.h" #include "Lista.h" // Funktio, joka generoi satunnaisen kokonaisluvun väliltä 1 - lkm inline int satunnaisluku(int lkm) return 1 + static_cast<int>((lkm*static_cast<long>(rand()))/(rand_max+1)); int main() const int dimraja = 100; srand((unsigned)time(0)); // Laatikon mitan yläraja // Alustetaan satunnaislukugeneraattori // Luodaan tyhjä lista AutoKuorma kuorma1; // Lisätään listaan 10 satunnaisen kokoista laatikkoa for(int i = 0 ; i < 10 ; i++) kuorma1.lisaaltk(new Laatikko(satunnaisluku(dimRaja),satunnaisluku(dimRaja), satunnaisluku(dimraja))); // Etsitään listan suurin laatikko Laatikko* pltk = kuorma1.haeensimmainen(); Laatikko* pseurltk; while(pseurltk = kuorma1.haeseuraava()) if(pltk->vertaatilavuuksia(*pseurltk) < 0) pltk = pseurltk; // Sijoitetaan ja testataan cout << endl << "Ensimmäisen listan suurin laatikko on " << pltk->luepituus() << " * " << pltk->luesyvyys() << " * " << pltk->luekorkeus() << endl; const int ltklkm = 20; Laatikko laatikot[ltklkm]; // Alkioiden määrä taulukossa // Laatikko-olioiden taulukko for(int i = 0 ; i < ltklkm ; i++) laatikot[i] = Laatikko(satunnaisluku(dimRaja), satunnaisluku(dimraja), satunnaisluku(dimraja)); AutoKuorma kuorma2(laatikot, ltklkm); // Etsitään listan suurin laatikko pltk = kuorma2.haeensimmainen(); while(pseurltk = kuorma2.haeseuraava()) if(pltk->vertaatilavuuksia(*pseurltk) < 0) pltk = pseurltk; 510

15 Luokan operaatiot cout << endl << "Toisen listan suurin laatikko on " << pltk->luepituus() << " * " << pltk->luesyvyys() << " * " << pltk->luekorkeus() << endl; // Poistetaan ensimmäisen listan Laatikko-oliot pseurltk = kuorma1.haeensimmainen(); while(pseurltk) delete pseurltk; pseurltk = kuorma1.haeseuraava(); return 0; Kun minä suoritan tämän esimerkin, saan tulostuksen: Ensimmäisen listan suurin laatikko on 94 * 68 * 55 Toisen listan suurin laatikko on 80 * 73 * 78 Saat varmastikin jotain erilaista kuin tässä, koska Laatikko-olioiden mitat generoidaan satunnaisesti. Palauta mieleen (luvusta 10), että satunnaislukugeneraattori alustetaan tietokoneen kellolla. Kuinka se toimii Funktio main() luo kaksi Laatikko-olioiden listaa. Todellisten Laatikko-olioiden puuttuessa generoimme satunnaisen kokoisia laatikoita, joiden mittojen koko on väliltä 1 ja 100. Satunnaiset mitat generoidaan seuraavasti määritellyllä funktiolla: inline int satunnaisluku(int lkm) return 1 + static_cast<int>((lkm*static_cast<long>(rand()))/(rand_max+1)); Tämä kutsuu standardikirjaston funktiota rand(), joka (kuten luvussa 10 näimme) generoi satunnaisen kokonaisluvun väliltä 0 ja RAND_MAX. Prosessi aloitetaan kutsumalla standardikirjaston funktiota srand(), jolla alustetaan satunnaislukugeneraattori. Tähän käytetään yleensä nykyistä kellonaikaa. Funktion rand() palauttama arvo muunnetaan välille 0 ja 99, johon sitten lisätään luku 1, jotta satunnaisluku()-funktio palauttaa arvon väliltä Muunnamme palautetun arvon long-tyyppiseksi, jolla varmistamme, että kertolasku suoritetaan long-tyyppisillä arvoilla. Muutoin saattaisimme saada arvon, joka ei mahdu int-tyyppiin, koska int on vain kaksi tavua. Käytämme AutoKuorma-luokan muodostinfunktion oletusmuotoa luodessamme tyhjän listan: AutoKuorma kuorma1; Tämän jälkeen lisäämme for-silmukassa 10 Laatikko-oliota listaan kuorma1: for(int i = 0 ; i < 10 ; i++) kuorma1.lisaaltk(new Laatikko(satunnaisluku(dimRaja),satunnaisluku(dimRaja), satunnaisluku(dimraja))); 511

16 C++ Ohjelmoijan käsikirja Jokaisella silmukan kierroksella luomme Laatikko-olion vapaasta muistista ja lisäämme sen listaan lisaaltk()-funktiolla. Meidän ei tarvitse pitää kirjaa näistä olioista, koska ne ovat käytettävissä listassa. Seuraavaksi käymme listan läpi löytääksemme Laatikko-olion, jonka tilavuus on suurin: Laatikko* pltk = kuorma1.haeensimmainen(); Laatikko* pseurltk; while(pseurltk = kuorma1.haeseuraava()) if(pltk->vertaatilavuuksia(*pseurltk) < 0) pltk = pseurltk; // Sijoitetaan ja testataan Tässä osassa ohjelmaa osoitinta pltk käytetään tallettamaan suurimman olion osoite. Aluksi pltk asetetaan listan ensimmäiseen olioon. while-silmukkaa kontrolloi kuorma1-olion haeseuraava()-funktion palauttama osoite. On tärkeää huomata, että while-silmukan ehtolauseke sisältää sijoitusoperaattorin (=) eikä vertailuoperaattoria (==): tällöin while-silmukassa testattava lauseke on pseurltk sijoituksen jälkeen. Kun pseurltk on nolla, olemme saavuttaneet listan lopun ja silmukan suoritus päättyy. Käytämme silmukassa Laatikko-luokan vertaatilavuuksia()-funktiota vertaamaan osoittimen pltk osoittaman laatikon ja listan nykyisessä positiossa olevan laatikon (johon osoittaa osoitin pseurltk) tilavuuksia. Meidän täytyy käyttää -> -operaattoria vertaatilavuuksia()-funktion kutsussa, koska kutsumme sitä osoittimen pltk kautta. Funktio vaatii parametrinä olion, joten välitämme *pseurltk:n. Jos palautuva arvo on negatiivinen, parametrinä ollut olio on suurempi kuin pltk:n osoittama olio, joten talletamme sen osoitteen pltk-osoittimeen uutena suurimpana oliona. Kun silmukan suoritus päättyy, pltk sisältää listan tilavuudeltaan suurimman Laatikkoolion osoitteen. Sitten tulostamme tämän Laatikko-olion mitat lauseella: cout << endl << "Ensimmäisen listan suurin laatikko on " << pltk->luepituus() << " * " << pltk->luesyvyys() << " * " << pltk->luekorkeus() << endl; Toistamme samat toiminnot myös toiselle listalle kuorma2, jonka luomme Laatikko-olioiden taulukosta. Huomaa, että ensimmäisen listan Laatikko-oliot luodaan vapaasta muistista, kun taas taulukon Laatikko-oliot ovat paikallisia olioita. Tämän vuoksi meidän tulee poistaa esimmäisen listan Laatikko-oliot muistista ennen ohjelman suorituksen päättymistä. No, kaikki näyttää toimivan OK, ja saimme oikeat vastaukset, joten mikä on pielessä AutoKuorma-luokassa? Itse asiassa siinä on kolme ongelmaa: Vähiten merkityksellinen ongelma on se, että Paketti-luokka on kaikkien käytettävissä, vaikka haluamme käyttää tätä luokkaa vain AutoKuorma-luokan yhteydessä. 512

17 Luokan operaatiot Hieman vakavampi ongelma (vaikka se ei olekaan ilmeinen tässä esimerkissä) koskee AutoKuorma-luokan kopiointia. Oletetaan, että otamme AutoKuorma-olion, kuorma1, ja teemme siitä suoran kopion, kuorma2. Tämän tuloksena on, että kuorma2 ei ole riippumaton kuorma1:stä - koska molemmat listat sisältävät osoittimet samoihin Laatikko-olioihin ja ne molemmat sisältävät myös osoittimet samoihin Paketti-olioihin. Jos nyt poistamme kuorma2-olion, myös luokalle kuorma1 kuuluvat oliot tuhoutuvat, koska ne tuhotaan kuorma2-olion mukana. Kolmas ongelma liittyy muistinhallintaan. Katso uudelleen, miten luomme AutoKuorma-luokan Paketti-oliot. Ne luodaan vapaasta muistista, mutta mikään ei poista niitä muistista. Joka kerta, kun lisäämme uuden Laatikko-olion listaan, luodaan uusi Paketti-olio, jota ei koskaan poisteta muistista. Ei edes silloin, kun AutoKuorma-olion näkyvyysalue päättyy. Tämä on erittäin vakava muistivuoto, jota ei koskaan pidä jättää ohjelmaan. Katsotaan seuraavaksi, kuinka voimme ratkaista nämä ongelmat. Aloitetaan ensimmäisestä. Luokan käsittelyn kontrollointi Käytännössä törmätään varsin usein tarpeeseen rajoittaa luokkaan käsiksi pääsemistä. Suunnittelimme Paketti-luokan käytettäväksi erityisesti AutoKuorma-luokan kanssa, joten meidän pitäisi varmistaa, että Paketti-olioita voivat muodostaa vain AutoKuorma-luokan funktiot. Tarvitsemme mekanismin, jolla voimme esitellä Paketti-oliot julkisiksi AutoKuorma-luokalle, mutta yksityisiksi kaikille muille. Paras tapa tehdä tämä on käyttää sisäkkäisiä luokkia. Sisäkkäiset luokat Sisäkkäinen luokka on luokka, jonka määrittely on toisen luokan sisällä. Sisemmän luokan nimeä voi käyttää vain ulommassa luokassa. Voimme sijoittaa Paketti-luokan määrittelyn AutoKuormaluokan määrittelyn sisälle: class AutoKuorma public: AutoKuorma(Laatikko* pltk = 0, int lkm = 1); // Muodostinfunktio Laatikko* haeensimmainen(); Laatikko* haeseuraava(); void lisaaltk(laatikko* pltk); private: // Listan alkio -luokan määrittely class Paketti public: Laatikko* pltk; Paketti* pseur; // Haetaan ensimmäinen laatikko // Haetaan seuraava laatikko // Lisää listaan uuden laatikon // Osoitin laatikkoon // Osoitin seuraavaan pakettiin ; void asetaseur(paketti* ppaketti); Paketti(Laatikko* puusiltk); // Lisätään listan loppuun // Muodostinfunktio 513

18 C++ Ohjelmoijan käsikirja ; Paketti* palku; Paketti* phanta; Paketti* pnykyinen; // Listan ensimmäinen // Listan viimeinen // Viimeksi käsitelty Paketti-tyyppi on nyt paikallinen AutoKuorma-luokan määrittelyssä. Koska olemme sijoittaneet Paketti-luokan määrittelyn AutoKuorma-luokan yksityiseen osaan, Paketti-olioita ei voida luoda AutoKuorma-luokan ulkopuolelta. Koska Paketti-luokka on täysin yksityinen AutoKuorma-luokassa, voimme tehdä Paketti-luokan jäsenet julkisiksi. Koska jäsenet ovat vapaasti käytettävissä AutoKuorma-luokan jäsenfunktioista, voimme poistaa Paketti-luokan jäsenfunktiot haeltk() ja haeseur(). Yksikään Paketti-olion jäsen ei ole käytettävissä luokan ulkopuolella. Meidän tulee myös muuttaa AutoKuorma-luokan jäsenfunktioiden määrittelyä. Funktio lisaaltk() pystyy lisäämään uuden olion listan loppuun käsittelemällä viimeisen olion pseur-jäsenmuuttujaa suoraan: void AutoKuorma::lisaaLtk(Laatikko* pltk) Paketti* ppaketti = new Paketti(pLtk); // Luodaan paketti if(palku) phanta->pseur = ppaketti; else palku = ppaketti; phanta = ppaketti; // Tarkistetaan, että lista ei ole tyhjä // Lisätään uusi olio häntään // Lista on tyhjä // joten uusi olio on alku // Lisätään sen osoite häntään Ensimmäisen Laatikko-olion hakevan funktion ei enää tarvitse kutsua funktiota saadakseen Laatikko-olion osoitteen, joten määrittely näyttää nyt seuraavalta: Laatikko* AutoKuorma::haeEnsimmainen() pnykyinen = palku; return pnykyinen->pltk; Funktio, joka hakee listan seuraavan Laatikko-olion, voidaan määritellä nyt seuraavasti: Laatikko* AutoKuorma::haeSeuraava() if(pnykyinen) pnykyinen = pnykyinen->pseur; else pnykyinen = palku; // pnykyinen ei ole null -> seuraavaksi // pnykyinen on null // joten asetetaan ensimmäiseksi return pnykyinen? pnykyinen->pltk : 0; 514

19 Paketti-luokan sijoittaminen AutoKuorma-luokan sisälle määrittelee yksinkertaisesti Paketti-tyypin. AutoKuorma-luokan oliot eivät muutu mitenkään - niillä on aivan samat jäsenet kuin aikaisemminkin. Sisemmän luokan jäsenfunktiot voivat suoraan viitata ulomman luokan staattisiin jäseniin ja muihinkin ulomman luokan tyyppeihin ja lueteltuihin tyyppeihin. Muihin ulomman luokan jäseniin voidaan sisemmästä luokasta viitata tavalliseen tapaan: luokan olion kautta tai olioon viittauksen tai osoittimen kautta. Luokan operaatiot Sisäkkäiset luokat ja julkinen saantitapa Mainitaan lyhyesti, mitä tapahtuu, jos sijoitamme Paketti-luokan määrittelyn AutoKuorma-luokan julkiseen osaan. Tällöin ohjelmassa voidaan luoda Paketti-olioita ulkoisesti. Esimerkiksi: AutoKuorma::Paketti apaketti(altk); //Määrittelee Paketti-tyyppisen muuttujan Luonnollisestikin Paketti-tyypin tekeminen julkiseksi hävittää syyt, jotka saivat meidät tekemään siitä sisäkkäisen luokan! Ystäväluokat Luokkaan käsiksi pääsyä voidaan rajoittaa myös käyttämällä ystäväluokkia. Tällöin voimme esitellä kaikki Paketti-luokan jäsenmuuttujat yksityisiksi ja määritellä koko luokan AutoKuormaluokan ystäväksi. Tämä tapahtuu lisäämällä seuraava lause Paketti-luokan määrittelyyn: friend class AutoKuorma;! Tämä varmistaa, että kaikki Paketti-olion jäsenet ovat käytettävissä AutoKuorma-luokassa, mutta muualla ei. Kaikissa tämän luvun tulevissa esimerkeissä käytämme kuitenkin sisäkkäisiä luokkia. Tämä on ideamme mukaista, sillä Paketti-luokka ei ole itsenäinen olio, vaan sillä on merkitystä vain AutoKuorma-olioiden yhteydessä. Kopiomuodostimen tärkeys Kopiomuodostinta käytetään luomaan uusi olio, joka on aivan samanlainen kuin jo olemassa oleva olio. Mainitsimme esimerkin 12.5 yhteydessä, että kääntäjä muodostaa oletuskopiomuodostimen, jos sellaista tarvitaan, etkä ole määritellyt sellaista luokan määrittelyssä. Oletuskopiomuodostin kopioi alkuperäisen olion jäsenmuuttujat uuden olion vastaaviin jäsenmuuttujiin. Tämä saattaa aiheuttaa ongelmia joissain tapauksissa ja varsinkin AutoKuorma-luokan kohdalla näin tapahtuu. Oletetaan, että haluamme kopioida AutoKuorma-olion - jos esimerkiksi haluamme toistaa saman jakelusuunnitelman toisena päivänä. Kun kopioit AutoKuorma-luokan olion, oletus- 515

20 C++ Ohjelmoijan käsikirja kopiomuodostin yksinkertaisesti kopioi jäsenmuuttujiin palku, phanta ja pnykyinen talletetut osoitteet. Tällöin molemmat AutoKuorma-oliot jakavat saman Paketti-olioiden ketjun. AutoKuorma tkuorma2(tkuorma1); tkuorma1 palku pnykyinen phanta pltk pseur tkuorma2 palku pnykyinen phanta pltk pseur pltk pseur pltk pseur Jaettu Paketti.olioiden lista 0 Tässä ei itse asiassa ole kuin yksi lista. Meillä on kuitenkin kaksi eri mahdollisuutta käsitellä listaa ja vaara piileekin juuri tässä. Jos muutamme listaa esimerkiksi olion tkuorma1 kautta, se vaikuttaa Paketti-olioiden ketjuun, mutta muutos ei siirry olion tkuorma2 jäseniin. Erityisesti, jos lisäät olion listaan tkuorma1, olion tkuorma2 jäsen phanta ei enää osoitakaan listan viimeiseen olioon. Tähän liittyy vielä muutakin. Törmäämme samankaltaisiin ongelmiin, jos teemme funktion, jolle välitetään AutoKuorma-olio parametrinä. Palauta mieleen, että kopiomuodostinta kutsutaan, kun funktiolle välitetään parametri arvoparametrimekanismilla. Tästä syystä funktion kutsussa käytetään AutoKuorma-luokan kopiomuodostinta luomaan kopio alkuperäisestä AutoKuorma-oliosta - jos funktio nyt lisää olion listaan, alkuperäisen AutoKuorma-olion eheys rikkoutuu. 516 Kopiomuodostimen toteuttaminen Olion kopiomuodostimelle tulee välittää parametrinä saman luokan olio ja sen tulee luoda kopio asianmukaisella tavalla. Tässä on välitön ongelma, joka meidän tulee ratkaista. Näemme tämän selkeästi, jos yritämme kirjoittaa kopiomuodostimen AutoKuorma-luokalle: AutoKuorma::AutoKuorma(AutoKuorma Kuorma) //Koodi, joka luo Kuorma-olion kopion

21 Luokan operaatiot Tämä näyttää ensisilmäyksellä olevan OK, mutta mitä tapahtuu, kun muodostinfunktiota kutsutaan? Parametri välitetään arvoparametrinä, joten kääntäjä kutsuu kopiomuodostinta tehdäkseen kopion parametristä. Parametri välitetään kopiomuodostimelle tietysti arvoparametrinä, joten tarvitaan uusi kopiomuodostimen kutsu; ja niin edelleen. Lyhyesti sanottuna olemme saaneet aikaan rekursiivisen kopiomuodostimen kutsun. Itse asiassa, kääntäjä ei käännä tällaista koodia. Ratkaisuna on välittää parametri viittauksena. Viittausparametrit Kopiomuodostin tulee määritellä siten, että parametrinä on const-tyyppinen viittaus: AutoKuorma::AutoKuorma(const AutoKuorma& Kuorma) //Koodi, joka luo Kuorma-olion kopion Nyt parametriä ei enää välitetä arvoparametrinä, joten vältämme kopiomuodostimen rekursiiviset kutsut. Sen sijaan kääntäjä välittää funktiolle vain viittauksen kopioitavaan olioon. Parametrin tulee olla const-tyyppinen, koska kopiomuodostin tekee vain kopioita - sen ei tule muuttaa alkuperäistä oliota. Tästä voit päätellä, että kopiomuodostimen parametrin tulee aina olla const-tyyppinen viittaus saman luokan olioon. Toisin sanoen, kopiomuodostin on saman mallinen kaikille luokille: Tyyppi::Tyyppi(const Tyyppi& olio) //Koodi, joka luo kopion oliosta Tässä yleisessä muodossa Tyyppi on luokan tyypin nimi. Eli miten kopiomuodostin toteutetaan AutoKuorma-luokallemme? Meidän täytyy luoda kopio Paketti-olioiden ketjusta luotavalle uudelle AutoKuorma-oliolle. Tämä voidaan tehdä seuraavalla koodilla, kun Paketti-luokka on määritelty AutoKuorma-luokan sisälle: AutoKuorma::AutoKuorma(const AutoKuorma& kuorma) palku = phanta = pnykyinen = 0; if(kuorma.palku == 0) return; Paketti* papu = kuorma.palku; do lisaaltk(papu->pltk); while(papu = papu->pseur); // Tallettaa uuden ketjun osoitteen // Sijoitetaan ja sitten testataan osoitin Tässä luodaan kopio ensimmäisestä Paketti-oliosta kutsumalla sen kopiomuodostinta ja sitten kopioidaan kaikki seuraavat Paketti-oliot ja osoitinta pseur päivitetään aina kunkin kopioidun Paketti-olion kohdalla ketjun seuraavan olion osoitteella. 517

22 C++ Ohjelmoijan käsikirja Tässä alkuperäiset ja kopioidut Paketti-oliot osoittavat yhä samoihin Laatikkoolioihin. Jos haluamme tehdä täysin riippumattoman AutoKuorma-olion, jonka Paketti-oliot osoittavat omiin Laatikko-olioihinsa, meidän täytyisi toteuttaa oma kopiomuodostin myös Paketti-luokalle. Tarpeisiimme riittää, että yksinkertaisesti toteutamme kopiomuodostimen vain AutoKuorma-luokalle. Kokeillaan, toimiiko versiomme myös käytännössä. Kokeile itse - Kopiomuodostimen käyttö Tarvitsemme esimerkin 13.1 tiedostoja Laatikko.h ja Laatikko.cpp sellaisenaan. Käytämme sisäkkäisiä AutoKuorma/Paketti -luokkia edellä kuvatulla tavalla ja lisäämme kopiomuodostimen, joten Lista.h sisältää seuraavat määrittelyt: class AutoKuorma public: AutoKuorma(Laatikko* pltk = 0, int lkm = 1); // Muodostinfunktio AutoKuorma(const AutoKuorma& kuorma); //Kopiomuodostin Laatikko* haeensimmainen(); Laatikko* haeseuraava(); void lisaaltk(laatikko* pltk); private: // Listan alkio -luokan määrittely class Paketti public: Laatikko* pltk; Paketti* pseur; // Haetaan ensimmäinen laatikko // Haetaan seuraava laatikko // Lisää listaan uuden laatikon // Osoitin laatikkoon // Osoitin seuraavaan pakettiin ; void asetaseur(paketti* ppaketti); Paketti(Laatikko* puusiltk); // Lisätään listan loppuun // Muodostinfunktio ; Paketti* palku; Paketti* phanta; Paketti* pnykyinen; // Listan ensimmäinen // Listan viimeinen // Viimeksi käsitelty AutoKuorma-luokan kopiomuodostimen prototyyppi on lisätty tässä luokan julkiseksi jäseneksi. Tiedostoa Lista.cpp täytyy myöskin muuttaa tämän mukaan; meidän tulee myöskin muuttaa AutoKuorma-luokan jäsenfunktioita lisaaltk(), haeensimmainen() ja haeseuraava() ja poistaa Paketti-luokan jäsenfunktiot haeltk() ja haeseur(). Viimeinen muutos tiedostoon Lista.cpp on muuttaa muita Paketti-luokan jäsenfunktioita: // Paketti-luokan muodostinfunktio AutoKuorma::Paketti::Paketti(Laatikko* puusiltk): pltk(puusiltk), pseur(0) // Lisätään paketti listan loppuun void AutoKuorma::Paketti::asetaSeur(Paketti* ppaketti) pseur = ppaketti; 518

23 Luokan operaatiot Luomme AutoKuorma-olioon tällä kertaa vain kolme laatikkoa. Voimme käyttää kopiomuodostinta kopioimaan olemassa olevan AutoKuorma-olion ja sitten laajentaa sitä. Koska etsimme suurimman tilavuuden omaavan Laatikko-olion useista listoista, voimme sijoittaa tämän tekevän koodin omaan funktioonsa. Tässä on koodi: // Esimerkki 13.2 Kopiomuodostimen käyttö #include <iostream> #include <cstdlib> // Satunnaislukugeneraattoria varten #include <ctime> // time-funktiota varten using namespace std; #include "Laatikko.h" #include "Lista.h" // Funktio, joka generoi satunnaisen kokonaisluvun väliltä 1 - lkm inline int satunnaisluku(int lkm) return 1 + static_cast<int>((lkm*static_cast<long>(rand()))/(rand_max+1)); // Funktio, joka etsii listan tilavuudeltaan suurimman laatikon Laatikko* maxltk(autokuorma& Kuorma) Laatikko* pltk = Kuorma.haeEnsimmainen(); Laatikko* pseurltk; while(pseurltk = Kuorma.haeSeuraava()) // Sijoitetaan ja testataan osoitin if(pltk->vertaatilavuuksia(*pseurltk) < 0) pltk = pseurltk; return pltk; int main() const int dimraja = 100; srand((unsigned)time(0)); // Laatikon mitan yläraja // Alustetaan satunnaislukugeneraattori // Luodaan lista AutoKuorma kuorma1; // Lisätään listaan 3 laatikkoa for(int i = 0 ; i < 3 ; i++) kuorma1.lisaaltk(new Laatikko(satunnaisluku(dimRaja), satunnaisluku(dimraja), satunnaisluku(dimraja))); Laatikko* pltk = maxltk(kuorma1); // 1. listan suurin laatikko cout << endl << "Ensimmäisen listan suurin laatikko on " << pltk->luepituus() << " * " << pltk->luesyvyys() << " * " << pltk->luekorkeus() << endl; AutoKuorma kuorma2(kuorma1); pltk = maxltk(kuorma2); // Luodaan kopio 1. listasta // 2. listan suurin laatikko 519

24 C++ Ohjelmoijan käsikirja cout << endl // Tulostetaan se << "Toisen listan suurin laatikko on " << pltk->luepituus() << " * " << pltk->luesyvyys() << " * " << pltk->luekorkeus() << endl; // Lisätään toiseen listaan 5 uutta laatikkoa for(int i = 0; i<5; i++) kuorma2.lisaaltk(new Laatikko(satunnaisluku(dimRaja), satunnaisluku(dimraja), satunnaisluku(dimraja))); pltk = maxltk(kuorma2); // Laajennetun listan suurin laatikko cout << endl // Tulostetaan se << "Laajennetun toisen listan suurin laatikko on " << pltk->luepituus() << " * " << pltk->luesyvyys() << " * " << pltk->luekorkeus() << endl; // Lasketaan ensimmäisen listan laatikoiden lukumäärä ja tulostetaan se Laatikko* pseurltk = kuorma1.haeensimmainen(); int lkm = 0; // Laatikkojen lukumäärä while(pseurltk) // Kun listassa on laatikko lkm++; // Kasvatetaan lukumäärää pseurltk = kuorma1.haeseuraava(); // ja haetaan seuraava laatikko cout << endl << "1. listassa on yhä " << lkm << " Laatikko-oliota."<< endl; // Poistetaan Laatikko-oliot vapaasta muistista pseurltk = kuorma2.haeensimmainen(); while(pseurltk) delete pseurltk; pseurltk = kuorma2.haeseuraava(); return 0; Kun suoritin ohjelman, se tulosti: Ensimmäisen listan suurin laatikko on 9 * 37 * 76 Toisen listan suurin laatikko on 9 * 37 * 76 Laajennetun toisen listan suurin laatikko on 89 * 56 * listassa on yhä 3 Laatikko-oliota. Saat varmasti jotain muuta. Suorita ohjelma muutaman kerran, niin saat laajennetun listan suurimmaksi laatikoksi jonkin muun. Kuinka se toimii Uudelle maxltk()-funktiollemme välitetään parametrinä AutoKuorma-olio. Se palauttaa osoittimen, joka osoittaa tämän autokuorman tilavuudeltaan suurimpaan laatikkoon. Tämän funktion koodi on otettu esimerkin 13.1 main()-funktiosta. Huomaa, että parametri on viittaus, joten meidän ei tarvitse suorittaa listan kopiointia.

25 Luokan operaatiot Havainnollistaaksemme, että AutoKuorma-luokan kopiomuodostin toimii kuten sen pitäisi, luomme ensin tyhjän AutoKuorma-olion kuorma1: AutoKuorma kuorma1; Tämän jälkeen, kuten teimme esimerkin 13.1 ohjelmassakin, lisäämme Laatikko-olioita listaan. Jokainen Laatikko-olio luodaan vapaasta muistista: for(int i = 0 ; i < 3 ; i++) kuorma1.lisaaltk(new Laatikko(satunnaisluku(dimRaja), satunnaisluku(dimraja), satunnaisluku(dimraja))); Tarkistusta varten haemme tilavuudeltaan listan suurimman Laatikko-olion kutsumalla maxltk()- funktiota: Laatikko* pltk = maxltk(kuorma1); // 1. listan suurin laatikko Kun olemme tulostaneet tämän Laatikko-olion mitat, luomme kopion kuorma1-oliosta käyttämällä AutoKuorma-luokan kopiomuodostinta: AutoKuorma kuorma2(kuorma1); // Luodaan kopio 1. listasta Jotta varmistumme, että kuorma2 on sama kuin alkuperäinenkin, kutsumme maxltk()-funktiota uudelleen saadaksemme selville kuorma2-olion suurimman laatikon ja tulostamme sen mitat. Tämän jälkeen lisäämme kuorma2-olioon viisi Laatikko-oliota: for(int i = 0; i<5; i++) kuorma2.lisaaltk(new Laatikko(satunnaisluku(dimRaja), satunnaisluku(dimraja), satunnaisluku(dimraja))); Seuraavaksi kutsumme jälleen maxltk()-funktiota kuorma2-oliolla, jotta saamme selville suurimman kahdeksasta laatikosta; ja tulostamme sen mitat. Tärkeä kohta on siinä, että kuorma1-olio ei ole muuttunut ja havainnollistaaksemme tämän laskemme kuorma1-oliossa olevien Laatikko-olioiden lukumäärän: Laatikko* pseurltk = kuorma1.haeensimmainen(); int lkm = 0; // Laatikkojen lukumäärä while(pseurltk) // Kun listassa on laatikko lkm++; // Kasvatetaan lukumäärää pseurltk = kuorma1.haeseuraava(); // ja haetaan seuraava laatikko Silmukkaa kontrolloi osoitin pseurltk. Aluksi se sisältää ensimmäisen Laatikko-olion osoitteen; niin kauan kuin pseurltk ei osoita listan lopun yli (eli niin kauan kuin pseurltk ei ole null), kasvatamme lkm:n arvoa ja siirrämme osoitinta pseurltk eteenpäin listassa. Kun tulemme listan loppuun, haeseuraava() palauttaa arvon null ja silmukan suoritus päättyy. Lopuksi, kun olemme tulostaneet lkm:n arvon, poistamme muistista kaikki kuorma2-olion Laatikko-oliot. Tähän kuuluu tietysti myös kuorma1:n oliot, joten meidän ei tarvitse huolehtia niistä erikseen. 521

Operaattoreiden uudelleenmäärittely

Operaattoreiden uudelleenmäärittely Operaattoreiden uudelleenmäärittely 14 Operaattoreiden uudelleenmäärittely Tässä luvussa käsittelemme, kuinka voit lisätä toiminnallisuutta luokkiisi, jotta ne toimivat enemmän C++:n perustietotyyppien

Lisätiedot

Ohjelman virheet ja poikkeusten käsittely

Ohjelman virheet ja poikkeusten käsittely Ohjelman virheet ja poikkeusten käsittely 17 Ohjelman virheet ja poikkeusten käsittely Poikkeukset ovat tapa ilmoittaa virheistä ja odottamattomista tilanteista C++-ohjelmassasi. Poikkeusten käyttö virheiden

Lisätiedot

Virtuaalifunktiot ja polymorfismi

Virtuaalifunktiot ja polymorfismi Virtuaalifunktiot ja polymorfismi 16 Virtuaalifunktiot ja polymorfismi Polymorfismi on niin tehokas olio-ohjelmoinnin ominaisuus, että tulet varmastikin käyttämään sitä lähes kaikissa C++-ohjelmissasi.

Lisätiedot

Osoitin ja viittaus C++:ssa

Osoitin ja viittaus C++:ssa Osoitin ja viittaus C++:ssa Osoitin yksinkertaiseen tietotyyppiin Osoitin on muuttuja, joka sisältää jonkin toisen samantyyppisen muuttujan osoitteen. Ohessa on esimerkkiohjelma, jossa määritellään kokonaislukumuuttuja

Lisätiedot

Periytyminen. Luokat ja olio-ohjelmointi

Periytyminen. Luokat ja olio-ohjelmointi Periytyminen 15 Periytyminen Tässä luvussa käsittelemme aihetta, joka on olio-ohjelmoinnin kaikkein tärkein osa - periytyvyys. Periytyvyyden avulla voimme luoda uusia luokkia uudelleenkäyttämällä ja laajentamalla

Lisätiedot

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta C++ - perusteet Java-osaajille luento 5/7: operaattoreiden ylikuormitus, oliotaulukko, parametrien oletusarvot, komentoriviparametrit, constant, inline, Operaattoreiden ylikuormitus Operaattoreiden kuormitus

Lisätiedot

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat:

Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat: 1. Luokan jäsenet Luokassa määriteltävät jäsenet ovat pääasiassa tietojäseniä tai aliohjelmajäseniä. Luokan määrittelyyn liittyvät varatut sanat: class luokan_nimi tyypit: enum, struct, class, typedef

Lisätiedot

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset Harjoituksen aiheena ovat aliohjelmat ja abstraktit tietotyypit sekä olio-ohjelmointi. Tehtävät tehdään C-, C++- ja Java-kielillä.

Lisätiedot

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Osoittimet Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Muistilohkon koko riippuu muuttujan tyypistä, eli kuinka suuria arvoja muuttujan

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 3 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten muuttujiin liittyvät kysymykset. Tehtävä 1. Määritä muuttujien max_num, lista,

Lisätiedot

12 Mallit (Templates)

12 Mallit (Templates) 12 Mallit (Templates) Malli on määrittely, jota käyttämällä voidaan luoda samankaltaisten aliohjelmien ja luokkien perheitä. Malli on ohje kääntäjälle luoda geneerisestä tyyppiriippumattomasta ohjelmakoodista

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 30.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 30.9.2015 1 / 27 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.

Lisätiedot

Tietueet. Tietueiden määrittely

Tietueet. Tietueiden määrittely Tietueet Tietueiden määrittely Tietue on tietorakenne, joka kokoaa yhteen eri tyyppistä tietoa yhdeksi asiakokonaisuudeksi. Tähän kokonaisuuteen voidaan viitata yhteisellä nimellä. Auttaa ohjelmoijaa järjestelemään

Lisätiedot

Luokat. Luokat ja olio-ohjelmointi

Luokat. Luokat ja olio-ohjelmointi Luokat 12 Luokat Tässä luvussa laajennamme edellisessä luvussa käsittelemäämme struktuurityyppiä ja siirrymme yhteen C++-ohjelmoijan kaikkein tärkeimmistä välineistä: luokkiin. Käsittelemme myöskin joitakin

Lisätiedot

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. X Poikkeusten käsittelystä 812347A Olio-ohjelmointi, 2015 syksy 2. vsk X Poikkeusten käsittelystä Sisältö 1. Yleistä poikkeusten käsittelystä 2. Poikkeuskäsittelyn perusteita C++:ssa 3. Standardissa määritellyt poikkeukset 4. Poikkeusvarmuus

Lisätiedot

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit IDL - proseduurit 25. huhtikuuta 2017 Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 9.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 9.2.2009 1 / 35 Listat Esimerkki: halutaan kirjoittaa ohjelma, joka lukee käyttäjältä 30 lämpötilaa. Kun lämpötilat

Lisätiedot

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014 18. syyskuuta 2014 IDL - proseduurit Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

Sisältö. 2. Taulukot. Yleistä. Yleistä

Sisältö. 2. Taulukot. Yleistä. Yleistä Sisältö 2. Taulukot Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.1 2.2 Yleistä

Lisätiedot

Mallit standardi mallikirjasto parametroitu tyyppi

Mallit standardi mallikirjasto parametroitu tyyppi Mallit 18 Mallit Malli on tehokas mekanismi uusien luokkien generoimiseksi automaattisesti. Standardikirjaston suuri osa, standardi mallikirjasto, rakentuu kokonaan mallien määrittelymahdollisuuden ympärille,

Lisätiedot

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa.

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa. Taulukot C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa. Taulukon muuttujilla (muistipaikoilla) on yhteinen nimi. Jokaiseen yksittäiseen

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 2.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 2.3.2009 1 / 28 Puhelinluettelo, koodi def lue_puhelinnumerot(): print "Anna lisattavat nimet ja numerot." print

Lisätiedot

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen Metodit Metodien määrittely Metodin parametrit ja paluuarvo Metodien suorittaminen eli kutsuminen Metodien kuormittaminen 1 Mikä on metodi? Metodi on luokan sisällä oleva yhteenkuuluvien toimintojen kokonaisuus

Lisätiedot

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma. 2. Taulukot 2.1 Sisältö Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.2 Yleistä

Lisätiedot

Omat tietotyypit. Mikä on olio?

Omat tietotyypit. Mikä on olio? Omat tietotyypit 11 Omat tietotyypit C++:n suuri vahvuus on sen oliopohjaisuudessa. Siihen liittyy runsaasti asiaa ja kulutammekin seuraavat viisi lukua tässä aiheessa. Tässä ja seuraavassa luvussa käsittelemme

Lisätiedot

Ohjelmointi 1 Taulukot ja merkkijonot

Ohjelmointi 1 Taulukot ja merkkijonot Ohjelmointi 1 Taulukot ja merkkijonot Jussi Pohjolainen TAMK Tieto- ja viestintäteknologia Johdanto taulukkoon Jos ohjelmassa käytössä ainoastaan perinteisiä (yksinkertaisia) muuttujia, ohjelmien teko

Lisätiedot

Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014

Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014 Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014 Kirjoita jokaiseen palauttamaasi konseptiin kurssin nimi, kokeen päivämäärä, oma nimi ja opiskelijanumero. Vastaa kaikkiin tehtäviin omille konsepteilleen.

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 11.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 11.2.2009 1 / 33 Kertausta: listat Tyhjä uusi lista luodaan kirjoittamalla esimerkiksi lampotilat = [] (jolloin

Lisätiedot

T740103 Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

T740103 Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010 12. Periytyminen Johdantoa Käytännössä vähänkään laajemmissa ohjelmissa joudutaan laatimaan useita luokkia, joiden pitäisi pystyä välittämään tietoa toisilleen. Ohjelmien ylläpidon kannalta olisi lisäksi

Lisätiedot

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa(); Sisällys 7. Oliot ja viitteet Olio Java-kielessä. Olion luominen, elinikä ja tuhoutuminen. Viitteiden käsittelyä: sijoitus, vertailu ja varautuminen null-arvoon. Viite metodin paluuarvona.. 7.1 7.2 Olio

Lisätiedot

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä

Sisällys. 7. Oliot ja viitteet. Olion luominen. Olio Java-kielessä Sisälls 7. Oliot ja viitteet Olio Java-kielessä. Olion luominen, elinikä ja tuhoutuminen.. Viitteiden vertailu. Varautuminen null-arvoon. Viite metodin paluuarvona.. Muuttumattomat ja muuttuvat merkkijonot.

Lisätiedot

Sisältö. 22. Taulukot. Yleistä. Yleistä

Sisältö. 22. Taulukot. Yleistä. Yleistä Sisältö 22. Taulukot Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko metodin parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 22.1 22.2 Yleistä

Lisätiedot

Olio-ohjelmointi Syntaksikokoelma

Olio-ohjelmointi Syntaksikokoelma C++-kielen uusia ominaisuuksia Olio-ohjelmointi Syntaksikokoelma 31.10.2008 Bool-tietotyyppi: Totuusarvo true (1), jos ehto on tosi ja false (0) jos ehto epätosi. Dynaaminen muistinvaraus: Yhden muuttuja

Lisätiedot

Osoittimet. Mikä on osoitin?

Osoittimet. Mikä on osoitin? Osoittimet 7 Osoittimet On aika siirtyä käsittelemään osoittimia, C++:lle elintärkeätä ominaisuutta. Osoittimet ovat tärkeitä, koska ne luovat perustan muistin dynaamiselle varaukselle ja käytölle. Ne

Lisätiedot

Kääntäjän virheilmoituksia

Kääntäjän virheilmoituksia OHJ-1101 Ohjelmointi 1e 2008-09 1 Kääntäjän virheilmoituksia Kun progvh2 ohjelma käännetään antaa tutg++ seuraavat virheilmoitukset ja varoitukset: proffa> tutg++ progvh2.cc progvh2.cc:29:13: warning:

Lisätiedot

Olio-ohjelmointi 2. välikoe HYV5SN

Olio-ohjelmointi 2. välikoe HYV5SN Olio-ohjelmointi 2. välikoe 27.4.2007 HYV5SN 1. Tee ohjelma, joka sisältää laatikko-luokan. Luokan tietojäseninä ovat laatikon syvyys, leveys ja korkeus. Toteuta luokkaan muodostin, jonka avulla olio voidaan

Lisätiedot

Olio-ohjelmointi Javalla

Olio-ohjelmointi Javalla 1 Olio-ohjelmointi Javalla Olio-ohjelmointi Luokka Attribuutit Konstruktori Olion luominen Metodit Olion kopiointi Staattinen attribuutti ja metodi Yksinkertainen ohjelmaluokka Ohjelmaluokka 1 Olio-ohjelmointi

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 6 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 6 Vastaukset Harjoituksen aiheena on funktionaalinen ohjelmointi Scheme- ja Haskell-kielillä. Voit suorittaa ohjelmat osoitteessa https://ideone.com/

Lisätiedot

Tietorakenteet ja algoritmit

Tietorakenteet ja algoritmit Tietorakenteet ja algoritmit Rekursio Rekursion käyttötapauksia Rekursio määritelmissä Rekursio ongelmanratkaisussa ja ohjelmointitekniikkana Esimerkkejä taulukolla Esimerkkejä linkatulla listalla Hanoin

Lisätiedot

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5) Alkuarvot ja tyyppimuunnokset (1/5) Aiemmin olemme jo antaneet muuttujille alkuarvoja, esimerkiksi: int luku = 123; Alkuarvon on oltava muuttujan tietotyypin mukainen, esimerkiksi int-muuttujilla kokonaisluku,

Lisätiedot

Harjoitustyö: virtuaalikone

Harjoitustyö: virtuaalikone Harjoitustyö: virtuaalikone Toteuta alla kuvattu virtuaalikone yksinkertaiselle olio-orientoituneelle skriptauskielelle. Paketissa on testaamista varten mukana kaksi lyhyttä ohjelmaa. Ohjeita Noudata ohjelman

Lisätiedot

C++11 lambdat: [](){} Matti Rintala

C++11 lambdat: [](){} Matti Rintala C++11 lambdat: [](){} Matti Rintala bool(*)(int) Tarve Tarve välittää kirjastolle/funktiolle toiminnallisuutta Callback-funktiot Virhekäsittely Käyttöliittymät Geneeristen kirjastojen räätälöinti STL:n

Lisätiedot

Osa III. Edelliset kolme lukua ovat käsitelleet viittausten ja osoittimien käyttöä. Tämän luvun aiheita ovat:

Osa III. Edelliset kolme lukua ovat käsitelleet viittausten ja osoittimien käyttöä. Tämän luvun aiheita ovat: Osa III 12. oppitunti Kehittyneet viittaukset ja osoittimet Edelliset kolme lukua ovat käsitelleet viittausten ja osoittimien käyttöä. Tämän luvun aiheita ovat: Kuinka viittausten viemisellä voidaan tehostaa

Lisätiedot

T Olio-ohjelmointi Osa 3: Luokka, muodostin ja hajotin, this-osoitin Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

T Olio-ohjelmointi Osa 3: Luokka, muodostin ja hajotin, this-osoitin Jukka Jauhiainen OAMK Tekniikan yksikkö 2010 11. Luokka Opetellaan seuraavaksi, miten omia luokkia kirjoitetaan. Aikaisemmin olikin jo esillä, että luokka on tietorakenne, joka sisältää sekä tiedot (attribuutit) että niitä käsittelevät aliohjelmat

Lisätiedot

13 Operaattoreiden ylimäärittelyjä

13 Operaattoreiden ylimäärittelyjä 248 13 C++-kielessä voidaan operaattoreita ylimäärittää. Ylimääriteltävää operaattoria voidaan pitää ikäänkuin metodina, joka esitellään luokan esittelyssä ja määritellään luokan ulkopuolella kuten metoditkin.

Lisätiedot

Taulukot. Jukka Harju, Jukka Juslin 2006 1

Taulukot. Jukka Harju, Jukka Juslin 2006 1 Taulukot Jukka Harju, Jukka Juslin 2006 1 Taulukot Taulukot ovat olioita, jotka auttavat organisoimaan suuria määriä tietoa. Käsittelylistalla on: Taulukon tekeminen ja käyttö Rajojen tarkastus ja kapasiteetti

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 20. huhtikuuta 2018 Vastaa kaikkiin tehtäviin. Tee kukin tehtävä omalle konseptiarkille. Noudata ohjelmointitehtävissä kurssin koodauskäytänteitä.

Lisätiedot

C++ rautaisannos. Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout:

C++ rautaisannos. Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout: C++ rautaisannos Kolme tapaa sanoa, että tulostukseen käytetään standardikirjaston iostreamosassa määriteltyä, nimiavaruuden std oliota cout: # include #include main ( ) main (

Lisätiedot

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille:

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille: Merkkijonot C-kielessä merkkijono on taulukko, jonka alkiot ovat char -tyyppiä. Taulukon viimeiseksi merkiksi tulee merkki '\0', joka ilmaisee merkkijonon loppumisen. Merkkijono määritellään kuten muutkin

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 1.4.2009 T-106.1208 Ohjelmoinnin perusteet Y 1.4.2009 1 / 56 Tentti Ensimmäinen tenttimahdollisuus on pe 8.5. klo 13:00 17:00 päärakennuksessa. Tämän jälkeen

Lisätiedot

7. Oliot ja viitteet 7.1

7. Oliot ja viitteet 7.1 7. Oliot ja viitteet 7.1 Sisällys Olio Java-kielessä. Olion luominen, elinikä ja tuhoutuminen. Viitteiden sijoitus. Viitteiden vertailu. Varautuminen null-arvoon. Viite metodin paluuarvona. Viite metodin

Lisätiedot

Tehtävä 1. TL5302 Olio-ohjelmointi Koe Malliratkaisuja. Tässä sekä a)- että b)-kohdan toimiva ratkaisu:

Tehtävä 1. TL5302 Olio-ohjelmointi Koe Malliratkaisuja. Tässä sekä a)- että b)-kohdan toimiva ratkaisu: TL5302 Olio-ohjelmointi Koe 19.4.2005 Malliratkaisuja Tehtävä 1 Tässä sekä a)- että b)-kohdan toimiva ratkaisu: #include using namespace std; int main() int taul[5]=1,2,3,4,5; int *p,&r=taul[0];

Lisätiedot

TIETORAKENTEET JA ALGORITMIT

TIETORAKENTEET JA ALGORITMIT TIETORAKENTEET JA ALGORITMIT Timo Harju 1999-2004 1 typedef link List; /* Vaihtoehtoisia nimiä */ typedef link Stack; /* nodepointterille */ typedef link Queue typedef struct node Node; /* itse nodelle

Lisätiedot

811312A Tietorakenteet ja algoritmit , Harjoitus 2 ratkaisu

811312A Tietorakenteet ja algoritmit , Harjoitus 2 ratkaisu 811312A Tietorakenteet ja algoritmit 2017-2018, Harjoitus 2 ratkaisu Harjoituksen aiheena on algoritmien oikeellisuus. Tehtävä 2.1 Kahvipurkkiongelma. Kahvipurkissa P on valkoisia ja mustia kahvipapuja,

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.3.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.3.2010 1 / 56 Tiedostoista: tietojen tallentaminen ohjelman suorituskertojen välillä Monissa sovelluksissa ohjelman

Lisätiedot

Muuttujien roolit Kiintoarvo cin >> r;

Muuttujien roolit Kiintoarvo cin >> r; Muuttujien roolit Muuttujilla on ohjelmissa eräitä tyypillisiä käyttötapoja, joita kutsutaan muuttujien rooleiksi. Esimerkiksi muuttuja, jonka arvoa ei muuteta enää kertaakaan muuttujan alustamisen jälkeen,

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 7. huhtikuuta 2017 Vastaa kaikkiin tehtäviin. Tee jokainen tehtävä erilliselle konseptiarkille. Kirjoittamasi luokat, funktiot ja aliohjelmat

Lisätiedot

Pong-peli, vaihe Aliohjelman tekeminen. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana

Pong-peli, vaihe Aliohjelman tekeminen. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana Muilla kielillä: English Suomi Pong-peli, vaihe 3 Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana Jaetaan ohjelma pienempiin palasiin (aliohjelmiin) Lisätään peliin maila (jota ei voi vielä

Lisätiedot

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus?

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus? Osa III 11. oppitunti Viittaukset Kahdessa viime luvussa opit käyttämään osoittimia kohteiden käsittelyyn vapaalla muistialueella sekä viittaamaan noihin kohteisiin epäsuorasti. Tässä luvussa käsiteltävät

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti Tentaattori: Antti-Jussi Lakanen 8. kesäkuuta 2018 Yleistä Tentti 1 meni pistekeskiarvon (11.2) perusteella välttävästi. Omasta tehtäväpaperista saa kopion

Lisätiedot

Ohjelmointi 2. Jussi Pohjolainen. TAMK» Tieto- ja viestintäteknologia , Jussi Pohjolainen TAMPEREEN AMMATTIKORKEAKOULU

Ohjelmointi 2. Jussi Pohjolainen. TAMK» Tieto- ja viestintäteknologia , Jussi Pohjolainen TAMPEREEN AMMATTIKORKEAKOULU Ohjelmointi 2 Jussi Pohjolainen TAMK» Tieto- ja viestintäteknologia Tietotyypeistä C++ - kielessä useita tietotyyppejä Kirjaimet: char, wchar_t Kokonaisluvut: short, int, long Liukuluvut: float, double

Lisätiedot

Java kahdessa tunnissa. Jyry Suvilehto

Java kahdessa tunnissa. Jyry Suvilehto Java kahdessa tunnissa Jyry Suvilehto Ohjelma Ohjelmointiasioita alkeista nippelitietoon n. 45 min Tauko 10 min Oliot, luokat ja muut kummajaiset n. 45 min Kysykää Sisältöä ei oikeasti ole 2x45 min täytteeksi,

Lisätiedot

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista Sisällys 1. Omat operaatiot Yleistä operaatioista. Mihin operaatioita tarvitaan? Oman operaation määrittely. Yleisesti, nimeäminen ja hyvä ohjelmointitapa, määreet, parametrit ja näkyvyys. HelloWorld-ohjelma

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 22. huhtikuuta 2016 Vastaa kaikkiin tehtäviin. Tee jokainen tehtävä erilliselle konseptiarkille! Kirjoittamasi luokat, funktiot ja aliohjelmat

Lisätiedot

1. Omat operaatiot 1.1

1. Omat operaatiot 1.1 1. Omat operaatiot 1.1 Sisällys Yleistä operaatioista. Mihin operaatioita tarvitaan? Oman operaation määrittely. Yleisesti, nimeäminen ja hyvä ohjelmointitapa, määreet, parametrit ja näkyvyys. HelloWorld-ohjelma

Lisätiedot

Algoritmit 2. Luento 7 Ti Timo Männikkö

Algoritmit 2. Luento 7 Ti Timo Männikkö Algoritmit 2 Luento 7 Ti 4.4.2017 Timo Männikkö Luento 7 Joukot Joukko-operaatioita Joukkojen esitystapoja Alkiovieraat osajoukot Toteutus puurakenteena Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 2/26

Lisätiedot

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet Tunnus, varattu sana, kommentti Muuttuja, alkeistietotyyppi, merkkijono, literaalivakio, nimetty vakio Tiedon merkkipohjainen tulostaminen 1 Tunnus Java tunnus Java-kirjain Java-numero

Lisätiedot

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti: 1 (7) Tiedon lukeminen näppäimistöltä Scanner-luokan avulla Miten ohjelma saa käyttöönsä käyttäjän kirjoittamaa tekstiä? Järjestelmässä on olemassa ns. syöttöpuskuri näppäimistöä varten. Syöttöpuskuri

Lisätiedot

Muuttujat ja kontrolli. Ville Sundberg

Muuttujat ja kontrolli. Ville Sundberg Muuttujat ja kontrolli Ville Sundberg 14.9.2007 Alkeistyyppi Alin abstraktiotaso josta tarvitsee välittää Yksittäinen, jakamaton tiedonjyvä Tavallaan kaikki alkeistyypit ovat lukuja arvojoukko vaihtelee

Lisätiedot

Metodien tekeminen Javalla

Metodien tekeminen Javalla 1 Metodien tekeminen Javalla Mikä metodi on? Metodin syntaksi Metodi ja sen kutsuminen Parametreista Merkkijonot ja metodi Taulukot ja metodi 1 Mikä metodi on? Metodilla toteutetaan luokkaan toiminnallisuutta.

Lisätiedot

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset 815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset Harjoituksen aiheena on funktionaalinen ohjelmointi Scheme- ja Haskell-kielillä. Voit suorittaa ohjelmat osoitteessa https://ideone.com/

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 7.2.2011 T-106.1208 Ohjelmoinnin perusteet Y 7.2.2011 1 / 39 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 25.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 25.2.2009 1 / 34 Syötteessä useita lukuja samalla rivillä Seuraavassa esimerkissä käyttäjä antaa useita lukuja samalla

Lisätiedot

Ohjelmointi 2 / 2010 Välikoe / 26.3

Ohjelmointi 2 / 2010 Välikoe / 26.3 Ohjelmointi 2 / 2010 Välikoe / 26.3 Välikoe / 26.3 Vastaa neljään (4) tehtävään ja halutessa bonustehtäviin B1 ja/tai B2, (tuovat lisäpisteitä). Bonustehtävät saa tehdä vaikkei olisi tehnyt siihen tehtävään

Lisätiedot

Algoritmit 2. Luento 13 Ti Timo Männikkö

Algoritmit 2. Luento 13 Ti Timo Männikkö Algoritmit 2 Luento 13 Ti 30.4.2019 Timo Männikkö Luento 13 Simuloitu jäähdytys Merkkijonon sovitus Horspoolin algoritmi Ositus ja rekursio Rekursion toteutus Algoritmit 2 Kevät 2019 Luento 13 Ti 30.4.2019

Lisätiedot

C++11 Syntaksi. Jari-Pekka Voutilainen Jari-Pekka Voutilainen: C++11 Syntaksi

C++11 Syntaksi. Jari-Pekka Voutilainen Jari-Pekka Voutilainen: C++11 Syntaksi 1 C++11 Syntaksi Jari-Pekka Voutilainen 13.4.2012 2 Range-for Iteroi säiliön kaikki alkiot for-silmukassa. Säiliöltä vaaditaan begin- ja end-iteraattorit. Pätee kaikille C++11 STL-säiliöille, taulukoille,

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 12. huhtikuuta 2019 Tee kukin tehtävä omalle konseptiarkille. Noudata ohjelmointitehtävissä kurssin koodauskäytänteitä. Yksi A4-kokoinen lunttilappu

Lisätiedot

Lyhyt kertaus osoittimista

Lyhyt kertaus osoittimista , syksy 2007 Kertausta Luento 10 12.10.2007 Syksy 2007 1 Lyhyt kertaus osoittimista char *p; /* char, int, jne ilmoittavat, minkä tyyppisiä */ Keskusmuisti int *q; /* olioita sisältäviin muistilohkoihin

Lisätiedot

13. Loogiset operaatiot 13.1

13. Loogiset operaatiot 13.1 13. Loogiset operaatiot 13.1 Sisällys Loogiset operaatiot AND, OR, XOR ja NOT. Operaatioiden ehdollisuus. Bittioperaatiot. Loogiset operaatiot ohjausrakenteissa. Loogiset operaatiot ja laskentajärjestys.

Lisätiedot

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 16.3

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 16.3 16. Lohkot 16.1 Sisällys Tutustutaan lohkoihin. Muuttujien ja vakioiden näkyvyys sekä elinikä erityisesti operaation lohkossa. Nimikonfliktit. Muuttujat operaation alussa vai myöhemmin? 16.2 Lohkot Kaarisulut

Lisätiedot

11. Javan toistorakenteet 11.1

11. Javan toistorakenteet 11.1 11. Javan toistorakenteet 11.1 Sisällys Laskuri- ja lippumuuttujat. Sisäkkäiset silmukat. Tyypillisiä ohjelmointivirheitä: Silmukan rajat asetettu kierroksen verran väärin. Ikuinen silmukka. Silmukoinnin

Lisätiedot

Sisällys. 3. Muuttujat ja operaatiot. Muuttujat ja operaatiot. Muuttujat. Operaatiot. Imperatiivinen laskenta. Muuttujat. Esimerkkejä: Operaattorit.

Sisällys. 3. Muuttujat ja operaatiot. Muuttujat ja operaatiot. Muuttujat. Operaatiot. Imperatiivinen laskenta. Muuttujat. Esimerkkejä: Operaattorit. 3. Muuttujat ja operaatiot Sisällys Imperatiivinen laskenta. Muuttujat. Nimi ja arvo. Muuttujan nimeäminen. Muuttujan tyyppi.. Operandit. Arvon sijoitus muuttujaan. Aritmeettiset operaattorit. Arvojen

Lisätiedot

Kirjoita oma versio funktioista strcpy ja strcat, jotka saavat parametrinaan kaksi merkkiosoitinta.

Kirjoita oma versio funktioista strcpy ja strcat, jotka saavat parametrinaan kaksi merkkiosoitinta. Tehtävä 63. Kirjoita oma versio funktiosta strcmp(),joka saa parametrinaan kaksi merkkiosoitinta. Tee ohjelma, jossa luetaan kaksi merkkijonoa, joita sitten verrataan ko. funktiolla. Tehtävä 64. Kirjoita

Lisätiedot

Jypelin käyttöohjeet» Miten voin liittää törmäyksiin tapahtumia?

Jypelin käyttöohjeet» Miten voin liittää törmäyksiin tapahtumia? Muilla kielillä: English Suomi Jypelin käyttöohjeet» Miten voin liittää törmäyksiin tapahtumia? Kun kaksi fysiikkaoliota törmää toisiinsa, syntyy törmäystapahtuma. Nämä tapahtumat voidaan ottaa kiinni

Lisätiedot

1. Mitä tehdään ensiksi?

1. Mitä tehdään ensiksi? 1. Mitä tehdään ensiksi? Antti Jussi i Lakanen Ohjelmointi 1, kevät 2010/ Jyväskylän yliopisto a) Etsitään Googlesta valmis algoritmi b) Mietitään miten itse tehtäisiin sama homma kynällä ja paperilla

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CS-A1111 4.10.2017 CS-A1111 Ohjelmoinnin peruskurssi Y1 4.10.2017 1 / 23 Mahdollisuus antaa luentopalautetta Luennon aikana voit kirjoittaa kommentteja ja kysymyksiä sivulle

Lisätiedot

A274101 TIETORAKENTEET JA ALGORITMIT

A274101 TIETORAKENTEET JA ALGORITMIT A274101 TIETORAKENTEET JA ALGORITMIT PERUSTIETORAKENTEET LISTA, PINO, JONO, PAKKA ABSTRAKTI TIETOTYYPPI Tietotyyppi on abstrakti, kun se on määritelty (esim. matemaattisesti) ottamatta kantaa varsinaiseen

Lisätiedot

Javan perusteita. Janne Käki

Javan perusteita. Janne Käki Javan perusteita Janne Käki 20.9.2006 Muutama perusasia Tietokone tekee juuri (ja vain) sen, mitä käsketään. Tietokone ymmärtää vain syntaksia (sanojen kirjoitusasua), ei semantiikkaa (sanojen merkitystä).

Lisätiedot

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 15.3

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 15.3 15. Lohkot 15.1 Sisällys Tutustutaan lohkoihin. Muuttujien ja vakioiden näkyvyys sekä elinikä erityisesti operaation lohkossa. Nimikonfliktit. Muuttujat operaation alussa vai myöhemmin? 15.2 Lohkot Aaltosulkeet

Lisätiedot

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä Matti Luukkainen 10.12.2009 Tässä esitetty esimerkki on mukaelma ja lyhennelmä Robert Martinin kirjasta Agile and Iterative Development löytyvästä

Lisätiedot

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit Liite E - Esimerkkiprojekti E Esimerkkiprojekti Olet lukenut koko kirjan. Olet sulattanut kaiken tekstin, Nyt on aika soveltaa oppimiasi uusia asioita pienen, mutta täydellisesti muotoiltuun, projektiin.

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 17.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 17.2.2010 1 / 41 Sanakirja Monissa sovelluksissa on tallennettava rakenteeseen avain arvo-pareja. Myöhemmin rakenteesta

Lisätiedot

1 Tehtävän kuvaus ja analysointi

1 Tehtävän kuvaus ja analysointi Olio-ohjelmoinnin harjoitustyön dokumentti Jyri Lehtonen (72039) Taneli Tuovinen (67160) 1 Tehtävän kuvaus ja analysointi 1.1 Tehtävänanto Tee luokka, jolla mallinnetaan sarjaan kytkettyjä kondensaattoreita.

Lisätiedot

4. Luokan testaus ja käyttö olion kautta 4.1

4. Luokan testaus ja käyttö olion kautta 4.1 4. Luokan testaus ja käyttö olion kautta 4.1 Olion luominen luokasta Java-kielessä olio määritellään joko luokan edustajaksi tai taulukoksi. Olio on joukko keskusmuistissa olevia tietoja. Oliota käsitellään

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 4 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten lauseisiin, lausekkeisiin ja aliohjelmiin liittyvät kysymykset. Tehtävä 1. Mitä

Lisätiedot

14. oppitunti. Operaattorin ylikuormitus. Osa. Operaattorin ylikuormittaminen

14. oppitunti. Operaattorin ylikuormitus. Osa. Operaattorin ylikuormittaminen Osa IV 14. oppitunti Operaattorin ylikuormitus Edellisessä luvussa opit ylikuormittamaan metodeita ja luomaan kopiomuodostimen, joka tekee syvän kopion. Tässä luvussa käsitellään seuraavia aiheita: Kuinka

Lisätiedot

3. Muuttujat ja operaatiot 3.1

3. Muuttujat ja operaatiot 3.1 3. Muuttujat ja operaatiot 3.1 Sisällys Imperatiivinen laskenta. Muuttujat. Nimi ja arvo. Muuttujan nimeäminen. Muuttujan tyyppi. Operaattorit. Operandit. Arvon sijoitus muuttujaan. Aritmeettiset operaattorit.

Lisätiedot

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4) 2. Lisää Java-ohjelmoinnin alkeita Muuttuja ja viittausmuuttuja Vakio ja literaalivakio Sijoituslause Syötteen lukeminen ja Scanner-luokka 1 Muuttuja ja viittausmuuttuja (1/4) Edellä mainittiin, että String-tietotyyppi

Lisätiedot

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes) Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes) Kääreluokista Javan alkeistietotyypit ja vastaavat kääreluokat Autoboxing Integer-luokka Double-luokka Kääreluokista Alkeistietotyyppiset muuttujat (esimerkiksi

Lisätiedot

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.

Luokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista. 1 Luokka Murtoluku uudelleen Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista. Sievennettäessä tarvitaan osoittajan ja nimittäjän suurin yhteinen tekijä (syt).

Lisätiedot