Standardi mallikirjasto

Koko: px
Aloita esitys sivulta:

Download "Standardi mallikirjasto"

Transkriptio

1 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 sisältää joukon malleja, jotka tarjoavat vielä suuremmat mahdollisuudet. Voit käyttää näitä malleja luodessasi standardimuotoisia säiliöitä, algoritmeja ja funktioita omille tietotyypeille, jos ne tarvitsevat tällaisia ominaisuuksia ohjelmissasi. Nämä mallit muodostavat yhdessä standardin mallikirjaston (STL). Tässä luvussa esittelemme STL:n perussäiliöt ja algoritmit, jotka toimivat näiden säiliöiden yhteydessä. Luvun aiheita ovat: Standardin mallikirjaston perusrakenne Miten luodaan ja käytetään peräkkäissäiliöitä vector<> ja list<> sekä assosiatiivisia säiliöitä map<> ja multimap<> vector<>- ja list<>-säiliöiden erikoiset talletustavat Miten iteraattorit yhdistävät säiliöt yksinkertaisiin C++:n standarditaulukoihin Miten STL käyttää erikoistumista suorituskyvyn parantamiseksi STL:n arkkitehtuurin perusteet Yksi STL:n tärkeä ominaisuus on se, että se antaa käyttöösi yleisiä työkaluja. Koska STL:n kaikki ominaisuudet ovat mallipohjaisia, ne toimivat lähes kaikkien mahdollisten tietotyyppien kanssa. STL:n avulla voit luoda luokan, joka määrittelee linkitetyn listan mille tahansa tietotyypillesi. Jos tarvitset linkitetyn listan Laatikko-olioille ja JalkapallonPelaaja-olioille, se ei ole mikään ongelma STL:lle. Kun sinun tarvitsee käsitellä olioitasi tavalliseen tapaan, STL voi auttaa tässäkin. Jos sinun tarvitsee lajitella Laatikko-oliosi nousevaan järjestykseen, STL voi muodostaa lajittelufunktion mille tahansa tietotyypille, jolle on määritelty vertailuoperaattori järjestyksen vertailua varten. Käyttääpä ohjelmasi millaisia olioita tahansa, on mahdollista, että STL voi auttaa niiden standardimuotoisessa järjestelyssä tai analysoinnissa. 823

2 C++ Ohjelmoijan käsikirja STL sisältää kolmenlaisia työkaluja - säiliöitä, iteraattoreita ja algoritmeja. Säiliöiden avulla voit järjestää mielivaltaisen tyyppisiä olioita - linkitetty lista on yksi esimerkki säiliöistä. STL:n säiliöt jakaantuvat kahteen luokkaan: Peräkkäissäiliöt (vector, deque ja list), jotka sisältävät tietyn tyyppisiä olioita peräkkäisessä muodossa. Assosiatiiviset säiliöt (map, multimap, set ja multiset) mahdollistavat tietyn tyyppisten olioiden tallettamisen ja hakemisen erityyppisten avainten avulla. Yksinkertainen esimerkki voisi olla Tyontekija-olio, jonka avaimena on henkilönumero. Tyontekija-olio voidaan hakea henkilönumeron perusteella. Iteraattorit ovat liima, joka pitää STL:n kasassa. Riippumatta käytettävästä säiliöstä, sen alkioita käsitellään lähes yksinomaan iteraattoreiden avulla ja iteraattoreita käytetään algoritmien soveltamisessa säiliön olioille. Iteraattori on fiksu osoitin. Luvussa 14 määrittelimme yksinkertaisen iteraattoriluokan - LtkPtr-luokan - AutoKuorma-säiliöllemme. Lisäksi STL sisältää iteraattoreita, joita voidaan käyttää olioiden siirtämiseen virtaan tai virrasta. Algoritmit tarjoavat laskenta- tai analysointimekanismeja iteraattoreiden avulla käytettäville oliojoukoille. Algoritmien esimerkkinä voidaan mainita säiliön olioiden haku ja lajittelu. Kaikille STL:n algoritmeille välitetään parametrinä iteraattori. Emme mitenkään voi käsitellä koko STL:ää tässä luvussa. Koko STL:n käsittely vaatisi oman kirjansa, joten käsittelemme tässä vain pienen osan mahdollisuuksistamme. Käsittelemme joitakin perustyökaluja ja katsomme, miten voimme niitä käyttää yksinkertaisten ongelmien ratkaisuun. Näin pääset alkuun ja saat itseluottamusta kokeilla itse joitakin muita STL:n ominaisuuksia. STL:n kaikkein tärkeimmät työkalut ovat säiliöt - tulet varmastikin käyttämään niitä kaikkein useimmin. Et voi kuitenkaan käyttää säiliöitä ilman iteraattoreita, joten sinun tulee ymmärtää myöskin ne hyvin. Algoritmit ovat STL:n kaikkein suurin työkalukokoelma. Suuri osa niistä ei ole kuitenkaan käyttökelpoisia suurelle osalle ohjelmia ja joidenkin käyttö on varsin erikoistunutta. Emme käsittele STL:n algoritmeja yksityiskohtaisesti tässä luvussa, mutta käytämme joitakin niistä. Seuraava taulukko antaa yleiskuvan tarjolla olevista vaihtoehdoista. Algoritmiperhe Perustuu Esimerkkejä 824 kuuluminen operator= copy, remove, replace sijoittaminen operator=swap random_shuffle, rotate, reverse, permute järjestys operator< sort, partition, merge, find, min, max etsintä ja valinta operator== unique, match, count, search, copy_if, remove_if, replace_if muuntaminen funktio-olio for_each, transform, generate, fill numeeriset funktio-olio inner_product, partial_sum, accumulate, adjacent_difference

3 Standardi mallikirjasto Nämä ovat vapaamuotoisia perheitä ja taulukossa on lueteltu vain pieni osa kaikista käytettävissä olevista algoritmeista. Algoritmit toimivat yleisesti ottaen säiliöihin talletettujen olioiden kanssa, mutta niiden ei tarvitse tietää mitään varsinaisesta käytetystä säiliöstä, koska olioita käsitellään aina iteraattoreiden avulla. Kaksi ensimmäistä ryhmää - kuuluminen ja sijoittaminen - hoitavat alkioiden siirtelyt. Tärkeimmät tässä käytettävät operaattorit ovat sijoitusoperaattori ja swap-operaattori (vaihtooperaattori). Järjestys-ryhmän algoritmit ovat kaikkein tärkeimmät. Lajittelu on itsessään äärettömän suuri tieteenala ja oikean tekniikan käyttö on suorituskyvyn kannalta kriittinen. STL:n tarjoamat lajittelualgoritmit ovat parhaimpien tunnettujen joukossa. Monet STL:n algoritmit ovat suhteellisen helppoja tehdä itsekin uudelleen, mutta lajittelualgoritmit ovat suuri poikkeus. Jos voit opetella vain yhden algoritmiperheen, opettele järjestys-algoritmit. Etsintä ja valinta -algoritmit ovat yksinkertaisia, mutta erittäin käteviä. Näitä algoritmeja käytetään tilanteissa, joissa alkiot ovat samat. Muuntaminen-ryhmän algoritmeja näkyy ohjelmissa harvemmin. Ellei tilanne ole hyvin yksinkertainen, on usein helpompaa kirjoittaa itse for-silmukka. STL:n toteutus näille algoritmeille sallii niiden optimoinnin tavalla, joka ei ole mahdollista omalle koodillesi. Harkitse näiden algoritmien käyttöä, kun hyvä suorituskyky on äärimmäisen tärkeää. Funktio-oliot, joihin muuntaminen- ja numeeriset -ryhmät perustuvat, ovat luokkaolioita, jotka uudelleenmäärittelevät funktion kutsu -operaattorin operator(), ja ovat erityisesti suunnitellut funktion välittämiseen parametrinä tehokkaammin kuin pelkän funktion osoittimen välittäminen tarjoaa. Edellä oleva taulukko jakaa algoritmit tärkeimmän toiminnon mukaan, mutta algoritmit voidaan jakaa ryhmiin myös muilla tavoilla. Usein algoritmit jaetaan muuttaviin ja ei-muuttaviin algoritmeihin. Näistä ensimmäiset ovat algoritmeja, jotka muuttavat säiliön sisältöä ja jälkimmäiset ovat algoritmeja, jotka eivät muuta säiliön sisältöä. STL:n otsikkotiedostot STL:n ominaisuudet esitellään seuraavissa otsikkotiedostoissa: Otsikkotiedosto <vector> <deque> <list> <map> Tarkoitus taulukkosäiliö, jossa on yksi pää taulukkosäiliö, jossa on kaksi päätä molempiin suuntiin linkitetty listasäiliö assosiatiivinen taulukkosäiliö Taulukko jatkuu seuraavalle sivulle 825

