Operaattoreiden uudelleenmäärittely

Koko: px
Aloita esitys sivulta:

Download "Operaattoreiden uudelleenmäärittely"

Transkriptio

1 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 tapaan. Olemme jo nähneet, kuinka luokillamme voi olla jäsenfunktioita, jotka käsittelevät olion jäsenmuuttujia - voimme ajatella tätä lauseella jäsenfunktio käsittelee olioita, joihin sillä on pääsy - mutta voimme tehdä tämän lisäksi paljon muutakin. Operaattoreiden uudelleenmäärittelyn avulla voit toteuttaa C++:n perusoperaattorit hyvin määritellyllä tavalla omille luokillesi. Tässä luvussa käsittelemme seuraavia aiheita: Mitä C++:n operaattoreita voit toteuttaa omille tietotyypeillesi Miten luokillesi toteutetaan funktioita, jotka uudelleenmäärittelevät operaattorit Miten operaattorifunktiot toteutetaan luokan jäseninä ja tavallisina funktioina Milloin sijoitusoperaattori on pakko toteuttaa Miten tyypinmuunnokset toteutetaan operaattorifunktioina Mitä ovat fiksut osoittimet Operaattoreiden toteutus luokille Laatikko-luokkamme suunniteltiin siten, että se soveltuu sovellukselle, joka on pääasiassa kiinnostunut laatikon tilavuuksista. Tällaiselle sovellukselle on tärkeää pystyä vertaamaan laatikoiden tilavuuksia. Luvussa 12 toteutimme Laatikko-luokalle vertaatilavuuksia()-funktion, joka vertasi kahden olion tilavuuksia, mutta eikö olisikin hienoa, jos voisit kirjoittaa: if(ltk1 < Ltk2) // Tee jotain... seuraavanlaisen, varsin kömpelön funktiokutsun sijaan: if(ltk1.vertaatilavuuksia(ltk2) < 0) // Tee jotain

2 C++ Ohjelmoijan käsikirja! Haluaisit varmastikin laskea yhteen kahden Laatikko-olion tilavuudet lausekkeella Ltk1 + Ltk2 tai jopa valita kolmas laatikko Laatikko-olioiden listasta lausekkeella kuorma1[2]. No, kaikki tämä ja paljon muutakin on mahdollista - sinun tulee vain kirjoittaa koodi, joka toteuttaa haluamasi toiminnon. Tämä voidaan tehdä C++:n operaattoreiden uudelleenmäärittelyn avulla. Operaattoreiden uudelleenmäärittely Operaattoreiden uudelleenmäärittelyn avulla voit käyttää standardioperaattoreita (kuten +, -, *, < ja niin edelleen) omien tyyppiesi mukaisten olioiden kanssa. Tämän voit tehdä kirjoittamalla funktion, joka määrittelee uudelleen tietyn operaattorin, jotta se suorittaa tietyn toiminnon aina, kun sitä käytetään luokkasi olioiden kanssa. Jos esimerkiksi haluat määrätä, miten <-operaattorin tulee toimia Laatikko-olioiden yhteydessä, voit kirjoittaa Laatikko-luokalle jäsenfunktion, joka määrittelee operaattorin toiminnan. Meidän tapauksessamme olemme kiinnostuneita Laatikko-olioiden tilavuuksista - eli voimme kirjoittaa funktion, joka palauttaa true, jos ensimmäisen Laatikko-olion tilavuus on pienempi kuin toisen olion. Tällaisen funktion nimi olisi tässä tapauksessa operator<(). Yleisesti ottaen, tietyn operaattorin uudelleenmäärittelevän funktion nimi koostuu avainsanasta operator, jonka perässä on uudelleenmääriteltävä operaattori. Operaattoreiden, joiden nimi muodostuu kirjaimista, kuten new ja delete, ja avainsanan välillä tulee olla vähintään yksi tyhjä merkki. Muiden operaattoreiden kohdalla tyhjä merkki on vapaaehtoinen. Operaattorit, jotka voidaan uudelleenmääritellä Operaattoreiden uudelleenmäärittelyn avulla et voi keksiä uusia operaattoreita. Et myöskään voi muuttaa operaattoreiden suoritusjärjestystä ja operandien lukumäärää, joten operaattorin uudelleenmääritellyllä versiolla on sama suoritusjärjestys kuin alkuperäisellä operaattorillakin. Kaikkien operaattoreiden suoritusjärjestyksen löydät liitteestä D. Vaikka et voikaan määritellä kaikkia operaattoreita uudelleen, rajoitukset eivät ole kovinkaan suuret. Seuraavassa on operaattorit, joita et voi määritellä uudelleen: Näkyvyysalueoperaattori :: Ehto-operaattori?: Suora jäsenen käsittelyoperaattori. 534 Osoitin jäseneen -operaattori.* sizeof-operaattori sizeof Emme ole vielä tavanneet osoitin jäseneen -operaattoria, mutta käsittelemme sitä luvussa 16. Lisäksi et voi määritellä uudelleen esikääntäjäkomennon symbolia # tai ##-symbolia. Kaikki muu on vapaasti määriteltävissä. Kuten tulemme huomaamaan, luokan tietyn operaattorin uudelleenmäärittelevän funktion ei välttämättä tarvitse olla luokan jäsen - se voi olla tavallinenkin funktio. Näemme esimerkkejä molemmista.

3 Operaattoreiden uudelleenmäärittely On sanomattakin selvää, että versiosi standardioperaattorista tulisi vastata operaattorin normaalia käyttötilannetta niin pitkälle kuin luokka antaa siihen mahdollisuuden. Ei olisi kovinkaan järkevää määritellä luokalle +-operaattoria uudelleen siten, että se suorittaa operandiolioidensa kertolaskun. Paras tapa ymmärtää operaattorin uudelleenmäärittelyn toiminta, on käydä läpi esimerkki, joten toteutetaan edellä jo käsittelemämme <-operaattori Laatikko-luokalle. Uudelleenmääritellyn operaattorin toteutus Määritelläksemme luokalle operaattorin, kirjoitamme yksinkertaisesti operaattorifunktion. Binäärisellä operaattorilla, joka toteutetaan luokan jäsenenä, on yksi parametri. Palaamme tähän hetken kuluttua. Voimme lisätä seuraavan funktion, joka määrittelee uudelleen <-operaattorin, prototyypin Laatikko-luokan määrittelyyn: class Laatikko public: bool operator<(const Laatikko& altk) const; //Uudelleenm. pienempi kuin ; // Laatikko-luokan loput määrittelyt Koska toteutamme vertailua, paluuarvon tyyppi on bool. Operaattorifunktiotamme operator<() kutsutaan, kun kahta Laatikko-oliota vertaillaan <-operaattorilla. Parametri on <-operaattorin oikeanpuoleinen operandi ja vasemmanpuoleinen vastaa this-osoitinta. Koska funktio ei muuta kumpaakaan operandia, olemme määritelleet parametrin ja funktion const-tyyppisiksi. Jotta näemme miten tämä toimii, oletetaan, että meillä on seuraava if-lause: if(ltk1 < ltk2) cout << ltk1 on pienempi kuin ltk2 << endl; Sulkeiden sisällä olevan testilausekkeen arvo on funktiomme paluuarvo. Se vastaa funktion kutsua ltk1.operator<(ltk2). Itse asiassa, jos haluat, voit kirjoittaa lausekkeen myös tällä tavalla: if(ltk1.operator<(ltk2)) cout << ltk1 on pienempi kuin ltk2 << endl; Kuten huomaat operator<-funktion käyttö tekee koodista luettavampaa. Kun nyt tiedämme, miten lausekkeen ltk1 < ltk2 operandit sidotaan funktion kutsuun, voimme toteuttaa uudelleenmääritellyn funktion varsin helposti. Jäsenfunktion, joka määrittelee uudelleen <-operaattorin, määrittely näkyy seuraavan sivun kaaviossa. 535

4 C++ Ohjelmoijan käsikirja if( ltk1 < ltk2 ) this-osoittimen osoittama olio Operaattorifunktion parametri bool Laatikko::operator<(const Laatikko& altk) const return this->tilavuus() < altk.tilavuus();! Käytämme viittausparametriä välttääksemme tarpeettoman parametrin kopioinnin funktion kutsun yhteydessä. return-lauseke käyttää jäsenfunktiota tilavuus() this-osoittimella osoitetun Laatikko-olion tilavuuden laskentaan ja vertaa tulosta (tavallisella <-operaattorilla) altk-olion tilavuuteen. Eli boolean-arvo true palautetaan, jos this-osoittimen osoittama Laatikko-olio on tilavuudeltaan pienempi kuin viittauksena välitetty altk-olio - ja false muulloin. Tässä this-osoitinta käytettiin näyttämään yhteys ensimmäiseen operandiin. thisosoitinta ei tarvitse käyttää eksplisiittisesti. Kokeile itse - Uuudelleenmääritellyn <-operaattorin käyttö Kokeillaan Laatikko-olion uudelleenmääriteltyä pienempi kuin -operaattoria. Laatikko-luokan määrittely on otsikkotiedostossa Laatikko.h ja sisältää uudelleenmääritellyn operaattorifunktion operator<() määrittelyn: // Laatikko.h - Laatikko-luokan määrittely #ifndef LAATIKKO_H #define LAATIKKO_H class Laatikko public: //Muodostinfunktio Laatikko(double apituus = 1.0, double asyvyys = 1.0, double akorkeus = 1.0); double tilavuus() const; // Laskee laatikon tilavuuden double luepituus() const; double luesyvyys() const; double luekorkeus() const; inline bool operator<(const Laatikko& altk) const //Uudelleenm. pienempi kuin //Määritellään avoimeksi return tilavuus() < altk.tilavuus(); 536