4 C++ Ohjelmoijan käsikirja Otsikkotiedosto <set> <queue> <stack> <iterator> <algorithm> <numeric> <functional> <bitset> <valarray> <complex> <utility> Tarkoitus järjestetty joukkosäiliö kaksipäinen jono (säiliömuunnin) pino (säiliömuunnin) iteraattorit ja säiliötuki yleiskäyttöiset algoritmit numeeriset algoritmit algoritmien funktio-olio -tuki bittisarjoja kuvaavat oliot numeeristen arvojen taulukot kompleksilukujen tuki funktio-olioiden tuki Jotkin STL:n osat on esitelty myös virtojen otsikkotiedostoissa - <iostream>, <istream>, <ostream>, <sstream>. Nämä tukevat STL:n algoritmien pohjalta syöttöä ja tulostusta. vector-säiliön käyttö Paras paikka aloittaa STL:n käsittely on vector-säiliö, joka on lähinnä C++:n tavallista taulukkoa. Itse asiassa vector-säiliötä voidaan käyttää lähes kaikissa paikoissa, joissa voidaan käyttää C++:n taulukkoakin. vector-säiliön käyttö on paljon helpompaa kuin C++:n taulukon - taulukon kohdalla sinun tulee itse huolehtia taulukon koosta, mutta vector-säiliön kohdalla kaikki tällainen työ hoidetaan automaattisesti. Kun olet tottunut käyttämään vector-säiliötä, saatat päättääkin, että et enää koskaan käytä tavallista taulukkoa. Yksi tehtävä kuitenkin vaatii yhä C++:n taulukon käyttöä: staattisten alkuarvojen esittely: string nimet[] = Alf, Bjarne, Zaphod ; Suurissa ohjelmissa tällaisten määrittelyjen määrä kannattaa pitää mahdollisimman pienenä. On usein parempi hakea kiinteät alkuarvot ohjelman resurssitiedoista suoritusaikana. 826 Kokeile itse - vector<> vs. C++:n taulukko Katsotaan pikaisesti int-taulukkoa ja int-tyyppistä vector-säiliötä. Huomaamme, että ne toimivat suurelta osin samaan tapaan. // Esimerkki 20.1 Taulukon ja vector-säiliön pikavertailu #include <iostream> #include <vector> using namespace std;

5 Standardi mallikirjasto int main() int a[10]; vector<int> v(10); // C++:n taulukon esittely // vastaava STL:n vector-säiliön esittely cout << "10-alkioisen taulukon koko: " << sizeof a << endl; cout << "10-alkioisen vector-säiliön koko: " << sizeof v << endl; for (int i = 0; i < 10; ++i) a[i] = v[i] = i; int a_summa = 0, v_summa = 0; for (int i = 0; i < 10; ++i) a_summa += a[i]; v_summa += v[i]; cout << "taulukon 10 alkion summa on: " << a_summa << endl; cout << "vector-säiliön 10 alkion summa on: " << v_summa << endl; return 0; Kun suoritat tämän ohjelman, se tulostaa: 10-alkioisen taulukon koko: alkioisen vector-säiliön koko: 16 taulukon 10 alkion summa on: 45 vector-säiliön 10 alkion summa on: 45 Kuinka se toimii Kaikki STL:n oliot ovat osa standardikirjastoa, joten ne on määritelty nimiavaruudessa std. Tarvitsemiasi STL:n ominaisuuksia vastaavat otsikkotiedostot tulee tietysti sisällyttää lähdetekstiin ennen ominaisuuksien käyttöä. Jos haluat käyttää nimiä ilman std:n kirjoittamista aina nimen yhteyteen, voit ottaa std-nimiavaruuden käyttöön using-komennolla: #include <vector> using namespace std; Ainut ero taulukon ja vector-säiliön käytössä on niiden esittelyissä: int a[10]; vector<int> v(10); // C++:n taulukon esittely // vastaava STL:n vector-säiliön esittely C++:n taulukko on sisäänrakennettu tyyppi, joka esitellään []-syntaksilla. Toisaalta vectorsäiliö on mallina toteutettu standardikirjaston tyyppi. Malliparametri määrittelee vector-säiliön sisältämien olioiden tyypin. Tässä olemme esitelleet vector-säiliön, joka tallettaa int-tyyppisiä olioita. 827

6 C++ Ohjelmoijan käsikirja Tässä esimerkissä taulukko a ja vector-säiliö v ovat molemmat automaattisia muuttujia. Taulukon kohdalla tämä tarkoittaa sitä, että 10 kokonaisluvun tila varataan automaattisesta muistista. Minun tietokoneessani tyyppi int vie 4 tavua, joten taulukko a vie tilaa 40 tavua, kuten tulostuksesta huomaat. vector-säiliön olio v on myöskin automaattisessa näkyvyysalueessa, mutta (toisin kuin taulukko) se ei talleta sisältöään automaattiseen muistiin. Se varaa sisäisesti muistia alkioita varten vapaasta muistista. Aluksi se varaa talletettujen alkioiden verran muistia - mutta voit lisätä siihen niin monta alkiota kuin haluat. vector-säiliö huolehtii sisäisesti kaikista muistinvarauksen ongelmista (tietysti suhteessa vapaaseen muistiisi!). vector-olion ilmoitettu koko ei sisällä alkioita varten tarvittua muistia. Tästä syystä tällaista oliota kutsutaan usein kahvaksi. Se sisältää ainoastaan tarvittavan määrän muistia, jotta vectorsäiliö voi käsitellä alkioiden muistia. Kuten tulostuksesta huomaat, vector-olion sizeofoperaattorin palauttama koko on vain 16 tavua. v:n todellinen sisältö - muisti, joka tarvitaan sen tallettamien olioiden arvojen tallettamiseen - on varattu dynaamisesti, ja vie lisäksi 40 tavua vapaasta muistista. Taulukko vie siis selvästikin vähemmän muistia. vector-olion viemä lisätila on kuitenkin varsin pieni. Taulukon ongelma on siinä, että muisti on varattu ohjelmapinosta ja sen koko ja alkioiden lukumäärä on määrätty kiinteäksi jo käännösaikana. vector-olion viemän lisätilan vastapainona on kaksi korvaavaa hyötyä: ensiksikin, muistinhallinta on automaattinen ja toiseksi, voit lisätä alkioita vector-säiliöön aina tarvittaessa. 828 vector-säiliön perusoperaatiot vector-säiliön kanssa työskentely on huomattavasti joustavampaa kuin tavallisen taulukon kohdalla. Voit esimerkiksi lisätä alkioita vector-olion loppuun tai keskelle ja voit poistaa alkioita. Tarvittava muisti hallitaan aina automaattisesti. Saat aina selville vector-oliossa olevien alkioiden lukumäärän (kutsumalla sen size()-jäsenfunktiota) ja sen empty()-jäsenfunktio palauttaa arvon true, jos vector-oliossa ei ole lainkaan alkioita. Perusoperaatiot alkion lisäämiseksi tai poistamiseksi ovat: insert() Lisää yhden tai useamman alkion push_back() Lisää parametrinään saamansa oliot vector-olion perään erase() Poistaa yhden tai useamman alkion clear() Poistaa kaikki alkiot Jotta ymmärrät näiden alkioiden toiminnan, kokeillaan niitä esimerkin avulla. Meidän täytyy jo tässä esimerkissä käyttää iteraattoreita, mutta olet nähnyt iteraattoreita toiminnassa jo luvussa 14, joten tämän ei pitäisi olla kovinkaan pelottavaa. vector-olion begin()-jäsen palauttaa iteraattorin, joka osoittaa ensimmäiseen alkioon ja end()-jäsen palauttaa iteraattorin, joka osoittaa osoittimen, joka osoittaa yhden alkion verran viimeisen alkion ohi. Voit käyttää näitä iteraattoreita käydessäsi vector-olion alkioita läpi - kasvattamalla begin()-jäsenen palauttamaa iteraattoria, kunnes se on sama kuin end()-jäsenen palauttama iteraattori. Voit tietysti käyttää myös []-operaattoria; voit vapaasti päättää kumpaa tapaa käytät.