5 Operaattoreiden uudelleenmäärittely private: double pituus; double syvyys; double korkeus; ; #endif Huomaa, että olemme määritelleet uudelleenmääritellyn operaattorin avoimeksi funktioksi, koska se on tehokkaampi sellaisena. Otsikkotiedostossa on lisäksi Laatikko-luokan muiden jäsenten prototyypit. Määrittelyt ovat Laatikko.cpp-tiedostossa: // Laatikko.cpp Laatikko-luokan toteutus #include "Laatikko.h" // Muodostinfunktio Laatikko::Laatikko(double apituus, double asyvyys, double akorkeus): pituus(apituus), syvyys(asyvyys), korkeus(akorkeus) // 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; Vertailuoperaattorin uudelleenmäärittelyn jälkeen emme enää tarvitse vertaatilavuuksia()- jäsentä, joten olemme poistaneet sen. Testaamme <-operaattoria etsimällä Laatikko-olioiden taulukon suurimman alkion. Tässä on ohjelman koodi: // Esimerkki Uudelleenmääritellyn pienempi kuin -operaattorin käyttö #include <iostream> #include <cstdlib> // Satunnaislukugeneraattoria varten #include <ctime> // time-funktiota varten using namespace std; #include "Laatikko.h" // Funktio, joka generoi satunnaisluvun 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)); const int ltklkm = 20; Laatikko laatikot[ltklkm]; // Laatikon mittojen yläraja // Alustetaan satunnaislukugeneraattori // Taulukon alkioiden lukumäärä // Laatikko-olioiden taulukko 537

6 C++ Ohjelmoijan käsikirja for(int i = 0 ; i < ltklkm ; i++) laatikot[i] = Laatikko(satunnaisluku(dimRaja), satunnaisluku(dimraja), satunnaisluku(dimraja)); // Etsitään taulukon suurin laatikko laatikko* psuurin = &laatikot[0]; for(int i = 1 ; i < ltklkm ; i++) if(*psuurin < laatikot[i]) psuurin = &laatikot[i]; cout << endl << "Suurimman laatikon mitat ovat: " << psuurin->luepituus() << " * " << psuurin->luesyvyys() << " * " << psuurin->luekorkeus() << endl; return 0; Kun suoritan ohjelman, se tulostaa: Suurimman laatikon mitat ovat: 78 * 78 * 98 Koska tässä käytetään satunnaislukuja, saat mitä todennäköisimmin erilaisen tuloksen. Kuinka se toimii main()-funktio luo ensin Laatikko-olioiden taulukon. Oletamme aluksi, että taulukon ensimmäinen alkio on suurin ja talletamme sen osoitteen lauseella: laatikko* psuurin = &laatikot[0]; Tämän jälkeen vertaamme osoitteessa psuurin olevaa Laatikko-oliota jokaiseen taulukon seuraavaan alkioon: for(int i = 1 ; i < ltklkm ; i++) if(*psuurin < laatikot[i]) psuurin = &laatikot[i]; if-lauseen vertailussa kutsutaan operator<() funktiotamme. Funktion parametri on laatikot[i] ja this-osoitin osoittaa osoittimen psuurin osoittamaan Laatikko-olioon. Jos laatikot[i]:n tilavuus on suurempi kuin psuurin osoittaman laatikon tilavuus, vertailun tulos on true ja talletamme laatikot[i]:n osoitteen uutena suurimpana Laatikko-oliona. Käytämme tässä osoitinta, koska se on huomattavasti tehokkaampi kuin toinen vaihtoehto: Laatikko suurin = laatikot[0]; for(int i = 1 ; i < ltklkm ; i++) if(suurin < laatikot[i]) suurin = laatikot[i]; // Kopioi taulukon olion 538 Tässä koodissa on ylimääräistä hidastetta verrattuna alkuperäiseen. Joka kerta, kun Laatikkoolio talletetaan silmukassa muuttujaan suurin, laatikot-taulukon olio tulee kopioida suurinolioon jäsen jäseneltä. Se, kuinka kauan tähän kopiointiin menee aikaa, riippuu olion monimutkaisuudesta. Osoitinta käytettäessä ainoastaan osoite kopioidaan.

7 Operaattoreiden uudelleenmäärittely Kun silmukan suoritus päättyy, osoittimessa psuurin on taulukon suurimman Laatikko-olion osoite, joten voimme tulostaa suurimman olion mitat osoittimen avulla: cout << endl << "Suurimman laatikon mitat on: " << psuurin->luepituus() << " * " << psuurin->luesyvyys() << " * " << psuurin->luekorkeus() << endl; Globaalit operaattorifunktiot Funktio tilavuus() on Laatikko-luokan julkinen jäsen, joten voimme toteuttaa <-operaattorin tavallisena funktiona - globaalina operaattorifunktiona - luokan ulkopuolella. Tällöin funktion määrittely näyttää seuraavalta: inline bool operator<(const Laatikko& Ltk1, const Laatikko& Ltk2) return Ltk1.tilavuus() < Ltk2.tilavuus(); Olemme esitelleet operator<()-funktion avoimeksi funktioksi, koska haluamme, että se käännetään sellaiseksi, jos se vain on mahdollista. Kun operaattori on määritelty tällä tavalla, edellisen esimerkin main()-funktion koodi toimii täsmälleen samaan tapaan. Tätä versiota ei tietenkään tule esitellä const-tyyppiseksi - const-määrettä voidaan soveltaa vain luokan jäsenfunktioihin. Kun määrittelet jäsenfunktion const-tyyppiseksi, kerrot kääntäjälle, että se ei muuta oliota, josta funktiota kutsuttiin - eli const koskee tässä tapauksessa oliota, johon funktio kuuluu. Vaikka operaattorifunktion tulisi päästä käsiksi luokan yksityisiin jäseniin, se voidaan toteuttaa tavallisena funktiona, jos se esitellään luokan ystäväfunktiona. Yleisesti ottaen, jos funktion täytyy päästä käsiksi luokan yksityisiin jäseniin, suositeltavampi tapa on määritellä se luokan jäseneksi. Operaattorin täydellinen toteuttaminen! Operaattorin, kuten <, toteuttaminen luokalle saa aikaan tiettyjä odotuksia. Voit kirjoittaa lausekkeita kuten Ltk1 < Ltk2, mutta entäpä lausekkeet Ltk1 < 25.0 tai 10 < Ltk2? Operaattorifunktiomme operator<() ei pysty käsittelemään kumpaakaan näistä. Kun suunnittelet toteuttavasi uudelleenmääritellyn operaattorin funktiolle, tulee sinun miettiä todennäköiset tilanteet, joissa operaattori tullaan käyttämään. Kun käytämme alkuperäistä <-operaattoria esimerkiksi vertailtaessa float-tyyppistä ja int-tyyppistä arvoa keskenään, kääntäjä muuntaa toisen operandin tyypin samaksi kuin toinen operandi ennen vertailun toteuttamista - ja alkuperäinen <- operaattori on määritelty uudelleen vertaamaan kahta saman tyyppistä tietoa. Yllä kuvattu tilanne on hieman erilainen - meidän tulee määritellä <-operaattori uudelleen siten, että yllä mainittu vertailu on järkevä. 539

8 C++ Ohjelmoijan käsikirja Voimme varsin helposti tukea edellä mainittuja lausekkeita. Lisätään ensiksi funktio, joka vertailee Laatikko-olion tilavuutta (Laatikko-olio on ensimmäinen operandi) toiseen operandiin, joka on double-tyyppinen. Määrittelemme sen avoimeksi funktioksi luokan ulkopuolelle - ihan vain, jotta näemme miten se voidaan tehdä. Meidän tulee lisätä seuraava prototyyppi Laatikkoolion public-osaan: bool operator<(double aarvo) const; //Vertaa Laatikon tilavuus < double-arvo Laatikko-olio välitetään funktiolle implisiittisellä this-osoittimella ja double-arvo välitetään parametrinä. Tämän funktion toteutus on yhtä helppo kuin ensimmäisen operaattorifunktionkin - sen rungossa on vain yksi lause: // Funktio, joka vertaa Laatikko-oliota vakioon inline bool Laatikko::operator<(double aarvo) const return tilavuus() < aarvo;! Tämän määrittelyn tulee olla yhteneväinen luokan esittelyyn otsikkotiedostossa Laatikko.h. Avointa funktiota ei tule määritellä erillisessä.cpp-tiedostossa, koska sen määrittelyn tulee olla jokaisessa sitä käyttävässä lähdetekstitiedostossa. Sijoittamalla se luokan määrittelyyn varmistetaan, että näin aina on. Lausekkeen 10 < ltk2 käsittely ei ole sen vaikeampaa; se on vain hieman erilainen. Operaattorifunktio, joka on luokan jäsen, käyttää aina this-osoitinta vasempana operandina. Koska vasen operandi on tässä tapauksessa double-tyyppinen, emme voi toteuttaa operaattoria jäsenfunktiona. Jäljelle jää kaksi vaihtoehtoa: funktion toteuttaminen globaalina operaattorifunktiona tai ystäväfunktiona. Koska meidän ei tarvitse päästä käsiksi luokan yksityisiin jäseniin, voimme toteuttaa sen tavallisena funktiona: // Funktio, joka vertaa vakiota Laatikko-olioon inline bool operator<(const double aarvo, const Laatikko& altk) return aarvo < altk.tilavuus(); Nyt meillä on kolme uudelleenmääriteltyä versiota <-operaattorista Laatikko-oliota varten. Eli voimme nyt käsitellä lausekkeen ltk1 < ltk2 lisäksi esimerkiksi lausekkeita ltk1 < 2.5 * ltk2.tilavuus() tai jopa 0.5 * (ltk1.tilavuus() + ltk2.tilavuus()) < ltk3. Kumpikin <- operaattorin operandi voi olla lauseke, jonka arvo on tyyppiä double tai Laatikko-olio. 540

9 Kokeile itse - Operaattorin < täydellinen uudelleenmäärittely Operaattoreiden uudelleenmäärittely Voimme yhdistää kaiken edellä olleen esimerkiksi. Operaattorifunktion lisäksi lisäämme Laatikko-luokkaan funktion, joka tulostaa olion mitat. Tämä tekee main()-funktion koodista kompaktimman. Poistamme ensin esimerkin 14.1 Laatikko.h-tiedostosta vanhan operator<()- funktion ja lisäämme seuraavat prototyypit luokan määrittelyn julkiseen osaan: bool operator<(const Laatikko& altk) const; bool operator<(const double aarvo) const; // Vertailee Ltk < Ltk // vertailee Ltk < double-arvo Sitten lisäämme seuraavat avointen funktioiden määrittelyt Laatikko.cpp-tiedostoon: // Funktio, joka vertaa Laatikko-olio < Laatikko-olio inline bool Laatikko::operator<(const Laatikko& altk) const return tilavuus() < altk.tilavuus(); // Funktio, joka vertaa Laatikko-olio < double-arvo inline bool Laatikko::operator<(const double aarvo) const return tilavuus() < aarvo; Lopuksi lisäämme globaalin operaattorifunktion määrittelyn Laatikko.h-tiedoston loppuun: // Funktio, joka vertaa double-arvo < Laatikko-olio inline bool operator<(const double aarvo, const Laatikko& altk) return aarvo < altk.tilavuus(); Nämä kolme operaattorifunktion määrittelyä tulee sijoittaa Laatikko-luokan määrittelyn ja #endif-komennon väliin. Olemme sijoittaneet kaikkien operaattorifunktioiden määrittelyt otsikkotiedostoon Laatikko.h, koska ne ovat kaikki avoimia funktioita. Ainoastaan sellaisten jäsenfunktioiden, jotka eivät ole avoimia, määrittelyt tulee kirjoittaa.cpp-tiedostoon. Tästä syystä tämän esimerkin Laatikko.cpp-tiedosto on sama kuin esimerkissä Voimme käyttää uusia operaattoreita, kun etsimme taulukon kaikki Laatikko-oliot, joiden tilavuus on tiettyjen rajojen sisällä. Tässä on koodi: // Esimerkki Uudelleenmääriteltyjen pienempi kuin -operaattoreiden testaus #include <iostream> #include <cstdlib> // Satunnaislukugeneraattoria varten #include <ctime> // time-funktiota varten using namespace std; #include "Laatikko.h" // Funktio, joka generoi satunnaisluvun väliltä 1 - lkm inline int satunnaisluku(int lkm) return 1 + static_cast<int>((lkm*static_cast<long>(rand()))/(rand_max+1)); 541

10 C++ Ohjelmoijan käsikirja // Tulostetaan laatikon mitat void nayta(const Laatikko& altk) cout << endl << altk.luepituus() << " * " << altk.luesyvyys() << " * " << altk.luekorkeus(); int main() const int dimraja = 100; srand((unsigned)time(0)); const int ltklkm = 20; Laatikko laatikot[ltklkm]; // Laatikon mittojen yläraja // Alustetaan satunnaislukugeneraattori // Taulukon alkioiden lukumäärä // Laatikko-olioiden taulukko for(int i = 0 ; i < ltklkm ; i++) laatikot[i] = Laatikko(satunnaisluku(dimRaja), satunnaisluku(dimraja), satunnaisluku(dimraja)); // Etsitään taulukon suurin laatikko Laatikko* psuurin = &laatikot[0]; for(int i = 1 ; i < ltklkm ; i++) if(*psuurin < laatikot[i]) psuurin = &laatikot[i]; cout << endl << "Taulukon suurimman laatikon mitat on:"; nayta(*psuurin); int tilmin = ; // Alaraja laatikon tilavuudelle int tilmax = ; // Yläraja laatikon tilavuudelle // Tulostetaan rajojen välissä olevien Laatikko-olioiden mitat cout << endl << endl << "Laatikot, joiden tilavuus on välillä " << tilmin << " ja " << tilmax << " ovat:"; for(int i = 0 ; i < ltklkm ; i++) if(tilmin < laatikot[i] && laatikot[i] < tilmax) nayta(laatikot[i]); cout << endl; return 0; Kun suoritan ohjelman, saan tulostukseksi: Taulukon suurimman laatikon mitat on: 96 * 87 * Laatikot, joiden tilavuus on välillä ja ovat: 96 * 30 * * 100 * * 32 * * 72 * * 57 * 88

11 Operaattoreiden uudelleenmäärittely Kuinka se toimii Funktio nayta() tulostaa sille välitetyn Laatikko-olion mitat. Se on apufunktio, jota käytämme main()-funktiossa. main()-funktion alkuosassa luomme Laatikko-olioiden taulukon ja etsimme taulukon suurimman tilavuuden omaavan Laatikko-olion, kuten ennenkin. Tässä käytämme alkuperäistä versiota operator<()-funktiosta, jonka määrittelimme Laatikko-luokan jäseneksi. Käytämme kahta uutta operaattorifunktiotamme koodissa, joka tulostaa niiden Laatikko-olioiden mitat, joiden tilavuus on välillä tilmin ja tilmax: for(int i = 0 ; i < ltklkm ; i++) if(tilmin < laatikot[i] && laatikot[i] < tilmax) nayta(laatikot[i]);! if-lauseessa kutsutaan kumpaakin uusista operaattorifunktioista. Alilauseke tilmin < laatikot[i] vastaa funktion operator<(tilmin, laatikot[i]) kutsua ja laatikot[i] < tilmax vastaa jäsenfunktion kutsua laatikot[i].operator < (tilmax). Tulostaaksemme Laatikko-olion mitat, jotka täyttävät ehdot, välitämme sen yksinkertaisesti nayta()-funktiolle. Kaikki vertailuoperaattorit voidaan toteuttaa vastaavalla tavalla kuin olemme tässä toteuttaneet pienempi kuin -operaattorin. Ne eroavat vain pieniltä yksityiskohdiltaan; yleisellä tasolla ne ovat kaikki samanlaisia. Erilaiset operaattorifunktiot Kaikkien niiden operaattoreiden, jotka voidaan määritellä uudelleen, operaattorifunktiot ovat saman mallisia kuin olemme edellä nähneet. Kun operaattori X määritellään uudelleen ja vasen operandi on olio, jolle X määritellään uudelleen, operaattorin uudelleenmäärittelevä jäsenfunktio on muotoa: Paluuarvon_tyyppi operator X(Tyyppi OikeaOperandi); Paluuarvon_tyyppi riippuu siitä, mitä operaattori tekee. Vertailuoperaattoreiden ja loogisten operaattoreiden kohdalla se on yleensä bool (voit myös käyttää tyyppiä int). Operaattoreiden, kuten + ja *, tulee palauttaa jonkinlainen olio, kuten tulemme huomaamaan. Kun toteutat binäärisen operaattorin ei-jäsenfunktiolla, sen muoto on: Paluuarvon_tyyppi operator X(Luokan_tyyppi VasenOperandi, Tyyppi OikeaOperandi); Tässä Luokan_tyyppi on luokka, jolle määrittelet uudelleen operaattorin X. Jos binäärisen operaattorin vasenta operandia, tyyppiä Tyyppi, ei ole määritelty luokan Tyyppi jäsenenä, se tulee määritellä globaalina operaattorifunktiona: Paluuarvon_tyyppi operator X(Tyyppi VasenOperandi, Tyyppi OikeaOperandi); 543