7 Standardi mallikirjasto Kokeile itse - Lyhyt johdatus vector-säiliöön! Tämä ohjelma käy läpi juuri käsittelemämme yksinkertaiset vector-säiliön operaatiot. Kokeilemme alkioiden lisäämistä ja poistamista vector-oliosta ja erilaisia tapoja tutkia vectorolion sisältöä. Huomaa, että sinun käännösympäristösi STL:n toteutus ei ehkä toimi tämän esimerkin kanssa täsmälleen kirjoitetulla tavalla, koska tällä hetkellä STL:n toteutukset vaihtelevat suurestikin. ANSI/ISO-standardin pitäisi muuttaa tämä tilanne, koska yhä enemmän ja enemmän C++:n toteutuksia päivitetään sen mukaiseksi. Jos esimerkki ei toimi, sinun tulee tarkistaa kirjaston dokumenteista, mikä ohjelman osa tulee muuttaa. Tässä esimerkissä on kirjoitettu funktio nayta_jarjestys(), joka havainnollistaa C++:n osoittimien ja vector-säiliön iteraattoreiden yhtäläisyyttä. tutki_vector()-funktio, joka tulostaa vector-säiliön sisällön ohjelman eri kohdissa, kutsuu nayta_jarjetys()-funktiota. // Esimerkki 20.2 vector<>-säiliön käsittely #include <iostream> #include <vector> #include <algorithm> // STL:n vector-säiliö // copy()-funktio using namespace std; // Näyttää alkiot järjestyksessä void nayta_jarjestys(const int* ensim, const int* viim) cout << " "; copy(ensim, viim, ostream_iterator<int>(cout, " ")); cout << "" << endl; // Näyttää vector-olion sisällön void tutki_vector(const vector<int>& v) cout << " vector-oliolla on " << v.size() << " alkiota: "; nayta_jarjestys(v.begin(), v.end()); int main() vector<int> v; cout << "uusi vektori luotu" << endl; tutki_vector(v); // Luodaan tyhjä vektori cout << "täytetään vektori taulukosta" << endl; int arvot[] = 1, 3, 7, 5; v.insert(v.end(), arvot+1, arvot+3); // Lisätään kaksi alkiota tutki_vector(v); cout << "lisätään arvo 5" << endl; v.push_back(5); tutki_vector(v); // Lisätään alkio loppuun 829

8 C++ Ohjelmoijan käsikirja cout << "poistetaan alkio siirtymässä 1" << endl; v.erase(&v[1]); // Poistetaan toinen alkio tutki_vector(v); cout << "lisätään alkio 4 siirtymään 1" << endl; v.insert (v.begin()+1, 4); // Lisätään alkio tutki_vector(v); cout << "poistetaan kaikki alkiot" << endl; v.clear(); tutki_vector(v); // Poistetaan kaikki alkiot return 0; Tulostus näyttää vector-olion sisällön jokaisen vector-operaation jälkeen: uusi vektori luotu vector-oliolla on 0 alkiota: täytetään vektori taulukosta vector-oliolla on 2 alkiota: 3 7 lisätään arvo 5 vector-oliolla on 3 alkiota: poistetaan alkio siirtymässä 1 vector-oliolla on 2 alkiota: 3 5 lisätään alkio 4 siirtymään 1 vector-oliolla on 3 alkiota: poistetaan kaikki alkiot vector-oliolla on 0 alkiota: Kuten huomaat, vector-säiliö on hyvä pitämään huolta sisällöstään. Tavallisen taulukon kohdalla kaikkien näiden operaatioiden toteuttaminen olisi ollut huomattavasti hankalampaa. Kuinka se toimii Koodi alkaa kahdella #include-komennolla, jotka sisällyttävät kaksi STL:n otsikkotiedostoa: #include <vector> // STL:n vector-säiliö #include <algorithm> // copy()-funktio 830 Otsikkotiedosto vector määrittelee vector-säiliön ja kaikki sen sisäänrakennetut operaatiot. STL mahdollistaa, että voit tehdä vector-oliolla paljon muutakin, kuin mikä kuuluu suoraan vectormallin ilmentymään. Otsikkotiedosto algorithm sisältää sitten loput tarvittavat herkut. Seuraavaksi määrittelemme nayta_jarjestys()-funktion, joka tulostaa alkiot järjestyksessä: void nayta_jarjestys(const int* ensim, const int* viim) cout << " "; copy(ensim, viim, ostream_iterator<int>(cout, " ")); cout << "" << endl;

9 Standardi mallikirjasto Tämä funktio käyttää STL:n copy()-algoritmia, joka tulostaa cout-virtaan kahden osoittimen osoittaman välin. Näet ohjelman tulostuksesta, että tämä myöskin toimii. Palaamme ostream_iterator<>-iteraattoriin myöhemmin, kun käsittelemme tulostusiteraattoreita tarkemmin. Funktio copy() on ainut funktio tässä esimerkissä, joka ei kuulu itse vector-malliin. Sen kaksi ensimmäistä parametriä määrittelevät lähteen välin. Kopiointi alkaa ensim-alkiosta ja jatkuu viim-alkioon saakka. viim-alkiota ei kuitenkaan kopioida. copy-funktio hyväksyy minkä tahansa iteraattorin kahden ensimmäisen parametrinsä arvoksi - tässä olemme käyttäneet tavallisia osoittimia. Kolmas parametri on kohdesijainti, joka määritellään myöskin iteraattorin avulla. Tässä esimerkissä käytämme tulostusiteraattoria, joka luodaan lausekkeella ostream_iterator<int>(cout, " "). STL sallii tällaisen joustavan määrittelyn. copy()-algoritmi sijoittaa jokaisen lähdealkion kohdeolioomme tietämättä tarkasti, minkälaista kohdetta se käsittelee - se vain sijoittaa kopioitavat oliot kolmantena parametrinä olevan iteraattorin mukaan ja olettaa, että iteraattori tietää, minne olio tulee sijoittaa. Tässä tapauksessa kohdeolio tulostaa siihen kopioidut arvot standardiin tulostusvirtaan cout. Voit välittää monia erilaisia iteraattoreita STL:n algoritmeille ja ne toimivat sen mukaisesti. Iteraattori voi olla kuten osoitin, joka lukee ja kirjoittaa arvoja muistiin, tai se voi olla monimutkaisempi olio, joka lukee tai kirjoittaa arvot virtaan. copy()- funktio toimii yhtä hyvin kopioitaessa olio vector-säiliöstä virtaan tai kopioitaessa tietynlainen olio säiliöstä toiseen. Funktio tutki_vector() kutsuu nayta_jarjetys()-funktiotamme: void tutki_vector(const vector<int>& v) cout << " vector-oliolla on " << v.size() << " alkiota: "; nayta_jarjestys(v.begin(), v.end());! Tämä funktio havainnollistaa yhtä vector-säiliön varsin hienoa ominaisuutta. Huomaa, että välitämme vector-olion vain yhtenä parametrinä. Meidän ei tarvitse välittää toista parametriä, joka kertoisi vector-säiliön sisältämien alkioiden lukumäärän - eikä kuinka monta alkiota vectorsäiliöön voi sijoittaa. Tulostamme vector-olion alkioiden lukumäärän kutsumalla sen size()- jäsentä. vector-olio tietää aina, montako alkiota siihen on talletettu. Huomaa, että saamme vector-olion ensimmäisen ja viimeisen alkion iteraattorin selville begin()- ja end()-jäsenillä ja välitämme ne nayta_jarjestys()-funktiolle. Nämä iteraattorit muunnetaan automaattisesti nayta_jarjestys()-funktion parametrien tyyppisiksi, eli int*-tyyppisiksi. Vector-iteraattorit ovat lähes identtiset tavallisiin C++:n osoittimiin. Itse asiassa, monet STL:n toteutukset määrittelevät vector<t>::iterator-tyypin tavalliseksi C++:n T*-tyyppiseksi osoittimeksi. Juuri tämä tekee vector-säiliöstä niin hyvän tavallisten taulukoiden korvaajan. Lähes kaikki, mitä olet tehnyt osoittimien kanssa voit tehdä myös vector-säiliön kanssa. 831