12 C++ Ohjelmoijan käsikirja Kun toteutat unaarisen operaattorin luokan jäsenenä, se ei tarvitse yleensä parametriä - lisäys- ja vähennysoperaattorit ovat poikkeus tähän, kuten tulemme huomaamaan. Esimerkiksi yleisen operaattorifunktion muoto on: Luokka_tyyppi& operator Op(); Globaaleina operaattorifunktioina toteutetuilla unaarisilla operaattoreilla on yksi parametri. Kuten muiden kuin jäsenfunktioidenkin kohdalla, unaarisen Op-operaattorin operaattorifunktio voidaan toteuttaa seuraavasti: Luokka_tyyppi& operator Op(Luokka_Tyyppi&); Huomaa, että kaikkien operaattorifunktioiden - sekä jäsenfunktioiden että globaalien funktioiden - parametrien lukumäärä on kiinteä. Parametrien määrä määräytyy kyseisen operaattorin operandien lukumäärän mukaan. Emme käy esimerkeillä läpi kaikkien operaattoreiden uudelleenmäärittelyä, koska monet niistä ovat samankaltaisia kuin olemme jo nähneet. Käymme kuitenkin läpi sellaiset operaattorit, joissa on erityisesti käsiteltäviä asioita. Sijoitusoperaattorin uudelleenmäärittely Sijoitusoperaattorilla tarkoitamme =-operaattoria, jotta erotamme sen operaattoreista +=, *= ja niin edelleen. Sijoitusoperaattori kopioi tietyn tyyppisen olion (sijoitusoperaattorin oikealla puolella olevan) toiseen samantyyppiseen olioon (vasemmalla puolella olevaan). Sijoitusoperaattoria kutsutaan, kun kirjoitat: Laatikko ltk1; Laatikko ltk2(10, 10, 10); ltk1 = ltk2; //Kutsutaan sijoitusoperaattoria Jos et itse toteuta luokallesi uudelleenmääriteltyä sijoitusoperaattoria, kääntäjä muodostaa oletusversion operator=(). On mielenkiintoista tutkia, mitä tapahtuu, jos määrittelet hyvin yksinkertaisen luokan - esimerkiksi luokan, jossa on vain yksi jäsenmuuttuja: class Data public: int arvo; ; Riippuen siitä, miten luokkaa käytät, todellisuudessa luokka näyttää seuraavalta: class Data public: int arvo; 544

13 Operaattoreiden uudelleenmäärittely ; Data() ~Data() Data(const Data& adata) : arvo(adata.arvo) Data& operator=(const Data& adata) arvo = adata.arvo; return *this; // Oletusmuodostinfunktio // Tuhoajafunktio // Kopiomuodostin // Sijoitusoperaattori Sijoitusoperaattorin oletusversio suorittaa yksinkertaisen jäsen jäseneltä -prosessin, samaan tapaan kuin oletuskopiomuodostinkin. Älä sekoita kopiomuodostinta ja sijoitusoperaattoria - ne ovat eri. Kopiomuodostinta kutsutaan, kun luodaan uusi olio, joka alustetaan olemassa olevan saman luokan oliolla tai kun olio välitetään funktiolle arvoparametrinä. Sijoitusoperaattoria kutsutaan, kun sijoitusoperaattorin vasemmalla ja oikealla puolella on samantyyppiset oliot. Laatikko-luokkamme kohdalla oletussijoitusoperaattori toimii oikein, mutta kaikkien sellaisten luokkien kohdalla, joiden jäsenille on varattu muistia dynaamisesti, asiaan tulee paneutua tarkemmin. On suuren virheen paikka ohjelmassasi, jos et tällöin määrittele sijoitusoperaattoria uudelleen. Ongelmat ovat samantyyppisiä kuin kopiomuodostimenkin kohdalla. Oletetaan, että käytämme oletussijoitusoperaattoria olioille, joilla on dynaamisesti varattua muistia. Tuloksena on, että kaksi oliota jakaa samat vapaan muistin oliot, joten jos muutamme toista oliota, toisen olion eheys saattaa rikkoontua. AutoKuorma-luokka on juuri tällainen. Jäsen jäseneltä -kopioinnin tuloksena molemmat oliot jakavat saman listan; tämän ongelmanhan ratkaisimme jo luvussa 13. Ratkaisu oli yksinkertainen: toteutetaan sijoitusoperaattori siten, että olion dynaamiset osat kopioidaan asiallisesti. Tämä ei kuitenkaan pelkästään riitä, kuten tulemme huomaamaan. Itse asiassa, kaikilla luokilla, joilla on ongelmia oletuskopiomuodostimen kohdalla, on ongelmia myös oletussijoitusoperaattorin kohdalla. Jos toteutat näistä toisen, sinun tulee toteuttaa myös toinen - sekä tuhoajafunktio. Sijoitusoperaattorin toteuttaminen Katsotaan, mitä tällaisen funktion tulisi tehdä. Sijoituksessa on kaksi operandia: oikea operandi on kopioitava olio ja vasen operandi on kopioinnin kohde, joka muuttuu oikeanpuoleisen operandin kopioksi. Teemme kopioinnin operaattorifunktiossa, joten mikä on sen paluuarvon tyyppi? Tuleeko meidän palauttaa mitään? Katsotaan, miten funktiota käytetään käytännössä. Sijoitusoperaattorin normaalin toiminnan mukaan voimme kirjoittaa: kuorma1 = kuorma2 = kuorma3; 545

14 C++ Ohjelmoijan käsikirja Nämä kolme muuttujaa ovat AutoKuorma-typpiset ja teemme muuttujista kuorma1 ja kuorma2 muuttujan kuorma3 kopion. Koska sijoitusoperaattori on oikealta laskettava, tämä vastaa lausetta: kuorma1 = (kuorma2 = kuorma3); Jäsenfunktiolla operator=() kirjoitettuna tämä vastaa lausetta: kuorma1.operator=(kuorma2.operator=(kuorma3)); Tästä näkyy selvästi, että mitä tahansa funktio operator=() palauttaakin, se voi päätyä toisen operator=()-funktion parametriksi. Koska funktion operator=() parametri on viittaus olioon, voimme päätellä, että funktion tulee palauttaa vasemman operandin olio. Lisäksi, jos haluamme välttää turhan kopioinnin, paluuarvon tyypin tulee olla viittaus tähän olioon. Oikeanpuoleisen operandin kopiointi on samanlainen toiminto kuin käytimme kopiomuodostimessakin. Koska nyt tiedämme, mikä paluuarvon tyypin tulee olla, voimme yrittää tehdä =-operaattorin AutoKuorma-luokalle. Tarkastele ensin seuraavaa koodia; käsittelemme sen virheitä hetken kuluttua. AutoKuorma& AutoKuorma::operator=(const AutoKuorma& kuorma) palku = phanta = pnykyinen = 0; if(kuorma.palku == 0) return; Paketti* papu = kuorma.palku; do lisaaltk(papu->pltk); while(papu = papu->pseur); // talletetaan uuden listan osoitteet return *this; // Palautetaan vasen operandi this-osoitin sisältää vasemman operandin osoitteen, joten palauttamalla *this, palautamme tämän olion. Muutoin koodi on sama kuin olion kopiomuodostimessa. Funktio näyttää olevan OK ja toimiikin useimmissa tilanteissa, mutta siinä on kaksi ongelmaa. Ensimmäinen ongelma on vasen operandi. Se on AutoKuorma-olio, joka todennäköisesti sisältää listan. Asettamalla jäsenmuuttujan palku arvoksi 0, jätämme tuuliajolle kaikki tämän AutoKuorma-olion omistamat Paketti-oliot. Meidän tulee ensin poistaa kaikki vasemman operandin omistamat Paketti-oliot: AutoKuorma& AutoKuorma::operator=(const AutoKuorma& kuorma) while(pnykyinen = palku) // Kopioidaan ja testataan onko null palku = palku->pseur; // Siirretään palku osoittamaan seuraavaan olioon delete pnykyinen; // Poistetaan nykyinen olio 546 palku = phanta = pnykyinen = 0; if(kuorma.palku == 0) return;

15 Operaattoreiden uudelleenmäärittely Paketti* papu = kuorma.palku; do lisaaltk(papu->pltk); while(papu = papu->pseur); return *this; // talletetaan uuden listan osoitteet // Palautetaan vasen operandi Jos vasen operandi sisältää listan, palku ei ole null. while-silmukka tallettaa osoittimen listan ensimmäiseen Paketti-olioon ja tarkistaa onko se null. Jos se ei ole null, silmukan runko suoritetaan, jolloin palku siirretään osoittamaan listan seuraavaan Paketti-olioon ja nykyinen listan alku poistetaan. Näin käymme koko listan läpi ja poistamme yksi kerrallaan kaikki listan oliot, kunnes saavutamme null-osoittimen. Tämä huolehtii vasemmasta operandista, mutta jäljellä on yhä yksi ongelma. Oletetaan, että joku kirjoittaa lauseen: kuorma1 = kuorma1; Tämä ei kylläkään näytä kovinkaan järkevältä sijoitukselta, mutta tällainen tilanne saattaa hyvinkin syntyä monimutkaisemman lausekkeen tuloksena, jolloin tällaisen lopullisen sijoituksen saaminen ei ole niin selvästi näkyvissä. Tällöin, ensimmäisen ongelman ratkaisu poistaa olion listan, jonka jälkeen yritämme kopioida listan, jota ei ole enää olemassa! Meidän täytyy tarkistaa, ovatko molemmat operandit samat. Tämän voimme tehdä seuraavilla muutoksilla: AutoKuorma& AutoKuorma::operator=(const AutoKuorma& kuorma) if(this == &kuorma) // Verrataan operandien osoitteita return *this; // Jos samat, palautetaan 1. operandi while(pnykyinen = palku) // Kopioidaan ja testataan onko null palku = palku->pseur; // Siirretään palku osoittamaan seuraavaan olioon delete pnykyinen; // Poistetaan nykyinen olio palku = phanta = pnykyinen = 0; if(kuorma.palku == 0) return; Paketti* papu = kuorma.palku; do lisaaltk(papu->pltk); while(papu = papu->pseur); return *this; // talletetaan uuden listan osoitteet // Palautetaan vasen operandi Jos molemmat operandit ovat samat, niiden osoitteet ovat samat, joten osoittimen this ja funktiolle operator=() välitetyn parametrin vertailu riittää. Aina, kun teet sijoitusoperaattorin, sinun tulee tarkistaa, ovatko molemmat operandit samat. 547