10 C++ Ohjelmoijan käsikirja Kuten olemme jo kertoneet, v.begin() osoittaa ensimmäiseen alkioon. Pääset käsiksi ensimmäisen alkion sisältöön kirjoittamalla lausekkeen *v.begin(), v[0] tai v.front(). Mitä näistä käytät, riippuu käyttötilanteesta. Myöhemmin tässä luvussa näemme tilanteita, joissa jokin näistä on luonnollisempi vaihtoehto kuin muut. Huomaa, että et voi käyttää osoittimen end() osoittamaa arvoa - se osoittaa aina yhden osoitteen säiliön viimeisen alkion yli. Osoitinta end() kutsutaan yleensä lopun yli -osoittimeksi. Eli *v.begin() on sallittu, mutta varsin samanlainen lauseke *v.end() on huono idea. Sen sijaan *(v.end()-1) on sallittu ja hyödyllinen tapa päästä käsiksi viimeiseen alkioon. Viimeiseen alkioon pääset käsiksi myös lausekkeilla *(v.begin()+v.size()-1), v[v.size()-1] tai yksinkertaisesti v.back(). Ennen kuin yrität käsitellä alkiota, sinun tulee varmistaa, että viimeinen alkio on olemassa. Nopea tapa tarkistaa tämä on kutsua jäsenfunktiota v.empty(), joka palauttaa arvon true, kun v ei sisällä ainuttakaan alkiota. Ohjelmamme käyttää vector-mallin ilmentymää vector<int>, joten esittelemme int-tyyppisiä arvoja tallettavan vector-säiliön seuraavasti: vector<int> v; // Luodaan tyhjä vektori Tässä esittelemme v:n mallin vector<int>-ilmentymänä kutsumalla oletusmuodostinfunktiota. Näemme tulostuksesta, että uusi säiliömme on aluksi tyhjä. Käytössäsi on tietysti myös muunlaisia muodostinfunktioita. Jos esimerkiksi haluaisit säiliön 50 double-tyyppiselle arvolle, voisit esitellä vector-säiliön data seuraavasti: vector<double> data(50); Uuteen säiliöömme voimme tallettaa arvoja monella tavalla. Yksi kaikkein tehokkaimmista on insert()-jäsenfunktio, joka kopioi kokonaisen sarjan arvoja: cout << "täytetään vektori taulukosta" << endl; int arvot[] = 1, 3, 7, 5; v.insert(v.end(), arvot+1, arvot+3); // Lisätään kaksi alkiota tutki_vector(v); 832 Tästä huomaa jälleen, että STL mielellään määrittelee sarjat kahden osoittimen väliin jäävällä välillä. Funktion insert() ensimmäinen parametri, v.end(), on osoitin sijaintikohtaan, johon haluamme alkiot sijoittaa. Huomaa, että käytämme tässä lopun yli -osoittavaa osoitinta - sen käyttö on sallittu, kun yhdistät arvoja. Tästä onkin helppo muistaa, mitä lopun yli -osoitin tarkoittaa: se on sijaintikohta, johon seuraava lisättävä arvo sijoitetaan. Eli voit käyttää end()-osoitinta uusien alkioiden lisäämiseen - mutta älä yritä käsitellä sen osoittamaa arvoa. insert()-funktion toinen ja kolmas parametri, eli lausekkeet arvot-1 ja arvot+3, määrittelevät yhdessä lisättävien alkioiden välin. Tässä lähteemme on taulukko arvot ja kopioimme tässä toisen ja kolmannen alkion - eli alkaen kohdasta arvot+1 ja päättyen alkiota arvot+3 edeltävään alkioon.

11 Standardi mallikirjasto! Välit määritellään tavallisesti tällä tavalla STL:ssä - väliä, joka sisältää ensimmäisen alkion, mutta ei viimeistä, kutsutaan puoliavoimeksi väliksi. Tällainen merkitään [alku, loppu), jossa sulkeet osoittavat, että väli on suljettu vasemmasta päästä, mutta avoin oikeasta päästä. Eli väli sisältää kohdan alku, mutta ei kohtaa loppu. Kun määrittelet [alku, loppu) välin, kuten esimerkiksi arvoilla arvot+1 ja arvot+3, varmista, että loppu on suurempi kuin alku - ja että molemmat osoittimet on liitetty samaan lähdeolioon. Nämä ovat varsin yleisiä - ja vaikeasti havaittavia - virheitä. Palataan esimerkin 20.2 käsittelyyn. Lisäämme vector-säiliöön alkion push_back()-jäsenellä: v.push_back(5); // Lisätään alkio loppuun Tämä lisää arvon 5 uudeksi alkioksi v-olion perään. Miksi tätä funktiota ei kutsuta yksinkertaisesti nimellä append()? Jos push saa sinut ajattelemaan pinoja, olet oikeilla jäljillä. Itse asiassa STL sisältää pinomuuntimen (stack adaptor), jolla voit muuntaa vector-säiliön pinoksi. Emme käsittele STL:n muuntimia tässä yhteydessä, saat lisätietoa STL:n dokumenteistasi. Monet STL:n nimet viittaavat siihen, että säiliöt voidaan muuntaa toimimaan toisella tavalla, kuten stack ja queue. Seuraavaksi testaamme erase()- ja insert()-funktioita: v.erase(&v[1]); // Poistetaan toinen alkio erase()- ja insert()-operaatioihin kuuluu alkioiden siirtelyä, jotta lisättäville alkioille saadaan tilaa tai poistettavan alkion aukko poistetaan. Sisäisesti vector-säiliö kopioi alkioita, jotta ne pysyvät oikeassa järjestyksessä. Tämä voi olla hyvin hidas operaatio, kuten näemme, kun käsittelemme vector-säiliön muistinhallintaa. Koska vector-säiliö on malli, se voi sisältää myös luokkaolioita, ja tällöin erase()-funktion tulee kutsua jokaisen poistettavan olion tuhoajafunktiota. Tämä lause poistaa toisen alkion vector-säiliöstä v. Se käyttää erase()-funktion yksinkertaisinta muotoa, jolle välitetään vain yksi iteraattori, joka määrittelee yhden poistettavan alkion. Osoitintyyppinen parametri muunnetaan automaattisesti iteraattoriksi. Sen sijaan, että olisimme käyttäneet begin()- ja end()-jäseniä iteraattoreiden muodostuksessa, olemme käyttäneet taulukkomuotoa. Tällä havainnollistamme sitä, että v teeskentelee olevansa taulukko. Lauseke &v[1] viittaa v:n toisen alkion osoitteeseen. Tämän lauseen tuloksena toinen alkio, jonka arvo on 7, poistetaan vector-säiliöstä v. Seuraavaksi lisäämme uuden alkion lauseella: v.insert (v.begin()+1, 4); // Lisätään alkio 833

12 C++ Ohjelmoijan käsikirja! Olemme jo kerran käyttäneet insert()-funktiota. Tällöin sillä oli kaksi iteraattoriparametriä. Tässä muodossa sillä on kaksi parametriä, joista ensimmäinen on iteraattori ja toinen kokonaisluku. Määrittelemme sijaintikohdan lausekkeella v.begin()+1 ja lisäämme uuden alkion - arvon 4 - tähän sijaintikohtaan. Tässä sijaintikohdassa nyt oleva alkio ja kaikki sitä seuraavat alkiot tulee ensin siirtää eteenpäin, jotta uusi arvo mahtuu väliin. Nytkin vector-olio varaa uuden tilan ja kopioi alkiot automaattisesti. Tämä automaattinen kopiointi on varsin miellyttävää. Ohjelmasi suoritus kuitenkin hidastuu merkittävästi, jos vector-olio on suuri ja lisäät tai poistat alkioita olion alkupäästä. STL sisältää toisen säiliön, listan list<>, joka tekee nämä kaikki samat asiat, mutta mitään kopiointia ei tarvitse tehdä. Näemme listan toiminnassa varsin pian. Lopuksi poistamme kaikki alkiot lauseella: v.clear(); // Poistetaan kaikki alkiot Voimme käyttää clear()-jäsentä, jos haluamme poistaa kaikki alkiot eksplisiittisesti. Tämä ei ole kuitenkaan tarpeen. Kun vector-olion v näkyvyysalue päättyy (lohkon lopussa), v ja sen sisältö poistetaan automaattisesti v:n tuhoajafunktion toimesta. v.clear() on itse asiassa lyhyempi muoto lausekkeesta v.erase(v.begin(), v.end()). vector-säiliön käyttö taulukko-operaatioissa Katsotaan seuraavaksi esimerkkiä, johon törmäsimme ensimmäisen kerran luvussa 8, kun käsittelimme funktioita. Seuraavassa on keskiarvo()-funktio esimerkistä 8.5, joka on kiinnostaja siitä syystä, että sille välitetään parametrinä taulukko[]: // Funktio, joka laskee keskiarvon double keskiarvo(double taulukko[], int lkm) double summa = 0.0; // Tähän lasketaan summa for(int i = 0 ; i < lkm ; i++) summa += taulukko[i]; // Summataan taulukon alkiot return summa / lkm; // Palautetaan keskiarvo 834 Ennen kuin STL oli olemassa, C- ja C++-ohjelmat kirjoitettiin tällä tavalla. Vaikka olemmekin käsitelleet runsaasti uusia asioita luvun 8 jälkeen, muistat varmasti vieläkin, että double taulukko[] ja double* taulukko tarkoittavat tässä yhteydessä aivan samaa - eli keskiarvo()-funktion ensimmäinen parametri on osoitin. Koska taulukko ei tiedä, montako alkiota siinä on, meidän tulee aina välittää myös toinen parametri, joka kertoo taulukon alkioiden lukumäärän (joskus meidän tarvitsee välittää myöskin taulukon kapasiteetti). Katsotaan uudelleen esimerkkimme 20.2 nayta_jarjestys()-funktiotamme. Tälle funktiolle välitetään ensimmäisenä parametrinä myöskin osoitin, mutta käytetään vain erilaista muotoa. Toinen parametri on myöskin osoitin:

13 Standardi mallikirjasto void nayta_jarjestys(const int* ensim, const int* viim) cout << " "; copy(ensim, viim, ostream_iterator<int>(cout, " ")); cout << "" << endl; Koska osoittimet vastaavat iteraattoreita, voimme ajatella parametrien olevan tässä iteraattoreita. Väli ensim - viim on jälleen puoliavoin väli - ensim otetaan mukaan, mutta viim ei oteta. Tämä on kuitenkin täysin eri kuin kahden indeksin käyttäminen, koska välin olioiden tyyppi on iteraattoreiden yhteydessä implisiittinen. Vaikka vector-säiliön ja välin käyttäminen on eri taulukkoon ja muuttujaan lkm verrattuna, saamme kuitenkin helposti selville käsiteltävien alkioiden lukumäärän: int lkm = viim - ensim; Eli miksi STL käyttää välejä, eikä taulukoita ja lukumääriä? Tähän on useita syitä. Ensinnäkin, jos taulukoita käytetään runsaasti, osoittimien käyttö on miellyttävämpää. Toiseksi, se on myös huomattavasti tehokkaampaa. Kun näet lauseen, jossa on moniulotteinen taulukko, kääntäjä joutuu tekemään runsaasti töitä lauseen kohdalla. Tutkitaan esimerkiksi seuraavaa koodia: // kun kirjoitat seuraavaa double ilmanpaine[200][200][200]; double paine_keskella = ilmanpaine[99][100][101]; Kääntäjä löytää alkion ilmanpaine[99][100][101] suorittamalla seuraavat lauseet: // kääntäjä tekee todellisuudessa seuraavaa double* apu = ilmanpaine + 99 * sizeof (ilmanpaine[0]) * sizeof (ilmanpaine[0][0]) + 101; double paine_keskella = *apu; Kuten huomaat, kääntäjä tekee kaiken tämän laskennan vain muuntaakseen kaikki takaisin osoitinlausekkeeksi. Hyvä kääntäjä tekee lisäksi paljon yksinkertaistaakseen tätä aina, kun se vain on mahdollista - mutta silti kaikki nämä laskennat ja lisäykset vaativat aikaa. Yksinkertainen totuus on, että osoittimet ovat yksinkertaisempia kuin taulukot ja lisäksi, kun muistamme, että iteraattori on olio, joka toimii osoittimen tapaan, niin tässä on syy siihen, miksi STL:ssä käytetään yleensä välejä, jotka on määritelty iteraattoriparin avulla. Keskiarvon laskeminen iteraattoreiden avulla Voimme määritellä mallin keskiarvo()-funktiolle, joka käyttää iteraattoreita taulukkojen sijaan. Mallin koodi olisi tässä tapauksessa seuraava: template <typename Iter> double keskiarvo(iter a, Iter loppu) double summa = 0.0; // Tähän lasketaan summa 835

14 C++ Ohjelmoijan käsikirja int lkm = 0 ; for( ; a!= loppu ; lkm++) summa += *a++; // Summataan taulukon alkiot // Palautetaan keskiarvo return summa / lkm; Huomaa, kuinka vähän suoritamme operaatioita parametrimuuttujalle a: a!= loppu tarkistaa viimeisen arvon *a haetaan nykyinen arvo a++ siirrytään seuraavaan arvoon Kaksi viimeistä operaatiota on yhdistetty yhdeksi lausekkeeksi *a++. Huomaat varmastikin jo nyt, että tällainen lauseke on yksi kaikkein useimmin C++:ssa käytetty lauseke. Olemme koodanneet mallin siten, että operaation * ja jälkiliitteellisen ++ täytyy toimia tyypille Iter ja näin on sekä osoittimien että iteraattoreiden kohdalla. Iteraattoreiden käyttö yksinkertaisti koodia varsin paljon. Kokeillaan sitä esimerkin avulla. Kokeile itse - Keskiarvon laskeminen iteraattoreiden avulla Seuraavassa on ohjelma, joka laskee keskiarvot mallimme avulla: // Esimerkki 20.3 Keskiarvon laskeminen iteraattoreiden avulla #include <iostream> #include <vector> using namespace std; template <typename Iter> double keskiarvo(iter a, Iter loppu) double summa = 0.0; int lkm = 0 ; for( ; a!= loppu ; lkm++) summa += *a++; // Tähän lasketaan summa // Summataan taulukon alkiot return summa / lkm; // Palautetaan keskiarvo int main() double lampotila[] = 10.5, 20.0, 8.5 ; cout << "taulukon keskiarvo = " << keskiarvo(lampotila, lampotila + (sizeof lampotila/sizeof lampotila[0])) << endl; vector<int> aurinkoinen; aurinkoinen.push_back(7); aurinkoinen.push_back(12); aurinkoinen.push_back(15); cout << aurinkoinen.size() << " kuukautta" << endl; cout << "aurinkoisten päivien lukumäärän keskiarvo: "; cout << keskiarvo(aurinkoinen.begin(), aurinkoinen.end()) << endl; return 0; 836

15 Standardi mallikirjasto Tämän ohjelman tulostus on seuraava: taulukon keskiarvo = 13 3 kuukautta aurinkoisten päivien lukumäärän keskiarvo: Kuinka se toimii Mallien hyvänä puolena on se, että saat niin monta versiota kuin tarvitset, mutta joudut määrittelemään vain yhden. Tämä esimerkki muodostaa kaksi ilmentymää mallifunktiosta keskiarvo. Ensimmäinen keskiarvo-mallin ilmentymä on tavalliseen C++:n taulukkoon sijoitetuille arvoille: double lampotila[] = 10.5, 20.0, 8.5 ; cout << "taulukon keskiarvo = " << keskiarvo(lampotila, lampotila + (sizeof lampotila/sizeof lampotila[0])) << endl; Mallin ilmentymän tyyppi määritellään automaattisesti funktion parametreistä. Toisen parametrin tulee olla osoitin mukaan haluamaamme viimeistä alkiota seuraavaan alkioon - laskemme tämän lisäämällä taulukon alkioiden lukumäärän osoittimeen lampotila. Toinen keskiarvo-mallin ilmentymä on vector-säiliöön talletetuille int-tyyppisille arvoille. Ensin esittelemme vector<int>-olion aurinkoinen: vector<int> aurinkoinen; Ilmentymä luodaan lauseessa: cout << keskiarvo(aurinkoinen.begin(), aurinkoinen.end()) << endl; aurinkoinen.begin() ja aurinkoinen.end() -funktioiden palauttamat paluuarvot ovat tyyppiä vector<int>::iterator - tätä tyyppiä käytetään mallin toisen version ilmentymän muodostamisessa. Eli mallifunktion keskiarvo() kahden ilmentymän allekirjoitukset näyttävät seuraavilta: double keskiarvo<double*>(double* a, double* loppu); double keskiarvo<vector<int>::iterator>(vector<int>::iterator a, vector<int>::iterator loppu); Kuten olemme maininneet, jotkin STL:n vector-säiliön toteutukset käyttävät osoittimia (kuten int*) iteraattoreina. Tällöin toisen ilmentymän allekirjoitus näyttää seuraavalta: double keskiarvo<int*>(int* a, int* loppu); Kaikki STL:n toteutukset eivät kuitenkaan näin tee eikä muutenkaan ole korrektia olettaa, että voimme käyttää lyhyempää muotoa. Jotta ymmärrät, miksi olemme kirjoittaneet ::iterator-osan tyyppiin, vilkaistaan, miltä vectormallin määrittely näyttäisi: template <typename Arvo> 837

16 C++ Ohjelmoijan käsikirja class vector public: typedef Arvo* iterator; // paljon lisää koodia... ; Kun ilmennämme vector-mallin ilmentymän vector<int>, mallista tulee jotain seuraavankaltaista: class vector<int> public: typedef int* iterator; ; Eli vector<int>::iterator on vain tapa viitata siihen tyyppiin, jota vector-mallin ilmentymässä on käytetty iteraattorin toteutuksessa. Nimi iterator kuvaa tätä tyyppiä. Kuten tulostuksesta huomaat, keskiarvon laskenta sujuu kuten odotimmekin. Funktiomme toimii niin vector-säiliön alkioiden kuin tavallisen taulukonkin yhteydessä. Mallitaulukko-vaihtoehto Olisimme voineet hyödyntää malleja myöskin taulukkomuotoisessa ratkaisussa. Kokeile itse - Keskiarvon laskeminen Mallitaulukon avulla Tässä on vaihtoehtoinen versio esimerkille 20.3: // Esimerkki 20.4 Keskiarvon laskeminen mallitaulukon avulla #include <iostream> #include <vector> using namespace std; template <typename Taulukko> double keskiarvo (Taulukko a, long lkm) // Taulukko voi olla osoitin tai iteraattori double summa = 0.0; for (long i = 0; i < lkm; ++i) summa += a[i]; return summa/lkm; // tapahtuu virhetilanne, jos lkm==0 int main() double lampotila[] = 10.5, 20.0, 8.5 ; // Toinen parametri on nyt lukumäärä cout << "taulukon keskiarvo = " << keskiarvo(lampotila, (sizeof lampotila/sizeof lampotila[0])) << endl; 838