16 C++ Ohjelmoijan käsikirja Voimme nyt laajentaa dynaamisten luokkiemme kultaista sääntöä, jota rupesimme kehittämään luvussa 13: Jos luokan funktiot varaavat muistia vapaasta muistista, toteuta luokalle aina kopiomuodostin, sijoitusoperaattori ja tuhoajafunktio. Voit määritellä sijoitusoperaattorin muuhunkin tehtävään kuin olion kopioimiseen. Yleisesti ottaen, luokallasi voi olla useita uudelleenmääriteltyjä sijoitusoperaattoreita. Lisäversioilla on luokan tyypistä poikkeava parametrin tyyppi - joten ne ovat todellisuudessa muunnoksia. Joka tapauksessa paluuarvon tyypin tulee olla vasemman operandin tyyppi. Voit tietysti määritellä uudelleen myös Op=-sijoitusoperaattorit. Monissa tapauksissa saatat haluta erikseen määritellä, että et salli tiettyjä sijoitusoperaatioita luokan olioille. Jos näin on, voit estää ne esittelemällä sijoitusoperaattorin luokan yksityisenä jäsenenä. Kokeile itse - Sijoitusoperaattorin toteuttaminen Rakennetaan pieni käytännön esimerkki, josta näemme, miten luokan oliot toimivat, jos niille on määritelty sijoitusoperaattori tai ei ole. Määrittelemme luokan VirheIlmoitus, joka kuvaa virheilmoitusta ja jolla on kopiomuodostin, sijoitusoperaattori ja tuhoajafunktio: // VirheIlmoitus.h #ifndef VIRHEILMOITUS_H #define VIRHEILMOITUS_H #include <iostream> using namespace std; class VirheIlmoitus public: VirheIlmoitus(const char* pteksti = "Virhe"); // Muodostinfunktio ~VirheIlmoitus(); // Tuhoajafunktio void resetilmoitus(); // Muuta ilmoitusta VirheIlmoitus& operator=(const VirheIlmoitus& Ilmoitus); // Sijoitusoperaattori char* mita() const return pilmoitus; // Tulostetaan ilmoitus private: char* pilmoitus; ; #endif 548 Koska tämä luokka varaa muistia dynaamisesti, sille tulee määritellä kopiomuodostin, sijoitusoperaattori ja tuhoajafunktio. Poistamalla sijoitusoperaattorin luokasta, huomaamme mitä tapahtuu, jos unohdamme toteuttaa sen. Muodostinfunktion, tuhoajafunktion ja muiden jäsenfunktioiden määrittelyt sijoitetaan VirheIlmoitus.cpp-tiedostoon:

17 Operaattoreiden uudelleenmäärittely // VirheIlmoitus.cpp VirheIlmoitus-luokan toteutus #include <cstring> #include "VirheIlmoitus.h" using namespace std; // Muodostinfunktio VirheIlmoitus::VirheIlmoitus(const char* pteksti) pilmoitus = new char[ strlen(pteksti) + 1 ]; // varataan muisti strcpy(pilmoitus, pteksti); // Kopioidaan // Tuhoajafunktio VirheIlmoitus::~VirheIlmoitus() cout << endl << "Tuhoajafunktiota kutsuttu." << endl; delete[] pilmoitus; // Vapautetaan muisti // Muutetaan viesti void VirheIlmoitus::resetIlmoitus() // Korvataan ilmoitus asteriskeilla for(char* apu = pilmoitus ; *apu!= '\0' ; *(apu++) = '*') ; // Sijoitusoperaattori VirheIlmoitus& VirheIlmoitus::operator=(const VirheIlmoitus& ilmoitus) if(this == &ilmoitus) // Verrataan osoitteita, jos samat return *this; // palautetaan vasen operandi delete[] pilmoitus; // Vapautettaan vasemman muisti pilmoitus = new char[ strlen(ilmoitus.pilmoitus) + 1]; // Kopioidaan oikean operandin merkkijono vasempaan operandiin strcpy(this->pilmoitus, ilmoitus.pilmoitus); return *this; // Palautetaan vasen operandi Käytämme tätä virheilmoitusluokan versiota seuraavanlaisessa ohjelmassa: // Esimerkki sijoitusoperaattorin uudelleenmäärittely #include <iostream> #include <cstring> using namespace std; #include "VirheIlmoitus.h" int main() VirheIlmoitus varoitus("tässä on nyt paha ongelma"); VirheIlmoitus standardi; 549

18 C++ Ohjelmoijan käsikirja cout << endl << "varoitus sisältää - " << varoitus.mita(); cout << endl << "standardi sisältää - " << standardi.mita(); standardi = varoitus; // Käytetään sijoitusoperaattoria cout << endl << "Varoituksen sijoittamisen jälkeen standardi sisältää - " << standardi.mita(); cout << endl << "Resetoidaan varoitus, ei standardia" << endl; varoitus.resetilmoitus(); // Resetoidaan varoitus cout << endl << "varoitus sisältää nyt - " << varoitus.mita(); cout << endl << "standardi sisältää nyt - " << standardi.mita(); cout << endl; return 0; Kun ohjelma suoritetaan tällaisenaan, se tulostaa: varoitus sisältää - Tässä on nyt paha ongelma standardi sisältää - Virhe Varoituksen sijoittamisen jälkeen standardi sisältää - Tässä on nyt paha ongelma Resetoidaan varoitus, ei standardia varoitus sisältää nyt - ************************* standardi sisältää nyt - Tässä on nyt paha ongelma Tuhoajafunktiota kutsuttu. Tuhoajafunktiota kutsuttu. Kuten huomaat, kaikki toimii niin kuin pitäisikin. Pystymme resetoimaan ensimmäisessä VirheIlmoitus-oliossa olevan ilmoituksen ilman, että toinen, kopioitu olio muuttuu. Poista tai kommentoi nyt sijoitusoperaattorin esittely luokan määrittelystä ja määrittely tiedostosta VirheIlmoitus.cpp. Käännä ohjelma uudelleen, ja se tulostaa nyt: varoitus sisältää - Tässä on nyt paha ongelma standardi sisältää - Virhe Varoituksen sijoittamisen jälkeen standardi sisältää - Tässä on nyt paha ongelma Resetoidaan varoitus, ei standardia varoitus sisältää nyt - ************************* standardi sisältää nyt - ************************* Tuhoajafunktiota kutsuttu. Tuhoajafunktiota kutsuttu. 550 Saatat saada muitakin virheilmoituksia, koska ohjelma yrittää vapauttaa muistin vapaasta muistista kahteen kertaan saman olion kohdalla.

19 Operaattoreiden uudelleenmäärittely Kuinka se toimii Esimerkin kiinnostava osa on sen erikoinen toiminta ilman sijoitusoperaattoria. main()-funktiossa luomme olion varoitus lauseella: VirheIlmoitus varoitus("tässä on nyt paha ongelma"); Tämä kutsuu VirheIlmoitus-luoka muodostinfunktiota merkkijono parametrinään merkkijono. Seuraavaksi luomme VirheIlmoitus-olion käyttämällä ilmoituksen oletusarvoa: VirheIlmoitus standardi; Kun olemme tulostaneet kummankin olion ilmoituksen, kutsumme VirheIlmoitus-luokan sijoitusoperaattoria lauseella: standardi = varoitus; // Käytetään sijoitusoperaattoria Ohjelman toisella suorituskerralla tässä kutsutaan oletussijoitusoperaattoria, jonka kääntäjä luo automaattisesti, joten molemmat pilmoitus-oliot sisältävät saman osoitteen. Tästä seuraa se, että kun muutamme varoitus-oliota lauseella varoitus.resetilmoitus(); // Resetoidaan varoitus muutammekin molempien olioiden yhteistä merkkijonoa - tulostuksesta näemme selvästi, että sekä varoitus-olion että standardi-olion merkkijonot ovat samat. Ohjelman lopussa kummankin VirheIlmoitus-olion näkyvyysalue päättyy ja niiden tuhoajafunktioita kutsutaan, kuten tulostuksesta näkyy. Tuhoajafunktion ensimmäisellä kutsukerralla vapautetaan pilmoitus-osoittimen osoittama muisti vapaasta muistista. Virheellisessä versiossa, kun toinen tuhoajafunktion kutsu suoritetaan, yritetään vapauttaa sama merkkijono uudelleen, koska molempien VirheIlmoitus-olioiden pilmoitus-osoitin osoittaa samaan osoitteeseen - järjestelmäsi saattaa muodostaa oman virheilmoituksensa. Ohjelman ensimmäisellä suorituskerralla, jolloin käytössä on erikseen toteutettu VirheIlmoitusluokan sijoitusoperaattori, luodaan itsenäinen kopio oikeanpuoleisesta operandista ja standardiolio ei muutu, kun muutamme varoitus-oliota. Kummankin olion pilmoitus-osoitin osoittaa eri merkkijonoihin, joten tuhoajafunktiossa ei tapahdu mitään virheellistä. Aritmeettisten operaattoreiden uudelleenmäärittely Katsotaan seuraavaksi, kuinka voimme uudelleenmääritellä Laatikko-luokallemme lisäysoperaattorin. Tämä on kiinnostava tapaus, sillä lisäys on binäärinen operaatio, jossa luodaan ja palautetaan uusi olio. Uusi olio on operaattorin operandeina olevien Laatikko-olioiden summa (tai miten ikinä operaattorin määrittelemmekin). Mitä haluamme summan tarkoittavan? On eri vaihtoehtoja, mutta koska laatikon päätarkoitus on jonkin säilöminen ja sen tilavuus kiinnostaa meitä eniten, voimme olettaa, että kahden laatikon summa on laatikko, johon mahtuu molemmat summatut laatikot. 551