17 Standardi mallikirjasto vector<int> aurinkoinen; aurinkoinen.push_back(7); aurinkoinen.push_back(12); aurinkoinen.push_back(15); cout << aurinkoinen.size() << " kuukautta" << endl; cout << "aurinkoisten päivien lukumäärän keskiarvo: "; cout << keskiarvo(aurinkoinen.begin(), aurinkoinen.end() - aurinkoinen.begin()) << endl; return 0; Tämän ohjelman tulostus on aivan sama kuin esimerkissä Koodi näyttää jopa selkeämmältä! Huomaa, kuinka nyt tarvitsemme ainoastaan yhden operaation alkiolle a, nimittäin a.operator[](long). Tästä huomaamme heti, että indeksointioperaattorin parametri on long-tyyppinen - se kuvaa indeksin arvoa. Tässä versiossa meidän täytyy esitellä oma silmukkamuuttuja i - edellisessä versiossa se oli tarpeeton. Iteraattori istream_iterator Seuraava esimerkki havainnollistaa, kuinka voit käyttää mallialgoritmia epätavallistenkin iteraattoreiden kanssa. Olemme jo nähneet ostream_iterator-iteraattorin toiminnassa - tällä kertaa käytämme sen vastakohtaa, istream_iterator, joka hakee tiedon syöttövirrasta. Kokeile itse - Maaginen istream_iterator<> Esimerkeissä 20.3 ja 20.4 käytimme keskiarvo()-funktiotamme arvoille, jotka olivat olemassa taulukossa tai säiliössä. Tällä kertaa keskiarvo()-funktio lukee arvot suoraan syöttövirrasta. Käytämme tässä jälleen esimerkin 20.3 mallifunktiota: // Esimerkki 20.5 Lasketaan virrasta luettujen arvojen keskiarvo #include <iostream> #include <iterator> // istream_iterator<>-malli using namespace std; template <typename Iter> double keskiarvo(iter a, Iter loppu) double summa = 0.0; // Tähän lasketaan summa int lkm = 0 ; for( ; a!= loppu ; lkm++) summa += *a++; // Summataan taulukon alkiot return summa / lkm; // Palautetaan keskiarvo int main() cout << "Syötä numeroita, eroteltuina tyhjillä merkeillä - välilyönneillä, " << endl << "sarkaimella tai rivinvaihdoilla. Lopuksi paina merkkiyhdistelmää, " << endl << "joka vastaa tiedoston loppua (Ctrl-Z PC:ssä)" << endl; double ka = keskiarvo(istream_iterator<double>(cin), istream_iterator<double>()); cout << "Arvojen keskiarvo on " << ka << endl; return 0; 839

18 C++ Ohjelmoijan käsikirja! Kun suoritat tämän ohjelman, varmista, että käytät oikeaa merkkiyhdistelmää syöttövirran sulkemiseksi. PC-maailmassa tämä merkkiyhdistelmä on Ctrl-Z. Tämän jälkeen voi olla tarpeen painaa Enter. Eräs suosittu ohjelmointiympäristö tulee yhtiöltä, jonka tulee kuulla kaikki kahteen kertaan, joten jos ensimmäinen Ctrl-Z ei sulje virtaa, yritä painaa Ctrl-Z useampaan kertaan eri riveille. Tässä on ohjelman tulostus: Syötä numeroita, eroteltuina tyhjillä merkeillä - välilyönneillä, sarkaimella tai rivinvaihdoilla. Lopuksi paina merkkiyhdistelmää, joka vastaa tiedoston loppua (Ctrl-Z PC:ssä) Arvojen keskiarvo on 4.6 Sinun järjestelmäsi saattaa tulostaa jotain hieman erilaista. Älä yritä suorittaa tätä ohjelmaa liian hartaasti, jos se tuottaa ongelmia. Myöhemmin meillä on toinen esimerkki, jossa vältetään konsolin käyttö. Palaamme istream_iterator-iteraattoriin vielä uudelleen. Kuinka se toimii Seuraava lause muodostaa mallimme ilmentymän: double ka = keskiarvo(istream_iterator<double>(cin), istream_iterator<double>()); Tässä välitämme keskiarvo()-funktiollemme varsin oudon näköisiä lausekkeita! Kirjoitetaan tämä toisella tavalla, jotta voimme tutkia sitä tarkemmin: istream_iterator<double> alku(cin); istream_iterator<double> loppu; double ka = keskiarvo(alku, loppu); Olio alku on mallin istream_iterator<double> ilmentymä. Virtaolio cin välitetään muodostinfunktiolle, jotta iteraattori lukee standardista syöttövirrasta. Olio loppu on myöskin mallin istream_iterator<double> ilmentymä. Luomme end-olion käyttämällä istream_iterator<double>-luokan oletusmuodostinfunktiota. Kun muuttuja end luodaan tällä tavalla, se toimii lopun yli -arvona, joka vastaa tiedoston loppua. Uuden versiomme alku ja loppu eivät todellakaan ole osoittimia - ne ovat luokkaolioita, joten miksi tämä toimii? Vastaus on se, että nämä oliot ovat iteraattoreita, mikä tarkoittaa, että ne voivat käyttäytyä osoittimien tapaan. Ne silti välittävät käyttöömme kolme operaattoria, joista olemme riippuvaisia keskiarvo()-funktiossamme: 840 bool Iter::operator!=(Iter end_value); double Iter::operator*(); Iter Iter::operator++(int); Vertailu Viittaus Lisäys

19 Standardi mallikirjasto Tällä kertaa olemme esittäneet nämä luokkafunktioina, koska ne todellakin ovat luokkafunktioita. Ne ovat luokan istream_iterator<double> uudelleenmääriteltyjä operaattorifunktioita. Palauta mieleen, että operator++(int) ei itse asiassa saa int-tyyppistä parametriä - tällä tavalla vain kerromme kääntäjälle että tarkoitamme lisäysoperaattorin jälkiliitteellistä muotoa. Voimme käyttää näitä operaatioita minkä tahansa istream_iterator<double>-tyyppisen olion kohdalla. Toiminnallisuutta sisältävät istream_iterator-iteraattorit Edellä olleet istream_iterator-oliot teeskentelevät olevansa osoittimia, kuten LtkPtr-luokkamme oliot esimerkissä Nämä oliot pystyvät kuitenkin paljon muuhunkin - ne voivat sisältää monimutkaistakin toiminnallisuutta, kuten virtojen I/O-operaatioita. Tämä on erittäin keskeinen ajatus, sillä sen avulla STL on niin tehokas kirjasto. Kun yhdistämme mallifunktiot ja iteraattorit, voimme hankkia välimme mistä tahansa lähteestä. Tätä et voi tehdä vanhan taulukkomuotoisen esitystavan avulla. Kokeile itse - Lisää istream_iterator-taikaa Korostaaksemme iteraattoreiden yleistä luonnetta, tässä on vielä yksi esimerkki. Tällä kertaa kokeilemme puoliavointa väliä arvoilla, jotka ovat merkkijonossa. Jos sinulla oli vaikeuksia esimerkin 20.5 suorituksessa, kokeile mieluummin tätä. // Esimerkki 20.6 Lasketaan merkkijonovirran arvojen keskiarvo #include <iostream> #include <iterator> // istream_iterator<>-malli #include <sstream> // istringstream-iteraattori using namespace std; template <typename Iter> double keskiarvo(iter a, Iter loppu) double summa = 0.0; // Tähän lasketaan summa int lkm = 0 ; for( ; a!= loppu ; lkm++) summa += *a++; // Summataan taulukon alkiot return summa / lkm; // Palautetaan keskiarvo int main() char* kurssi_lukemat = " "; istringstream kello (kurssi_lukemat); istream_iterator<double> alku(kello); istream_iterator<double> loppu; cout << "Lukemat: " << kurssi_lukemat << ". Päivän keskiarvo on "; cout << keskiarvo (alku, loppu) << endl; return 0; Esimerkin tulostus näyttää seuraavalta: Lukemat: Päivän keskiarvo on

20 C++ Ohjelmoijan käsikirja Kuinka se toimii Jos katsot tarkkaan, tämä esimerkki on lähes identtinen esimerkkiin 20.5 verrattuna. Erona on se, että olemme korvanneet cin-virran omalla kello-virralla käyttämällä luokkaa istringstream: char* kurssi_lukemat = " "; istringstream kello (kurssi_lukemat); Alustamme kello-syöttövirtamme siten, että se lukee arvot suoraan ohjelman merkkijonosta kurssi_lukemat. Tämän jälkeen välitämme virtaolion istream_iterator<doubel>muodostinfunktiolle: istream_iterator<double> alku(kello); Uuden kello-virtamme hienona piirteenä on se, että sitä voidaan käyttää useimmissa tapauksissa, joissa saattaisimme käyttää cin-virtaa - istream_iterator ei ole niin pikkutarkka. Se käyttää tyytyväisenä istingstream-oliotamme kello tai muuta merkkijonojen lähdettä virran cin sijaan. Kaikki muu säilyy aivan samana, mukaan lukien keskiarvo()-mallimme! Lisää iteraattoreista Esimerkeissä olemme päässeet varsin pitkälle käyttämällä mallipohjaista versiotamme keskiarvo()-funktiosta. Olemme kuitenkin muodostaneet vain kolme erilaista ilmentymää: double keskiarvo<double*>(double*, double*); double keskiarvo<int*>(int*, int*); double keskiarvo<istream_iterator<double> > (istream_iterator<double>, istream_iterator<double>); Näistä näet selvästi, että kaksi ensimmäistä versiota käsittelevät yksinkertaisia osoittimia, kun taas kolmas käsittelee istream_iterator-oliota. Esimerkiksi esimerkissä 20.3 välitämme alkiot vector<int>-säiliöstä keskiarvo<int*>-versiolle. Esimerkeissä 20.5 ja 20.6 käytämme istream_iterator-oliota, jolloin voimme lukea numeeriset arvot konsolilta tai suoraan tiedostosta. Osoitinversiot käsittävät sekä C++:n perustaulukot että vector-säiliöt, kun taas istream_iterator-versio käsittää tiedostot ja merkkijonot. Emmekä ole vielä kuin hieman raapaisseet pintaa, mitä iteraattoreihin tulee. Iteraattoriolio näyttää yhä varsin mysteeriseltä, joten pysähdytään hetkeksi ja mennään hieman syvemmälle iteraattoriolioiden toimintaan. Huomaat varsin pian, että omien iteraattoriluokkien luominen ei olekaan niin vaikeaa. 842 Iteraattorit Meillä on jo hieman kokemusta hyvin yksinkertaisesta iteraattorista, kun luvussa 14 loimme LtkPtr-luokan; mutta voimme tehdä huomattavasti enemmänkin. Ymmärrämme paremmin STL:n iteraattoreiden toimintaa, jos luomme oman iteraattorimme aloittamalla ensin aivan tyhjästä. Aloitamme yksinkertaisimmasta mahdollisesta iteraattorista ja laajennamme sitä pikku hiljaa, kunnes se on sellainen kuin haluammekin sen olevan - STL:n iteraattoreiden veljeskunnan täysi jäsen.

21 Standardi mallikirjasto Kokeile itse - Oman iteraattorin luonti Aloitamme yksinkertaisesta iteraattorista, joka käy läpi kokonaislukuja. Seuraavassa on esimerkkimme koodi: // Esimerkki 20.7 Yksinkertainen kokonaislukuiteraattoriluokka #include <iostream> using namespace std; class Kokonaisluku public: Kokonaisluku (int par = 0) : X(par) bool operator!=(const Kokonaisluku& par) const //!= -vertailu if (X == par.x) // Debuggaustulostus cout << endl // Näytetään, että olemme täällä << "operator!= palauttaa arvon false" << endl; return X!= par.x; int operator*() const return X; Kokonaisluku& operator++() ++X; return *this; //Osoitusoperaattori // Etuliitteellinen lisäysoperaattori private: int X; ; int main() Kokonaisluku alku(3); Kokonaisluku loppu(7); cout << "Tämän päivän kokonaisluvut ovat: "; for( ; alku!= loppu ; ++alku) cout << *alku << " "; cout << endl; return 0; Kun esimerkki suoritetaan, se tulostaa: Tämän päivän kokonaisluvut ovat: operator!= palauttaa arvon false Kuinka se toimii Ohjelma toimii aivan kuin olisimme esitelleet muuttujat alku ja loppu tavallisiksi kokonaisluvuiksi ja sijoittaneet niihin samat arvot. Kokonaisluku-luokkamme tulostaa lisäksi lisärivin, jos uudelleenmääritelty!=-operaattori palauttaa arvon false. Määrittelemme Kokonaisluku-luokan muodostinfunktion seuraavasti: 843

22 C++ Ohjelmoijan käsikirja Kokonaisluku (int par = 0) : X(par) Kokonaisluku-luokalla on jäsenmuuttuja X, joka tallettaa nykyisen arvon. Jos emme onnistu alustamaan Kokonaisluku-oliota esittelyn yhteydessä, jäsenmuuttujan X oletusarvo on 0. Luokalle määritellään!=-operaattorifunktio: bool operator!=(const Kokonaisluku& par) const //!= -vertailu if (X == par.x) // Debuggaustulostus cout << endl // Näytetään, että olemme täällä << "operator!= palauttaa arvon false" << endl; return X!= par.x; Tämän oikeanpuolisena parametrinä on Kokonaisluku-olio ja se palauttaa bool-tyyppisen paluuarvon. Ohjelman tulostuksesta huomaat, että heti kun alku on yhtä suuri kuin loppu,!=operaattori palauttaa arvon false ja silmukan suoritus päättyy. Osoitusoperaattori määritellään seuraavasti: int operator*() const return X; //Osoitusoperaattori Tämä palauttaa nykyisen Kokonaisluku-olion jäsenmuuttujan X. Tämä funktio, sekä myös operator!=()-funktio, määritellään const-tyyppisiksi, koska ne eivät muuta olion sisältöä. Etuliitteellinen lisäysoperaattori määritellään seuraavasti: Kokonaisluku& operator++() ++X; return *this; // Etuliitteellinen lisäysoperaattori Edellisten esimerkkien keskiarvo()-funktiossa käytimme lauseketta *a++ jälkiliitteellisen operator++(int)-funktion sijaan. Kokonaisluku-luokallamme on nyt yksinkertaiset funktiot. Tässä on itse asiassa kaikki mitä tarvitsemme, jotta saamme sen toimimaan osoittimen tapaan, jolloin voimme tehdä joitakin varsin mielikuvituksellisia asioita. main()-funktiossa meillä on lause: for( ; alku!= loppu ; ++alku) cout << *alku << " "; 844 Tällaisen lauseen pitäisi näyttää jo varsin tutulta. Käytimme kovin samanlaista lausetta keskiarvo()-algoritmissamme, mutta tällöin käytimme *a++-lauseketta. Itse asiassa tulostuslauseen *alku:n korvaaminen *alku++:lla ei toimi tässä, koska emme ole määritelleet operator++(int)- funktiota, joka tukee Kokonaisluku-luokan jälkiliitteellistä muotoa. Tästä syystä käytämme muotoa *alku tulostuslauseessa ja lauseketta ++alku silmukan kontrollilausekkeessa. Itse asiassa olisimme voineet kirjoittaa:

23 Standardi mallikirjasto for( ; alku!= loppu ; ) cout << *++alku << " "; Tässä silmukka tulostaisi arvot 4-7. Lausekkeen *++alku arvo on jäsenmuuttujan alku.x arvo lisäyksen jälkeen. Iteraattoreiden välitys algoritmille Eli mitä hyötyä Kokonaisluku-luokastamme on? Mitä sellaista Kokonaisluku voi tehdä, mihin vanha kunnon int ei pysty? Katsotaanpa. Kokeile itse - Kokonaisluku-olion välityskeskiarvo<>:lle // Esimerkki 20.8 Kokonaisluku-olion keskiarvojen laskenta #include <iostream> using namespace std; class Kokonaisluku public: Kokonaisluku (int par = 0) : X(par) bool operator!=(const Kokonaisluku& par) const return X!= par.x; //!= -vertailu int operator*() const return X; Kokonaisluku& operator++() ++X; return *this; //Osoitusoperaattori // Etuliitteellinen lisäysoperaattori const Kokonaisluku operator++(int) // Jälkiliitteellinen ++-operaattori Kokonaisluku temp(*this); // Talletetaan nykyinen arvo ++X; // Vaihdetaan uuteen arvoon return temp; // Palautetaan muuttumaton talletettu arvo private: int X; ; template <typename Iter> double keskiarvo(iter a, Iter loppu) double summa = 0.0; // Tähän lasketaan summa int lkm = 0 ; for( ; a!= loppu ; lkm++) summa += *a++; // Summataan taulukon alkiot 845