20 C++ Ohjelmoijan käsikirja Tältä pohjalta voimme määritellä, että kahden Laatikko-olion summa on Laatikko-olio, johon mahtuu molemmat alkuperäiset laatikot päällekkäin asetettuina. Tämä määritelmä sopii myös ajatukseen, että luokkaamme käytetään paketoinnissa, koska lisäämällä halutun määrän Laatikko-olioita yhteen, tuloksena on Laatikko-olio, johon ne kaikki mahtuvat. Voimme tehdä tämän seuraavalla yksinkertaisella tavalla. Uuden olion pituus-jäsen on suurempi lisättävien olioiden pituus-jäsenistä. Syvyys-jäsen muodostetaan samaan tapaan. korkeus-jäsen on kahden operandin korkeus-jäsenten summa. Tällöin tuloksena olevaan laatikkoon mahtuu molemmat Laatikko-oliot. Muutamme muodostinfunktiota vielä niin, että Laatikko-olion pituus-jäsen on aina suurempi tai yhtä suuri kuin syvyys-jäsen. Seuraava kaavio havainnollistaa tuloksena olevaa Laatikko-oliota: pituus = 20 pituus = 25 syvyys = 15 syvyys = 10 korkeus = 7 ltk1 pituus = 25 korkeus = 14 ltk2 syvyys = 15 Box1 korkeus = 21 Box2 ltk1+ltk2 Koska lisäyksen tulos on uusi Laatikko-olio, lisäyksen toteuttavan funktion tulee palauttaa Laatikko-olio. Jos +-operaattorin uudelleenmäärittelevä funktio toteutetaan jäsenfunktiona, funktion esittely luokan Laatikko määrittelyssä näyttää seuraavalta: Laatikko operator+(const Laatikko& altk) const; //Lisätään kaksi laatikkoa Voimme määritellä parametrin const-tyyppiseksi, koska funktio ei muuta sitä, sekä viittaukseksi, jolloin vältämme oikean operandin tarpeettoman kopioinnin funktiota kutsuttaessa. Voimme määritellä myös funktion const-tyyppiseksi, koska se ei muuta vasenta operandiaan. Jäsenfunktion määrittely näyttäisi seuraavalta: 552 // Funktio, joka laskee yhteen kaksi Laatikko-oliota inline Laatikko Laatikko::operator+(const Laatikko& altk) const // Uudella oliolla on suurempi pituuksista ja syvyyksistä ja korkeuden summa return Laatikko( pituus > altk.pituus? pituus : altk.pituus, syvyys > altk.syvyys? syvyys : altk.syvyys, korkeus + altk.korkeus );

21 Operaattoreiden uudelleenmäärittely Huomaa erityisesti, että emme luo Laatikko-oliota vapaasta muistista kutsujalle palautuksen yhteydessä. Se olisi erittäin huono tapa toteuttaa funktio, koska muistin vapauttamisen suorittamisesta ei olisi täyttä varmuutta. Osoittimen palauttaminen vaikuttaisi myös muiden operaattoreiden, kuten operator=(), toteutukseen. Nyt funktiossa luodaan paikallinen Laatikkoolio, jonka kopio palautetaan kutsuvalle ohjelmalle. Koska nämä ovat automaattisia muuttujia, muistin hallinta suoritetaan automaattisesti. Kokeile itse - Lisäysoperaattorin uudelleenmäärittely Kokeillaan uutta lisäysoperaattoriamme esimerkin avulla. Lisäämme sen esimerkissä 14.2 käyttämäämme Laatikko-luokkaan. Meidän tulee lisätä uuden operaattorifunktion esittely Laatikko-luokan määrittelyn public-osaan Laatikko.h-tiedostossa: class Laatikko public: //Muodostinfunktio Laatikko(double apituus = 1.0, double asyvyys = 1.0, double akorkeus = 1.0); double tilavuus() const; // Laskee laatikon tilavuuden double luepituus() const; double luesyvyys() const; double luekorkeus() const; bool operator<(const Laatikko& altk) const; // Vertailee Ltk < Ltk bool operator<(const double aarvo) const; // vertailee Ltk < double-arvo Laatikko operator+(const Laatikko& altk) const; //Lisätään kaksi laatikkoa private: double pituus; double syvyys; double korkeus; ; Juuri näkemämme avoimen funktion operator+() määrittely tulee lisätä Laatikko.h-tiedostoon luokan määrittelyn perään. Muutamme Laatikko.cpp-tiedostossa olevaa muodostinfunktiota seuraavasti: Laatikko::Laatikko(double apituus, double asyvyys, double akorkeus) double maxsivu = apituus > asyvyys? apituus : asyvyys; double minsivu = apituus < asyvyys? apituus : asyvyys; pituus = maxsivu > 0.0? maxsivu : 1.0; syvyys = minsivu > 0.0? minsivu : 1.0; korkeus = akorkeus > 0.0? akorkeus : 1.0; Muodostinfunktiota muutettiin, jotta voidaan varmistua, että pituus-jäsen sisältää aina Laatikkoolion pidemmän mitan arvoista pituus ja syvyys. Tämä pitää oliot yhdenmukaisessa suunnassa, vaikka lisäysoperaattorimme tuottaakin näin erittäin pitkiä ja kapeita laatikoita. 553

22 C++ Ohjelmoijan käsikirja Kokeillaan lisäysoperaattoria yhdessä <-operaattorin kanssa. Etsimme taulukon Laatikkoolioiden parin, jonka tilavuus on pienin, kun ne lisätään toisiinsa. Taulukon kohdalla, jossa on 20 Laatikko-oliota, tämän tarkoittaa 380 parin tarkastamista. Seuraavassa on koodi: // Esimerkki Laatikko-olioiden lisäys #include <iostream> #include <cstdlib> // Satunnaislukugeneraattoria varten #include <ctime> // time-funktiota varten using namespace std; #include "Laatikko.h" // Funktio, joka generoi satunnaisluvun väliltä 1 - lkm inline int satunnaisluku(int lkm) return 1 + static_cast<int>((lkm*static_cast<long>(rand()))/(rand_max+1)); // Tulostetaan laatikon mitat void nayta(const Laatikko& altk) cout << endl << altk.luepituus() << " * " << altk.luesyvyys() << " * " << altk.luekorkeus(); int main() const int dimraja = 100; srand((unsigned)time(0)); const int ltklkm = 20; Laatikko laatikot[ltklkm]; // Laatikon mittojen yläraja // Alustetaan satunnaislukugeneraattori // Taulukon alkioiden lukumäärä // Laatikko-olioiden taulukko for(int i = 0 ; i < ltklkm ; i++) laatikot[i] = Laatikko(satunnaisluku(dimRaja), satunnaisluku(dimraja), satunnaisluku(dimraja)); int ensimmainen = 0; // Parin ensimmäisen laatikon indeksi int toinen = 1; // Parin toisen laatikon indeksi double mintilavuus = (laatikot[ensimmainen] + laatikot[toinen]).tilavuus(); for(int i = 0 ; i < ltklkm - 1 ; i++) for(int j = i + 1 ; j < ltklkm ; j++) if(laatikot[i] + laatikot[j] < mintilavuus) ensimmainen = i; toinen = j; mintilavuus = (laatikot[i] + laatikot[j]).tilavuus(); 554 cout << "Oliot, joiden tilavuus lisäyksen jälkeen on pienin, ovat:"; cout << endl << "laatikot[" << ensimmainen << "] "; nayta(laatikot[ensimmainen]); cout << endl << "laatikot[" << toinen << "] "; nayta(laatikot[toinen]); cout << endl << "Lisäyksen jälkeen tilavuus on " << mintilavuus << endl;

23 return 0; Suorituksen jälkeen sain tulostuksen: Oliot, joiden tilavuus lisäyksen jälkeen on pienin, ovat: laatikot[2] 31 * 1 * 31 laatikot[13] 23 * 3 * 13 Lisäyksen jälkeen tilavuus on 4092 Operaattoreiden uudelleenmäärittely Ohjelman jokaisella suorituskerralla tulee tavallisesti eri tulos. Kuinka se toimii Talletamme taulukon alkioiden parin, joiden Laatikko-olioiden tilavuus on pienin, kun ne lisätään toisiinsa, indeksit muuttujiin ensimmainen ja toinen. Aluksi sijoitamme taulukon kaksi ensimmäistä laatikkoa pienimmäksi pariksi lauseella: double mintilavuus = (laatikot[ensimmainen] + laatikot[toinen]).tilavuus(); Koska operator+() palauttaa Laatikko-olion, voimme kutsua tilavuus()-funktiota Laatikkooliolle, joka on palautettu summaamalla laatikot[ensimmainen] ja laatikot[toinen]. Sulkeet kahden Laatikko-olion summan ympärillä ovat välttämättömät, koska jäsenen käsittely - operaattori on suoritusjärjestyksessä ennen +-operaattoria. Jos olisimme halunneet tallettaa yhdistetyn Laatikko-olion, olisimme voineet kirjoittaa: Laatikko yhdistetty = laatikot[ensimmainen] + laatikot[toinen]; double mintilavuus = yhdistetty.tilavuus(); Yhdistettynä tilavuudeltaan pienin pari löytyy sisäkkäisillä silmukoilla: for(int i = 0 ; i < ltklkm - 1 ; i++) for(int j = i + 1 ; j < ltklkm ; j++) if(laatikot[i] + laatikot[j] < mintilavuus) ensimmainen = i; toinen = j; mintilavuus = (laatikot[i] + laatikot[j]).tilavuus(); Ulompi silmukka, jota kontrolloi i, käy läpi taulukon alkiot ensimmäisestä toiseksi viimeiseen. Sisempi silmukka, jota kontrolloi j, yhdistää i:n valitseman Laatikko-olion kaikkiin i:tä seuraaviin taulukon olioihin. Jokaisen Laatikko-olioiden parin kohdalla summan tilavuutta verrataan if-lauseessa mintilavuus-muuttujaan uudelleenmääritellyllä operaattorilla <. Tämä lauseke vastaa lauseketta: (laatikot[i].operator+(laatikot[j])).operator<(mintilavuus) operator+() palauttaa Laatikko-olion, jonka operator<()-funktiota kutsutaan. Jos operator<() palauttaa arvon true, nykyisten indeksien ensimmainen ja toinen arvot talletetaan ja Laatikkoolioiden summan tilavuus talletetaan muuttujaan mintilavuus. 555