24 C++ Ohjelmoijan käsikirja return summa / lkm; // Palautetaan keskiarvo int main() Kokonaisluku ensim(1); Kokonaisluku viim(11); cout << "Kokonaislukujen keskiarvo väliltä " << *ensim << " - " << -1+*viim; cout << " on " << keskiarvo(ensim, viim) << endl; return 0; Ohjelman tulostus on seuraava: Kokonaislukujen keskiarvo väliltä 1-10 on 5.5 Kuinka se toimii Emme tehneet kovinkaan suuria muutoksia. Lisäsimme operator++()-operaattorin jälkiliitteellisen muodon: const Kokonaisluku operator++(int) // Jälkiliitteellinen ++-operaattori Kokonaisluku temp(*this); // Talletetaan nykyinen arvo ++X; // Vaihdetaan uuteen arvoon return temp; // Palautetaan muuttumaton talletettu arvo Tiedämme jo entuudestaan, että toteuttaaksemme jälkiliitteellisen lisäysoperaattorin, meidän täytyy luoda kopio nykyisestä oliosta - tätä meidän ei tarvitse tehdä etuliitteellisessä muodossa. Tämä luo tietysti lisätyötä, koska tällöin kutsutaan kopiomuodostinta. Tästä syystä suurin osa seuraavista esimerkeistä käyttää etuliitteellistä muotoa aina, kun se vain on mahdollista, koska se on tehokkaampaa. Yksinkertaisen Kokonaisluku-luokkamme kohdalla tällä ei ole juuri mitään merkitystä, mutta kun teemme mallialgoritmeja, emme voi olla varmoja, miten paljon suoritusaikaa olion kopioiminen vie, kun käytämme lauseketta Iter++. Käytämme Kokonaisluku-luokkaamme seuraavissa lauseissa: Kokonaisluku ensim(1); Kokonaisluku viim(11); cout << "Kokonaislukujen keskiarvo väliltä " << *ensim << " - " << -1+*viim; cout << " on " << keskiarvo(ensim, viim) << endl; Jälleen kerran, viim on lopun yli -arvo. Meidän tulee vähentää siitä 1, jotta saamme sallitun arvon. Lisäksi, jos ensim olisi pelkkä int iteraattorin sijaan, meidän ei tarvitsisi käyttää lauseketta *ensim, jotta saamme sen arvon selville. 846 Jos oikein pysähdyt ajattelemaan, olemme tehneet jotain hyvin erilaista kutsuessamme keskiarvo()-funktiota uudella Kokonaisluku-iteraattorillamme. Kaikissa aikaisemmissa esimerkeissä keskiarvoon lasketut arvot olivat jossain - taulukoissa, vector-säiliöissä tai virroissa. Tässä esimerkissä arvoja ei ole olemassa missään. Ne lasketaan Kokonaisluku-luokan sisällä, kun keskiarvo()-algoritmi kutsuu kolmikkoa operator!=(), operator*() ja operator++().

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

Demo 6 vastauksia. 1. tehtävä. #ifndef #define D6T1 H D6T1 H. #include <iostream> using std::ostream; using std::cout; using std::endl;

Demo 6 vastauksia. 1. tehtävä. #ifndef #define D6T1 H D6T1 H. #include <iostream> using std::ostream; using std::cout; using std::endl; Demo 6 vastauksia 1. tehtävä #ifndef #define D6T1 H D6T1 H #include using std::ostream; using std::cout; using std::endl; #include using std::string; 10 template class

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

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

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

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

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

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

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

STL:n uudistukset. Seppo Koivisto TTY Ohjelmistotekniikka

STL:n uudistukset. Seppo Koivisto TTY Ohjelmistotekniikka STL:n uudistukset Seppo Koivisto TTY Ohjelmistotekniikka 2012-05-04 Sisältö 1 Muutokset säiliöihin ja uudet säiliötyypit 2 3 4 5 STL:n säiliöt Viitteet ja osoittimet ovat muuttuneet: Allocator::reference

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Chapel. TIE Ryhmä 91. Joonas Eloranta Lari Valtonen

Chapel. TIE Ryhmä 91. Joonas Eloranta Lari Valtonen Chapel TIE-20306 Ryhmä 91 Joonas Eloranta Lari Valtonen Johdanto Chapel on Amerikkalaisen Cray Inc. yrityksen kehittämä avoimen lähdekoodin ohjelmointikieli. Chapel on rinnakkainen ohjelmointikieli, joka

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

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

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

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

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

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

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

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

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

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

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ä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

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

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

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

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

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

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

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. V Geneerisyys

812347A Olio-ohjelmointi, 2015 syksy 2. vsk. V Geneerisyys 812347A Olio-ohjelmointi, 2015 syksy 2. vsk V Geneerisyys Sisältö 1. Johdanto geneerisyyteen 2. Geneeriset funktiot 3. Geneeriset luokat 4. Standard Template Library (STL) 5. IOStream-kirjasto 812347A

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

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

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 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

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

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

Ohjelmointitaito (ict1td002, 12 op) Kevät 2008. 1. Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen raine.kauppinen@haaga-helia.

Ohjelmointitaito (ict1td002, 12 op) Kevät 2008. 1. Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen raine.kauppinen@haaga-helia. Ohjelmointitaito (ict1td002, 12 op) Kevät 2008 Raine Kauppinen raine.kauppinen@haaga-helia.fi 1. Java-ohjelmoinnin alkeita Tietokoneohjelma Java-kieli ja Eclipse-ympäristö Java-ohjelma ja ohjelmaluokka

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

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

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

Listarakenne (ArrayList-luokka)

Listarakenne (ArrayList-luokka) Listarakenne (ArrayList-luokka) Mikä on lista? Listan määrittely ArrayList-luokan metodeita Listan läpikäynti Listan läpikäynti indeksin avulla Listan läpikäynti iteraattorin avulla Listaan lisääminen

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

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

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

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

1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa:

1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa: Tietorakenteet, laskuharjoitus 10, ratkaisuja 1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa: SamaLuku(T ) 2 for i = 1 to T.length 1 3 if T [i] == T [i + 1] 4 return True 5 return

Lisätiedot

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto Sisällys 18. bstraktit tietotyypit Johdanto abstrakteihin tietotyyppeihin. Pino ja jono. Linkitetty lista. Pino linkitetyllä listalla toteutettuna. 18.1 18.2 Johdanto Javan omat tietotyypit ovat jo tuttuja:

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

Rakenteiset tietotyypit Moniulotteiset taulukot

Rakenteiset tietotyypit Moniulotteiset taulukot C! Rakenteiset tietotyypit Moniulotteiset taulukot 22.2.2018 Agenda Rakenteiset tietotyypit Vilkaisu 6. kierroksen tehtäviin Moniulotteiset taulukot Esimerkki Seuraava luento to 8.3. Ilmoittautuminen ohjelmointikokeeseen

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

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

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

18. Abstraktit tietotyypit 18.1

18. Abstraktit tietotyypit 18.1 18. Abstraktit tietotyypit 18.1 Sisällys Johdanto abstrakteihin tietotyyppeihin. Pino ja jono. Linkitetty lista. Pino linkitetyllä listalla toteutettuna. 18.2 Johdanto Javan omat tietotyypit ovat jo tuttuja:

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

Olio-ohjelmointi Geneerisyys. 1. Johdanto

Olio-ohjelmointi Geneerisyys. 1. Johdanto Olio-ohjelmointi Geneerisyys Aiemmin käsiteltiin kolme monimuotoisuuden muotoa. Tässä osassa tutustutaan niistä neljänteen geneerisyyteen. Esitys perustuu pääosin teoksen [Bud] lukuun 18. Java-kielen geneerisyyden

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

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

etunimi, sukunimi ja opiskelijanumero ja näillä

etunimi, sukunimi ja opiskelijanumero ja näillä Sisällys 1. Algoritmi Algoritmin määritelmä. Aiheen pariin johdatteleva esimerkki. ja operaatiot (sijoitus, aritmetiikka ja vertailu). Algoritmista ohjelmaksi. 1.1 1.2 Algoritmin määritelmä Ohjelmointi

Lisätiedot

Osa. Listaus 2.1. HELLO.CPP esittelee C++ -ohjelman osat. 14: #include <iostream.h> 15: 16: int main() 17: {

Osa. Listaus 2.1. HELLO.CPP esittelee C++ -ohjelman osat. 14: #include <iostream.h> 15: 16: int main() 17: { Osa I 2. oppitunti C++-ohjelman osat Ennen kuin menemme yksityiskohtaisemmin sisälle C++-luokkiin, -muuttujiin jne, katsokaamme ensin, millaisista osista C++-ohjelma koostuu. Tämän tunnin aikana opit seuraavat

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

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

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

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

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

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

1 C++:n standardikirjasto

1 C++:n standardikirjasto TIE-20100 Tietorakenteet ja algoritmit 1 1 C++:n standardikirjasto Tässä luvussa käsitellään C++:n standardikirjaston tietorakenteita ja algoritmeja. Tarkoituksena on käsitellä sellaisia asioita, jotka

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

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

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

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

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti C! Perusteet 19.1.2017 Palautteesta (1. kierros toistaiseksi) Toistaiseksi helppoa Miksi vain puolet pisteistä? Vaikeinta oli ohjelmointiympäristön asennus ja käyttö Vaikeaa eroavuudet Pythonin ja C:n

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

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

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

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

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

1. Algoritmi 1.1 Sisällys Algoritmin määritelmä. Aiheen pariin johdatteleva esimerkki. Muuttujat ja operaatiot (sijoitus, aritmetiikka ja vertailu). Algoritmista ohjelmaksi. 1.2 Algoritmin määritelmä Ohjelmointi

Lisätiedot