24 C++ Ohjelmoijan käsikirja Lopuksi käytämme nayta()-funktiota tulostaessamme löytämämme Laatikko-oliot lauseilla: cout << "Oliot, joiden tilavuus lisäyksen jälkeen on pienin, ovat:"; cout << endl << "laatikot[" << ensimmainen << "] "; nayta(laatikot[ensimmainen]); cout << endl << "laatikot[" << toinen << "] "; nayta(laatikot[toinen]); cout << endl << "Lisäyksen jälkeen tilavuus on " << mintilavuus << endl; Uudelleenmääriteltyä +-operaattoria voidaan tietysti käyttää myös monimutkaisemmissakin lausekkeissa, joissa summataan Laatikko-olioita. Voimme esimerkiksi kirjoittaa: Laatikko ltk4 = ltk1 + ltk2 + ltk3; Tämän tuloksena on Laatikko-olio ltk4, johon mahtuu kolme muuta Laatikko-oliota päällekkäin kasattuna. Olisimme aivan yhtä hyvin voineet toteuttaa lisäysoperaattorin tavallisena funktiona (eli muuna kuin jäsenfunktiona), koska Laatikko-olion mittoihin päästään käsiksi julkisten jäsenfunktioiden kautta. Tällaisen funktion prototyyppi olisi: Laatikko operator+(const Laatikko& altk, const Laatikko& bltk); Jos jäsenmuuttujiin ei päästä käsiksi tällä tavalla, voit silti toteuttaa funktion tavallisena funktiona, joka sitten määritellään Laatikko-luokan ystäväksi. Näistä mainituista vaihtoehdoista ystäväfunktioon perustuva ratkaisu on aina huonoin, joten käytä aina muuta ratkaisutapaa kuin ystäväfunktio, jos se vain on mahdollista. Operaattorifunktiot ovat luokan varsin perustavanlaatuinen ominaisuus, joten minä yleensä toteutan ne jäsenfunktioina - se kuvaa paremmin, että operaatio on tyypin osa. Operaattorin toteutus perustuen toiseen operaattoriin Jos toteutat luokalle lisäysoperaattorin, saat aikaan odotuksen, että myös +=-operaattori on toteutettu luokalle. Käytännössä + ja += -operaattoreilla ei ole mitään yhteistä, mutta jos tarkoituksesi on toteuttaa molemmat, kannattaa huomata, että +-operaattori voidaan toteuttaa taloudellisesti +=-operaattorin avulla. Määritellään ensin funktio, joka toteuttaa +=-operaattorin Laatikko-luokalle. Koska siihen liittyy sijoitus, sen tulee palauttaa viittaus. Käyttämällä samaa logiikkaa kuin käytimme Laatikkoolioiden lisäysoperaattorin yhteydessä, voimme kirjoittaa määrittelyn seuraavasti: // Uudelleenmääritelty += -operaattori inline Laatikko& Laatikko::operator+=(const Laatikko& oikea) pituus = pituus > oikea.pituus? pituus : oikea.pituus; syvyys = syvyys > oikea.syvyys? syvyys : oikea.syvyys; korkeus += oikea.korkeus; return *this; 556 Tämä on varsin suoraviivainen toteutus, joka muuttaa vasemman operandin, eli *this, arvoa lisäämällä siihen oikean operandin. Jälleen tuloksena olevaan olioon mahtuvat alkuperäiset oliot sijoitettuna päällekkäin.

25 Operaattoreiden uudelleenmäärittely Voimme nyt toteuttaa funktion operator+() käyttämällä funktiota operator+=(): // Funktio, joka laskee yhteen kaksi Laatikko-oliota inline Laatikko Laatikko::operator+(const Laatikko& altk) const return Laatikko(*this) += altk; Tässä lauseke Laatikko(*this) kutsuu kopiomuodostinta luodakseen kopion lisäyksen vasemmasta operandista. Tämän jälkeen kutsutaan operator+=()-funktiota, joka lisää siihen oikean operandin. Voit samaa ideaa käyttäen toteuttaa myös uudelleenmääritellyt versiot operaattoreista -=, *= ja niin edelleen. Samaan tapaan voit uudelleenmääritellä myös vertailuoperaattorit toisen operaattorin pohjalta. Koska olemme jo määritelleet operator<()-funktion, voit uudelleenmääritellä >=-operaattorin sen pohjalta: inline bool Laatikko::operator>=(const Laatikko& altk) const return!(*this<(altk)); Pienempi kuin vastakohta on suurempi tai yhtä suuri kuin, joten voit toteuttaa funktion tällä tavalla. Indeksointioperaattorin uudelleenmäärittely Indeksointioperaattori [] tarjoaa erittäin mielenkiintoisia mahdollisuuksia tietyn tyyppisille luokille. Tämä operaattori on selvästikin tarkoitettu valitsemaan yksi olio oliojoukosta, joka voidaan ajatella taulukoksi - mutta oliot voivat itse asiassa olla missä tahansa säiliötyypissä. Voit uudelleenmääritellä indeksointioperaattorin harvalle taulukolle (jossa suuri osa alkioista on tyhjiä) tai esimerkiksi linkitetylle listalle. Tieto voi olla talletettuna jopa tiedostoon ja voit käyttää indeksointioperaattoria piilottamaan syöttö- ja tulostusoperaatioiden monimutkaisuudet. Koska itse päätät, mitä tapahtuu operaattorifunktion sisällä, voit jopa parantaa standardin indeksointioperaattorin toimintaa - esimerkiksi tarkistamalla, että annettu indeksi on sallittu. Luvun 13 AutoKuorma-luokkamme on esimerkki luokasta, jolle voitaisiin toteuttaa indeksointioperaattori. Jokainen AutoKuorma-olio sisältää järjestetyn joukon olioita. Sen sijaan, että käyttäjän pitäisi itse kirjoittaa koodi, joka kävisi läpi listan Laatikko-oliot, voit mahdollistaa listan läpikäynnin indeksin arvon avulla. Indeksin arvo 0 palauttaa listan ensimmäisen olion, arvo 1 palauttaa toisen olion ja niin edelleen. Indeksointioperaattorin sisäinen rakenne huolehtii listan selaamisesta, jotta haluttu olio löytyy. Mietitään hieman, miten operator[]()-funktion tulisi toimia tässä tapauksessa. Sen tulee hyväksyä indeksin arvo, joka tulkitaan listan sijainniksi ja palauttaa tämän sijaintikohdan Laatikko-olio. Meidän tulee palauttaa olio (ei osoitin), jos haluamme toteuttaa esimerkiksi lausekkeen kuorma[3] normaalin toiminnan, joka viittaa kuorma-olion kuvaaman listan neljänteen olioon. Funktion esittely AutoKuorma-luokassa voisi täten olla: 557

Luokan operaatiot. Osoittimet ja viittaukset luokan olioihin

Luokan operaatiot. Osoittimet ja viittaukset luokan olioihin Luokan operaatiot 13 Luokan operaatiot Luokkien olioiden luomiseen ja tuhoamiseen liittyy monia hienouksia, joista sinun tulee olla selvillä, jotta luokkiesi olioiden operaatiot toimivat turvallisesti

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ehto- ja toistolauseet

Ehto- ja toistolauseet Ehto- ja toistolauseet 1 Ehto- ja toistolauseet Uutena asiana opetellaan ohjelmointilauseet / rakenteet, jotka mahdollistavat: Päätösten tekemisen ohjelman suorituksen aikana (esim. kyllä/ei) Samoja lauseiden

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

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

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

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

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

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

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

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

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

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

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

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

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet Tunnus, varattu sana, kommentti Muuttuja, alkeistietotyyppi, merkkijono, Vakio Tiedon merkkipohjainen tulostaminen Ohjelmointi (ict1tx006) Tunnus (5.3) Javan tunnus Java-kirjain Java-numero

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 2 vastaukset Harjoituksen aiheena on BNF-merkinnän käyttö ja yhteys rekursiivisesti etenevään jäsentäjään. Tehtävä 1. Mitkä ilmaukset seuraava

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

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

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

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

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

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

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

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

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

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

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

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

INSIDE C++ Ohjelmoijan käsikirja. Ivor Horton WROX PRESS

INSIDE C++ Ohjelmoijan käsikirja. Ivor Horton WROX PRESS INSIDE C++ Ohjelmoijan käsikirja Ivor Horton WROX PRESS C++ Ohjelmoijan käsikirja Kirjoittanut Kääntäjä Kansi Kustantaja Ivor Horton Jouni Laaksonen Frank Chaumont IT Press PL 25 00511 HELSINKI Sähköpostiosoite

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

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo 15.2.2006

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo 15.2.2006 TURUN YLIOPISTO DEMO III Informaatioteknologian laitos tehtävät Olio-ohjelmoinnin perusteet / Salo 15.2.2006 1. Tässä tehtävässä tarkastellaan erääntyviä laskuja. Lasku muodostaa oman luokkansa. Laskussa

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

Tietotyypit ja operaattorit

Tietotyypit ja operaattorit Tietotyypit ja operaattorit Luennossa tarkastellaan yksinkertaisten tietotyyppien int, double ja char muunnoksia tyypistä toiseen sekä esitellään uusia operaatioita. Numeeriset tietotyypit ja muunnos Merkkitieto

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

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

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

Standardi mallikirjasto

Standardi mallikirjasto Standardi mallikirjasto 20 Standardi mallikirjasto Kuten jo tiedätkin C++ sisältää laajan standardikirjaston, joka yksinkertaistaa monia ohjelmointitehtäviä. Tähän saakka näkemäsi lisäksi tämä kirjasto

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

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

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

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

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin. 2. Ohjausrakenteet Ohjausrakenteiden avulla ohjataan ohjelman suoritusta. peräkkäisyys valinta toisto Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet

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

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen Taulukot: Array Taulukko Javassa pitää aina perustaa (new) Yksinkertaisessa tilanteessa taulukon koko tiedetään etukäteen ja

Lisätiedot

Osa III. Olioiden luominen vapaalle muistialueelle

Osa III. Olioiden luominen vapaalle muistialueelle Osa III 10. oppitunti Kehittyneet osoittimet Eräs tehokkaimpia C++ -työkaluja on mahdollisuus käsitellä tietokoneen muistia suoraan osoittimien avulla. Tässä luvussa käsitelläänkin seuraavia aiheita: Kuinka

Lisätiedot

Tietorakenteet ja algoritmit

Tietorakenteet ja algoritmit Tietorakenteet ja algoritmit Pino Pinon määritelmä Pinon sovelluksia Järjestyksen kääntäminen Palindromiprobleema Postfix-lausekkeen laskenta Infix-lausekkeen muunto postfix-lausekkeeksi Sisäkkäiset funktiokutsut

Lisätiedot

Harjoitus 7. 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Harjoitus 7. 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti: Harjoitus 7 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti: class Lintu //Kentät private int _siivenpituus; protected double _aivojenkoko; private bool _osaakolentaa; //Ominaisuudet public int

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

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

Algoritmit 2. Luento 2 To Timo Männikkö

Algoritmit 2. Luento 2 To Timo Männikkö Algoritmit 2 Luento 2 To 14.3.2019 Timo Männikkö Luento 2 Tietorakenteet Lineaarinen lista, binääripuu Prioriteettijono Kekorakenne Keko-operaatiot Keon toteutus taulukolla Algoritmit 2 Kevät 2019 Luento

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

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

Sisällys. 17. Ohjelmoinnin tekniikkaa. Aritmetiikkaa toisin merkiten. for-lause lyhemmin

Sisällys. 17. Ohjelmoinnin tekniikkaa. Aritmetiikkaa toisin merkiten. for-lause lyhemmin Sisällys 17. Ohjelmoinnin tekniikkaa for-lause lyhemmin. Vaihtoehtoisia merkintöjä aritmeettisille lauseille. Useiden muuttujien esittely ja alustaminen yhdellä lauseella. if-else-lause vaihtoehtoisesti

Lisätiedot

Sisällys. 16. Ohjelmoinnin tekniikkaa. Aritmetiikkaa toisin merkiten. Aritmetiikkaa toisin merkiten

Sisällys. 16. Ohjelmoinnin tekniikkaa. Aritmetiikkaa toisin merkiten. Aritmetiikkaa toisin merkiten Sisällys 16. Ohjelmoinnin tekniikkaa Vaihtoehtoisia merkintöjä aritmeettisille lauseille. Useiden muuttujien esittely ja alustaminen yhdellä lauseella. For-lause lyhemmin. If-else-lause vaihtoehtoisesti

Lisätiedot

Valinnat ja päätökset

Valinnat ja päätökset Valinnat ja päätökset 4 Valinnat ja päätökset Päätöksenteko on erittäin tärkeässä asemassa kaikissa ohjelmointikielissä. Jos ohjelman lauseiden suoritusjärjestystä ei voitaisi muuttaa tietojen vertailun

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

16. Ohjelmoinnin tekniikkaa 16.1

16. Ohjelmoinnin tekniikkaa 16.1 16. Ohjelmoinnin tekniikkaa 16.1 Sisällys Vaihtoehtoisia merkintöjä aritmeettisille lauseille. Useiden muuttujien esittely ja alustaminen yhdellä lauseella. For-lause lyhemmin. If-else-lause vaihtoehtoisesti

Lisätiedot

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++? JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS Teemu Saarelainen teemu.saarelainen@kyamk.fi Lähteet: http://java.sun.com/docs/books/tutorial/index.html Vesterholm, Kyppö: Java-ohjelmointi,

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 3.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 3.2.2010 1 / 36 Esimerkki: asunnon välityspalkkio Kirjoitetaan ohjelma, joka laskee kiinteistönvälittäjän asunnon

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

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005 Tällä luennolla Algebralliset tietotyypit Hahmonsovitus (pattern matching) Primitiivirekursio Esimerkkinä binäärinen hakupuu Muistattehan...

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti Tentaattori: Antti-Jussi Lakanen 18. toukokuuta 2018 Yleistä Tentti 1 oli pistekeskiarvon (12.7) perusteella vaikeudeltaan kohtuullinen. Omasta tehtäväpaperista

Lisätiedot

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta 5. 1. Toteuta Pythonilla seuraava ohjelma:

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta 5. 1. Toteuta Pythonilla seuraava ohjelma: Kerta 2 Kerta 3 Kerta 4 Kerta 5 Kerta 2 1. Toteuta Pythonilla seuraava ohjelma: 2. Tulosta Pythonilla seuraavat luvut allekkain a. 0 10 (eli, näyttää tältä: 0 1 2 3 4 5 6 7 8 9 10 b. 0 100 c. 50 100 3.

Lisätiedot

Algoritmit 2. Luento 2 Ke Timo Männikkö

Algoritmit 2. Luento 2 Ke Timo Männikkö Algoritmit 2 Luento 2 Ke 15.3.2017 Timo Männikkö Luento 2 Tietorakenteet Lineaarinen lista, binääripuu Prioriteettijono Kekorakenne Keko-operaatiot Keon toteutus taulukolla Algoritmit 2 Kevät 2017 Luento

Lisätiedot

Tietorakenteet ja algoritmit

Tietorakenteet ja algoritmit Tietorakenteet ja algoritmit Merkintöjen tulkintoja *++Pstack->top = item *Pstack->top++ = item (*Pstack->top)++ *(Pstack++)->top = item *(++Pstack)->top = item Lisää pinon toteutuksia Dynaaminen taulukko

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 28.2.2011 T-106.1208 Ohjelmoinnin perusteet Y 28.2.2011 1 / 46 Ohjelmointiprojektin vaiheet 1. Määrittely 2. Ohjelman suunnittelu (ohjelman rakenne ja ohjelman

Lisätiedot

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2 4. Attribuutit 4.1 Sisällys Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2 Yleistä Luokan lohkossa, mutta metodien ulkopuolella esiteltyjä muuttujia ja vakioita. Esittely

Lisätiedot

Zeon PDF Driver Trial

Zeon PDF Driver Trial Matlab-harjoitus 2: Kuvaajien piirto, skriptit ja funktiot. Matlabohjelmoinnin perusteita Numeerinen integrointi trapezoidaalimenetelmällä voidaan tehdä komennolla trapz. Esimerkki: Vaimenevan eksponentiaalin

Lisätiedot

7. Näytölle tulostaminen 7.1

7. Näytölle tulostaminen 7.1 7. Näytölle tulostaminen 7.1 Sisällys System.out.println- ja System.out.print-operaatiot. Tulostus erikoismerkeillä. Edistyneempää tulosteiden muotoilua. 7.2 Tulostusoperaatiot System.out.println-operaatio

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

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu Taulukot Taulukon määrittely ja käyttö Taulukko metodin parametrina Taulukon sisällön kopiointi toiseen taulukkoon Taulukon lajittelu esimerkki 2-ulottoisesta taulukosta 1 Mikä on taulukko? Taulukko on

Lisätiedot

16. Ohjelmoinnin tekniikkaa 16.1

16. Ohjelmoinnin tekniikkaa 16.1 16. Ohjelmoinnin tekniikkaa 16.1 Sisällys For-lause lyhemmin. Vaihtoehtoisia merkintöjä aritmeettisille lauseille. Useiden muuttujien esittely ja alustaminen yhdellä lauseella. If-else-lause vaihtoehtoisesti

Lisätiedot