OHJ-1150 Ohjelmointi II

Koko: px
Aloita esitys sivulta:

Download "OHJ-1150 Ohjelmointi II"

Transkriptio

1 OHJ-1150 Ohjelmointi II syksy 2013 Luentomoniste Ari Suntioinen Sisällysluettelo Sisältö OHJ-1150 Ohjelmointi II vector-tyyppi 252 Standard Template Library (STL) 261 STL-säiliöt 263 Sarjat 265 Lyhyitä esimerkkejä sarjoista 268 Assosiatiiviset säiliöt 276 Lyhyitä esimerkkejä set-rakenteesta 280 Lyhyitä esimerkkejä map-rakenteesta 283 STL-iteraattorit 288 STL-algoritmit 297 Monimutkaisten tyyppinimien yksinkertaistaminen 311 Muuttujan tyypin automaattinen määrittely 314 Abstraktiot 316 Abstraktit tietotyypit 321 Vektoriesimerkki 323 Luokat 330 Luokan esittelyn private-osa 332 Luokan esittelyn public-osa 334 Jäsenfunktioiden määrittely 336 Vektoriesimerkki hiukan toisin 338 Toteutuksen»kätkeminen» luokan sisällä 343 Mistä abstraktit tietotyypit tulevat? 347 Abstraktien tietotyyppien hyödyt 348 i Sisällysluettelo ii Funktioiden kuormittaminen 349 Funktion oletusparametrit 353 Rakentajan parametrit 356 Nimettömät eli lambda-funktiot 360 main-funktion parametrit 365 main-funktion paluuarvo 370 Modulaarisuus ja moduulit 373 TV-ohjelmatietokantaesimerkki 374 Moduulit 394 Moduulien toteuttaminen C++:lla 396 Esittely- eli hh-tiedostot 397 Määrittely- eli cc-tiedostot 402 Mistä moduulit tulevat? 405 Modulaarisuuden hyödyt 408 Automatisoitu käännös ja make 409 Versionhallinta ja rcs 415 Ajonaikaiset virheet ja gdb 422 Rekursio 427 Rekursio ohjelmoinnissa 429 Tietokoneen muisti 442 Osoittimet 446 Osoittimet struct- ja class-tietotyyppeihin 451 Taulukot ja osoittimet 453 Muuttujan näkyvyysalue ja elinikä 456 Dynaaminen muistinhallinta 460 Dynaamiset tietorakenteet 466 Dynaaminen pinotietorakenne-esimerkki 468 new:n onnistumisen tarkistaminen 475 Sisällysluettelo iii Poikkeukset 476 Pino toteutettuna dynaamisena taulukkona 482 Tietorakenteen kopiointi: alustus ja sijoitus 488 Puhelinluetteloesimerkki 499 Listat ja rekursio 511 Kahteen suuntaan linkitetty lista 521 Binäärihakupuu 527 Geneerisyys 535 Geneerinen pino-esimerkki 536 Geneerisyys C++:ssa 541

2 OHJ-1150 Ohjelmointi II 252 Esimerkki: vector-tyyppi Tutkitaan ennen varsinaiseen asiaan siirtymistä esimerkki vector-kirjastotyypin käytöstä Esimerkki johdattelee Standard Template Library (STL) -kirjaston perusajatuksiin, jotta perässä seuraava laajempi osa asiaa olisi ymmärrettävämpää Ajatellaan labyrinttia, jossa voidaan siirtyä seuraavaan risteykseen kertomalla ilmansuunta P (pohj), I (itä), E (etelä) tai L (länsi) Kirjoitetaan ohjelma, joka tulostaa optimoidun reitin, kun sille syötetään reitti, joka saadaan kirjaamalla jokainen siirtymä matkalla labyrintin alusta loppuun, kun labyrintissa on harhailtu sattumanvaraisesti Jos harhailemalla löydetty reitti on esimerkiksi: PLIPIPLIILEILLEI olisi optimoitu reitti: PI Siis aina kun reitissä on peräkkäin yhdistelmä LI, IL, PE tai EP, sievennetään se pois, koska ollaan palattu takaisinpäin OHJ-1150 Ohjelmointi II 253 Toteutettu ohjelma näyttää seuraavalta: #include <iostream> #include <vector> #include <string> using namespace std; void TulostaReitti(vector<char> reittivektori); int main( ) { string reitti; cout << "Syötä kuljettu reitti: "; getline(cin, reitti); vector<char> optimoitu_reitti; for ( string::size_type i = 0; i < reittilength( ); ++i ) { char uusi_suunta = reittiat(i); if ( optimoitu_reittisize( ) == 0 ) { optimoitu_reittipush_back(uusi_suunta); else { char edellinen_suunta = optimoitu_reittiback( ); if ( edellinen_suunta == I && uusi_suunta == L ) { optimoitu_reittipop_back( ); else if ( edellinen_suunta == L && uusi_suunta == I ) { optimoitu_reittipop_back( ); OHJ-1150 Ohjelmointi II 254 else if ( edellinen_suunta == P && uusi_suunta == E ) { optimoitu_reittipop_back( ); else if ( edellinen_suunta == E && uusi_suunta == P ) { optimoitu_reittipop_back( ); else { optimoitu_reittipush_back(uusi_suunta); TulostaReitti( optimoitu_reitti); void TulostaReitti(vector<char> reittivektori) { vector<char>::size_type i = 0; while ( i < reittivektorisize( ) ) { cout << reittivektoriat(i); ++i; cout << endl; OHJ-1150 Ohjelmointi II 255 Siitä opittua Vektori on dynaaminen korvike C++-kielen omalle taulukkotyypille ja se ratkaisee seuraavat taulukoihin liittyvät puutteet: Taulukot ovat staattisia rakenteita: alkioiden lukumäärää voi muuttaa vain kääntämällä ohjelman uudelleen Taulukkoa ei voi kopioida toiseen taulukkoon =-operaattorilla Kahta taulukkoa ei voi vertailla operaattoreilla ==,!=, <, >, <= ja >= Taulukkoa ei voi alustaa (asettaa alkuarvoa määrittelyn yhteydessä) toisesta taulukosta Taulukkoon talletettujen alkioiden lukumäärää ei yleensä saa selville, paitsi pitämällä siitä itse kirjaa Funktion parametrina taulukko käyttäytyy epäjohdonmukaisesti muihin tietotyyppeihin verrattuna: aina "viiteparametri"

3 OHJ-1150 Ohjelmointi II 256 Vektorityypin käyttämiseksi koodin alkuun on lisättävä: #include <vector> Vektorimuuttujan määrittely tapahtuu uudella erikoisella syntaksilla: vector<alkioiden_tyyppi> muuttuja; esimerkiksi: vector<int> lottonumerot; jonka jälkeen lottonumerot-muuttujaan voidaan tallentaa kokonaislukuja Vektorin loppuun voidaan lisätä alkioita yksi kerrallaan push_back-funktiolla: lottonumerotpush_back(32); jolloin vektorin koko (siihen talletettujen alkioiden lukumäärä) kasvaa yhdellä Viimeinen alkio voidaan poistaa pop_back-funktiolla: lottonumerotpop_back( ); jolloin vektorin koko pienenee yhdellä Jos vektori on tyhjä, pop_back-funktion kutsu kaataa ohjelman (tarkemmin: aiheuttaa poikkeuksen s 476, joka oletusarvoisesti keskeyttää ohjelman) OHJ-1150 Ohjelmointi II 257 Vektorin koko saadaan selville size-funktiolla: lottonumerotsize( ); Jos size-funktion paluuarvo halutaan tallettaa muuttujaan, on kyseisen muuttujan tyypin oltava: vector<alkiotyyppi>::size_type siis esimerkiksi vector<int>::size_type koko = lottonumerotsize( ); Tietotyyppi vector<alkiotyyppi>::size_type on aritmeettinen tyyppi ja sillä voidaan operoida kuten kokonaisluvuilla yleensä Syntaksi on hiukan vaikeaselkoinen, mutta kyseessä on vain yhdistelmä vektorin määrittelynotaatiota: vector<alkiotyyppi> ja merkkijonoista tuttua: string::size_type :: -notaatiota Vektorin ensimmäiseen ja viimeiseen alkioon päästään käsiksi front- ja back-funktioilla: cout << "eka alkio: " << lottonumerotfront( ) << endl << "vika alkio: " << lottonumerotback( ) << endl; Jos vektori on tyhjä, front- tai back-funktion kutsu kaataa ohjelman (aiheuttaa poikkeuksen s 476) OHJ-1150 Ohjelmointi II 258 Vektoria voi indeksoida [ ]-operaattorilla kuten taulukkoa: cout << lottonumerot[3] << endl; lottonumerot[0] = 5; Indeksointi alkaa tuttuun tapaan nollasta Operaattori [ ] ei tarkista, onko käsiteltävä alkio vektorissa vai ei tapahtuu kummia jos ei ole vastuu käyttäjällä kuten taulukoiden tapauksessa Operaattori [ ] ei lisää alkiota vektoriin, se ainoastaan käsittelee vektorissa jo ennestään olevaa tietoa Turvallisempi tapa indeksoida vektoria on at-funktio (string-tyypistä tuttu): cout << lottonumerotat(3) << endl; lottonumerotat(0) = 5; Tämä eroaa [ ]-operaattorista siten, että laiton indeksi aiheuttaa poikkeuksen (s 476) ja ohjelman suoritus keskeytyy tullaan tietoisiksi siitä, että ohjelmassa on looginen virhe OHJ-1150 Ohjelmointi II 259 Taulukoista poiketen vektori voi myös olla normaaliin tapaan funktion arvo- tai muuttujaparametri: void func1(vector<int> arvoparametri); void func2(vector<int>& muuttujaparametri); Arvoparametreihin sisältyy kuitenkin pieni kompa: arvoparametri on kopio todellisesta parametrista jos vektori on kooltaan suuri, tehdään paljon työtä, kun todellinen parametri kopioidaan muodolliseen parametriin Ongelma vältetään C++:ssa yleensä niin, että jos funktion parametri on kooltaan suuri tietorakenne, jonka ei haluta kopioituvan, tehdään muodollisesta parametrista nk vakioviite: void func3(const vector<int>& vakioviiteparametri); Nyt todellinen parametri ei kopioidu muodolliseen parametriin, mutta samalla const estää muodollisen parametrin (ja sitä kautta todellisen parametrin) muuttamisen Tämä ei tietenkään ole sama asia kuin arvoparametri, mutta riittävän lähellä useimmissa tapauksissa

4 OHJ-1150 Ohjelmointi II 260 Samaa idea toimii aina, kun funktion parametrina on tietotyyppi, jonka alkiot saattavat olla suuria merkkijonojen kanssa tehdään usein samoin: void func4(const string& vakioviitemerkkijono); Huomaa, että labyrinttiesimerkissä vakioviiteparametria ei käytetty yksinkertaisuuden vuoksi noudata silti vakioviite-ideaa omissa ohjelmissasi! Vektori voi olla myös funktion paluuarvona: vector<int> LueLottonumerotVersio1( ); lottonumerot = LueLottonumerotVersio1( ); Tähän liityy kuitenkin sama kompa kuin arvoparametreihin: paluuarvo joudutaan kopioimaan funktiosta kutsujalle toteuta suurikokoiset paluuarvot muuttujaparametrin avulla: void LueLottonumerotVersio2(vector<int>& numerovek); LueLottonumerotVersio2(lottonumerot); Nyt tulokset talletetaan muuttujaparametriin yhden kerran, eikä niitä tarvitse kopioda erikseen funktiosta palattaessa OHJ-1150 Ohjelmointi II 261 Standard Template Library (STL) C++:n standardikirjastoon kuuluu osana nk Standard Template Library (STL) STL tarjoaa ohjelmoijalle valmiit työkalut (tietorakenteita ja algoritmeja) monimutkaisten ja joustavien tietorakenteiden luontiin ja käsittelyyn kaikkea ei tarvitse tehdä alusta pitäen itse Loogisesti STL koostuu kolmesta osasta: STL-säiliöt (containers) eli varsinaiset yleiskäyttöiset tietorakenteet, joihin käsiteltävä tieto voidaan tallettaa (s 263) STL-iteraattorit (iterators) joiden avulla säiliöiden sisältämiä tietoalkioita voidaan käydä yksitellen läpi tai tarvittaessa esittää säiliön alkioiden osaväli (s 288) STL-algoritmit (algorithms) prosessoivat säiliöihin talletettuja alkioita (s 297) Se, mihin osaan säiliön sisältämistä alkioista algoritmin toimenpiteiden halutaan kohdistuvan, kerrotaan algoritmille iteraattoreiden avulla OHJ-1150 Ohjelmointi II 262 Iteraattorit luovat yhteyden säiliöiden ja algoritmien välille Tutkitaan seuraavassa kurssin kannalta riittävästi (muttei läheskään täydellisesti) kutakin STL:n osaa Päämääränä on paitsi yleissivistää niin myös tarjota hyvät työkalut STL:n käyttöön kurssilla niin, että esim harjoitustehtävissä voidaan keskittyä olennaisempaan asiaan Materiaali on tarkoituksella hiukan «käsikirjamainen», mikä toivottavasti auttaa käytännön työskentelyä STL:n kanssa OHJ-1150 Ohjelmointi II 263 STL-säiliöt Termi säiliö (container) tarkoittaa C++:ssa ja STL:ssä tietorakennetta, johon voidaan tallettaa useita jonkin muun tietotyypin alkioita STL-säiliöt ovat geneerisiä (yleiskäyttöisiä/tyyppiriippumattomia) dynaamisia (alkioden lukumäärää ei ole kiinnitetty) tietorakenteita: Geneerisyys STL ottaa vain yleisellä tasolla kantaa siihen, mitä ominaisuuksia tietotyypillä pitää olla, jotta sen alkioita voidaan tallettaa STL-säiliöihin Säiliömuuttujan määrittely tapahtuu aina säiliötyyppi<alkiotyyppi> muuttujan_nimi; syntaksilla Esimerkiksi vector, johon talletetaan opiskelijoita: vector<opiskelija> opiskelijarekisteri; jossa Opiskelija on jokin itse määritelty tietotyyppi yhden opiskelijan tietojen esittämiseen

5 OHJ-1150 Ohjelmointi II 264 Dynaamisuus Toisin kuin C++:n omalla taulukkotyyppillä (joka myös on eräänlainen säiliö), STL-säiliöillä ei ole kiinnitettyä maksimikokoa, vaan niiden koko kasvaa ja pienenee automaattisesti, kun uusia alkiota lisätään tai vanhoja poistetaan Säiliötyypit voidaan luokitella ominaisuuksiensa ja käyttäytymisensä perusteella kahteen kategoriaan: sarjat (sequence, sequence container)(s265) ja assosiatiiviset säiliöt (associative container)(s276) OHJ-1150 Ohjelmointi II 265 Sarjat (sequence, sequence container) Sarjat ovat tietorakenteita, jotka säilyttävät alkioiden järjestyksen Esimerkiksi vector-rakenteeseen ensimmäisenä lisätty alkio pysyy ensimmäisenä, jollei ohjelmoija erikseen suorita operaatiota, joka muuttaa sen paikkaa Jokaiselle sarjan alkiolle voidaan ajatella sijainnista riippuva järjestysnumero, sillä alkiot ovat rakenteessa peräkkäin (siitä nimi sequence) STL:ssä sarjoja ovat: vector (alkion lisäys ja poisto lopusta nopeaa, voidaan indeksoida kokonaisluvulla), deque (alkion lisäys ja poisto alusta ja lopusta nopeaa, voidaan indeksoida kokonaisluvulla), list (alkion lisäys ja poisto minne/mistä tahansa nopeaa, peräkkäissaantirakenne (s 213) ei voi indeksoida) ja jossain mielessä myös C++:n oma taulukkotyyppi voidaan ajatella säiliöksi, vaikka se ei olekaan STL-säiliö OHJ-1150 Ohjelmointi II 266 Sarjojen ominaisuudet ovat keskenään hiukan erilaisia kannattaa valita huolella oikea rakenne oikeaan tarkoitukseen Esimerkiksi ei ole hyvä ajatus valita tietorakenteeksi vector:ia, jos on tarve lisätä usein alkioita rakenteen alkuun (vrt edellisen sivun ominaisuuslista) Sarjatyyppeihin voidaan tallentaa minkä tahansa tietotyypin alkioita, kunhan kyseisellä tyypillä toimivat sijoitusoperaattori ja alustus toisesta samantyyppisestä muuttujasta Myös toisten STL-rakenteiden tallentaminen sarjoihin on mahdollista Kunkin sarjatyypin käyttämiseksi pitää ohjelman alkuun lisätä kyseisen tyypin include-direktiivi: #include <vector> // Voidaan käyttää vector-säiliötä, #include <deque> // deque-säiliötä ja #include <list> // list-säiliötä OHJ-1150 Ohjelmointi II 267 Tilanteita, joissa sarjat ovat käyttökelpoisia: on syystä tai toisesta tarpeen säilyttää järjestys, jossa tietoalkiot lisättiin rakenteeseen, tietoalkiot halutaan lajitella (asettaa järjestykseen), halutaan käsitellä tietoalkiota, kun sen järjestysnumero (indeksi) on tiedossa (tämä on mahdollista vain vector- ja deque-rakenteilla sekä C++-taulukoilla), halutaan tehdä järjestyksessä jotain kaikille alkioille (lineaarinen läpikäynti) ja koska vector ja deque ovat oikeastaan kehittyneempiä taulukoita niillä voidaan tehdä samoja asioita, jotka on totuttu tekemään taulukoiden avulla

6 OHJ-1150 Ohjelmointi II 268 Lyhyitä esimerkkejä sarjoista Kaikki sarjat (vector, deque ja list) ovat perusoperaatioiltaan hyvin samankaltaisia Merkittäviä poikkeuksia on oikeastaan vain kaksi: vector- ja deque-rakenteiden yksittäisiin alkioihin päästään suoraan käsiksi indeksoimalla [ ]-operaattorilla tai at-funktiolla, listan alkioita ei voi indeksoida deque- ja list-rakenteisiin alkioita voidaan lisätä ja poistaa myös alusta push_front- ja pop_frontoperaatioiden avulla, vektoriin näitä operaatioita ei voida kohdistaa Oletetaan esimerkeissä, että seuraavat on määritelty: vector<int> ivektori; deque<string> strdeque; list<opiskelija> olista; OHJ-1150 Ohjelmointi II 269 Alkioita voidaan lisätä ja poistaa lopusta: ivektoripush_back(4); strdequepush_back("the end"); olistapush_back(yhden_opiskelijan_tiedot); ivektoripop_back( ); strdequepop_back( ); olistapop_back(); Alkioita voidaan deque- ja list-rakenteen tapauksessa lisätä ja poistaa myös rakenteen alusta push_frontja pop_front-funktioilla: strdequepush_front("alussa deque oli autio ja tyhjä"); olistapush_front(joku_opiskelija); strdequepop_front( ); olistapop_front( ); Kaikkien STL-sarjojen ensimmäinen ja viimeinen alkio saadaan selville front- ja back-funktioilla: int i; i = ivektorifront( ); Opiskelija op; op = olistaback( ); Määrittelyn jälkeen rakenteet ovat automaattisesti tyhjiä (alkioiden lukumäärä nolla) OHJ-1150 Ohjelmointi II 270 vector- ja deque-rakenteita voidaan indeksoida [ ]-operaattorilla tai at-funktiolla, kun tiedetään halutun alkion indeksi: i = ivektori[4]; ivektoriat(3) = 42; string str; str = strdequeat(7); strdeque[666] = "the number of the beast"; Kaikki yksittäisiä alkioita käsittelevät toimenpiteet ovat laillisia vain, jos kyseinen alkio on olemassa: Indeksointi on laitonta luvulla, jonka mukaista alkiota rakenteessa ei ole at-funktiolla indeksointi on turvallisempaa kuin [ ]-operaattorilla, koska laiton indeksi keskeyttää ohjelman suorituksen front-, back-, pop_front- ja pop_back-funktiot keskeyttävät ohjelman, jos rakenne on tyhjä Edellä «ohjelman keskeyttäminen» tarkoittaa täsmällisesti ottaen poikkeuksen heittämistä, mutta siitä lisää myöhemmin (s476) OHJ-1150 Ohjelmointi II 271 Rakenteessa olevien alkoiden lukumäärä saadaan selville size-funktiolla tätä voidaan hyödyntää vector- ja deque-rakenteiden läpikäynnissä: // Huomaa että idea on sama kuin taulukoiden // läpikäynnissä: silmukkamuuttuja juoksee // järjestyksessä läpi kaikkien alkioiden indeksit deque<string>::size_type i = 0; while ( i < strdequesize( ) ) { cout << strdequeat(i) << " "; ++i; cout << endl; list-rakenteita voi käydä läpi vain nk iteraattoreiden avulla niistä lisää hetken kuluttua (s288) Funktiolla empty voidaan testata onko rakenne tyhjä (ei sisällä yhtään alkiota): if ( strdequeempty( ) ) { // Ei alkioita while (!olistaempty( ) ) { // olista:ssa on alkioita jäljellä

7 OHJ-1150 Ohjelmointi II 272 Kaikki STL-säiliöt määrittelevät sijoitusoperaation ja alustuksen toisesta samantyyppisestä säiliöstä: list<char> merkkilista_1; // merkkilista_2:n alkuarvoksi sama kuin // mitä merkkilista_1 sisältää list<char> merkkilista_2(merkkilista_1); // Sijoitetaan kaikki merkkilista_2:n // alkiot merkkilista_1:een merkkilista_1 = merkkilista_2; Alustukseen (siis alkuarvon asettamiseen määrittelyn yhteydessä) on muitakin vaihtoehtoja: Alkioiden lukumäärä kerrottu: // 500 kappaletta merkkijonoja vector<string> jasenet(500); Alkioiden lukumäärä ja alkuarvo kerrottu: // 24 reaalilukua, jotka alustettu nollaksi deque<double> lampotilat( 24, 00); Jos sarjarakenteelle ei määrittelyn yhteydessä kerrota alkioiden lukumäärää, rakenne on aluksi tyhjä (mutta alkioitahan voi lisätä) Vaikka alkioiden lukumäärä on kerrottu, alkioita voidaan silti myös lisätä ja poistaa OHJ-1150 Ohjelmointi II 273 Kaikille STL-sarjoille voi määrittelyn yhteydessä antaa alkuarvon (alkusisällön) alustuslistan avulla: vector<int> ivec = { 4, 7, 1 ; deque<string> strdeq = { "x", "yyyy" ; list<double> dlist = { 12, 34, 56, 78 ; Ajatus on täysin analoginen esimerkiksi structtyyppisten muuttujien alustukseen verrattuna: aaltosulkeiden sisällä luetellaan pilkuilla eroteltuina kaikki alustusarvot/-alkiot Säiliön alkukoko (siis size( )-funktion paluuarvo) on luonnollisesti sama kuin alustusalkioiden lukumäärä Alustuslistan avulla alustettuihin säiliöihin voi lisätä ja niistä voi poistaa alkioita normaalisti Alustuslistan sisältö voidaan myös sijoittaa entuudestaan olemassa olevaan muuttujaan: ivec = { 9, 8, 7, 6, 5 ; strdeq = { "aaa", "bbb", "ccc" ; dlist = { 99, 88, 77 ; Tämä on uuden c++-standardin tuoma ominaisuus, joka toimii Ohjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä Jos osallistut jatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissa opetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio kääntäjästä, eikä tämä ominaisuus toimi Älä siis tule liian riippuvaiseksi ominaisuuden olemassaolosta OHJ-1150 Ohjelmointi II 274 Sijoituksen jälkeen säiliö sisältää pelkästään alustuslistan alkiot samassa järjestyksessä ja sen koko on sama kuin alustuslistan alkioiden lukumäärä Alustuslistan alkioiden ei ole pakko olla literaalisia arvoja, vaan esimerkiksi seuraava on mahdollista: int func(string mjono) { int luku; ivec = { 1, func("abc"), 2, luku, 3 ; Alustuslista voi myös olla funktion todellisena parametrina, jos muodollisen parametrin tyyppi on STL-sarja: void tulosta(const vector<int>& v) { tulosta( { func("abc"), 2, luku ); OHJ-1150 Ohjelmointi II 275 Säiliö voidaan tyhjentää clear-funktiolla ivecclear( ); jonka jälkeen rakenteessa ei ole yhtään alkiota (mutta lisäys on edelleen mahdollista) Kahta samantyyppistä sarjaa voi tutkia vertailuoperaattoreilla: if ( merkkilista_1 == merkkilista_2 ) { // Listat yhtäsuuria: samat alkiot // samassa järjestyksessä Nämä olivat perusoperaatiot STL-sarjoille Muihin mahdollisuuksiin palataan iteraattorien (s288) ja algoritmien (s297) yhteydessä Kannattaa myös tutustua C++-kirjastoreferenssiin Tämä on uuden c++-standardin tuoma ominaisuus, joka toimii Ohjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä Jos osallistut jatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissa opetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio kääntäjästä, eikä tämä ominaisuus toimi Älä siis tule liian riippuvaiseksi ominaisuuden olemassaolosta

8 OHJ-1150 Ohjelmointi II 276 Assosiatiiviset säiliöt (associative container) Assosiatiiviset säiliöt järjestävät rakenteeseen talletetut tiedot omien tarpeidensa mukaan: siten että lisäys- ja hakuoperaatiot ovat mahdollisimman nopeita Rakenne ei ole sellainen, jossa alkioiden voisi ajatella olevan peräkkäisjärjestyksessä, joten niiden järjestysnumerosta tai paikasta ei voi puhua Assosiatiiviseen säiliöön tieto talletetaan (haku)avaimen perusteella myös haku tapahtuu saman avaimen avulla STL:ssä assosiatiivisia säiliöitä ovat: set: analoginen matemaattisen joukon kanssa, multiset: joukko, johon sama alkio voi kuulua useammin kuin kerran, map: liittää avainarvoon varsinaisen tietoalkion ja multimap: yhteen avainarvoon voi liittyä useampia tietoalkioita OHJ-1150 Ohjelmointi II 277 Kuten sarjojen kanssa, assosiatiivisten säiliöiden käyttöönotto tapahtuu include-direktiivillä: #include <set> // sekä set että multiset #include <map> // sama sekä map että multimap set- ja multiset-rakenteet vaativat, että talletettavalle avaimelle toimivat sijoitusoperaattori, alustus ja vertailu toisen samantyyppisen tietoalkion kanssa map- ja multimap-rakenteisiin talletettavalta tiedolta vaaditaan, että sekä avaimelle että varsinaiselle tietoalkiolle toimivat sijoitus ja alustus toisesta samantyyppisestä tietoalkiosta Lisäksi avaimelle pitää toimia vertailu map- ja multimap-rakenteisiin talletettava tieto koostuu kahdesta osasta: avaimesta ja varsinaisesta tietoalkiosta map- ja multimap-säiliömuuttujan määrittely on muotoa: map<avaintyyppi, alkiotyyppi> map_muuttuja; multimap<avaintyyppi, alkiotyyppi> multimap_muuttuja; OHJ-1150 Ohjelmointi II 278 Ideoita assosiatiivisten säiliöiden käyttökohteista: set kun on tarpeen selvittää kuuluuko alkio joukkoon vai ei, mutta avaimeen ei liity lisäinformaatiota Esimerkiksi arvottujen lottonumeroiden joukko: set<int> arvotut_lottonumerot; multiset jos on tarpeen pitää kirjaa joukosta tietoalkioita, kun tietyn niminen/numeroinen/tunnisteinen alkio voi esiintyä joukossa useammin kuin kerran Esimerkiksi kauppakassin sisältö: multiset<string> ostokset; voi sisältää vaikka "maito"-nimisen tuotteen useammin kuin kerran map sitoo yksikäsitteisen avainarvon ja siihen liittyvän tiedon toisiinsa Esimerkiksi avaimena opiskelijanumero (yksikäsitteinen) ja arvona kyseisen opiskelijan muut tiedot: map<int, Opiskelija> opiskelijarekisteri; OHJ-1150 Ohjelmointi II 279 multimap kuten map, mutta avain ei ole yksikäsitteinen multimap voi sisältää useita identtisiä avaimia, joihin liittyy eri arvo Esimerkiksi puhelinluettelo, jossa voi olla useita samannimisiä ihmisiä (avain, joka ei ole yksikäsitteinen), joilla kullakin on oma puhelinnumeronsa: multimap<string, int> puhelinluettelo; Vaikka multiset ja multimap ovat hyödyllisiä, niihin ei kurssilla puututa sen tarkemmin Kannattaa myös pitää mielessä, että STL-säiliöiden (sekä sarjojen että assosiatiivisten säiliöiden) alkiot voivat olla toisia STL-säiliöitä, esimerkiksi: vektori jonka alkiot ovat vektoreita: vector<vector<double>> ratkaisumatriisi; map jonka alkiot ovat listoja: map<string, list<double>> pankkitilin_otot_ja_panot;

9 OHJ-1150 Ohjelmointi II 280 Lyhyitä esimerkkejä set-rakenteesta Määritellään joukko, johon voi tallentaa merkkijonoja: set<string> laiva_on_lastattu; Määrittelyn jälkeen joukko on automaattisesti tyhjä Joukoille toimii alustus ja sijoitus toisesta samantyyppisestä joukosta: set<int> lottonumerot_1; set<int> lottonumerot_2(lottonumerot_1); lottonumerot_1 = lottonumerot_2; Joukkoon saadaan lisättyä uusi alkio insert-funktiolla: laiva_on_lastattuinsert("koirilla"); Lisäys toimii silloinkin, jos alkio kuului joukkoon jo entuudestaan se vaan ei tee mitään Alkion kuulumista joukkoon voi tutkia find-funktiolla: if (laiva_on_lastattufind(sana) == laiva_on_lastattuend( ) ) { // sana ei kuulu laiva_on_lastattu-joukkoon else { // sana-merkkijono oli joukossa jo entuudestaan OHJ-1150 Ohjelmointi II 281 Funktio find palauttaa nk iteraattorin näistä hetken päästä lisää (s288) Tässä vaiheessa riittää tietää, että paluuarvo on yhtäsuuri kuin kyseisen joukon end-funktion paluuarvo vain, jos parametri ei kuulu joukkoon Yksittäinen alkio voidaan poistaa erase-funktiolla: if (laiva_on_lastattufind(sana) == laiva_on_lastattuend( ) ) { // Sana ei kuulu joukkoon: ei voi poistaa else { laiva_on_lastattuerase( sana); Poistonkin voi tehdä ilman, että erikseen tarkastaa, kuuluuko poistettava alkio joukkoon vai ei jos ei kuulu, ei tehdä mitään Joukosta voidaan poistaa kaikki alkiot funktiolla clear tuloksena tyhjä joukko: laiva_on_lastattuclear( ); OHJ-1150 Ohjelmointi II 282 Keskenään samantyyppisiä joukkoja voi tutkia vertailuoperaattoreilla: if ( lottonumerot_1!= lottonumerot_2 ) { // Joukkojen alkioissa eroja else { // Joukoissa täsmälleen samat alkiot Joukkoon kuuluvien alkioiden lukumäärän saa selville size-funktiolla: if ( lottonumerot_1size( )!= LOTTONUMEROITA ) { // Jokin mättää: väärä määrä lottonumeroita Funktio empty selvittää, onko joukko tyhjä Kaikki mitä sivuilla todettiin alustuslistoista, pätee sellaisenaan myös set-rakenteisiin Joukon alkioiden läpikäynti toteutetaan iteraattorin avulla (s288) Tämä on uuden c++-standardin tuoma ominaisuus, joka toimii Ohjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä Jos osallistut jatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissa opetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio kääntäjästä, eikä tämä ominaisuus toimi Älä siis tule liian riippuvaiseksi ominaisuuden olemassaolosta OHJ-1150 Ohjelmointi II 283 Lyhyitä esimerkkejä map-rakenteesta Muista esitellyistä STL-rakenteista poiketen, maprakenteen määrittely sisältää sekä hakuavaimen että varsinaisen talletettavan tiedon tyypit: map<string, unsigned int> puhelinnumerot; Määrittelyn jälkeen map-rakenne on tyhjä Myös map-rakentelle on määritelty alustus ja sijoitus toisesta samantyyppisestä rakenteesta: map<string, double> hintalista_1; map<string, double> hintalista_2(hintalista_1); hintalista_1 = hintalista_2; map-rakennetta voi indeksoida [ ]-operaattorilla kuten vector- ja deque-rakenteita, mutta indeksin tyypin on oltava sama kuin hakuavaimen tyyppi: puhelinnumerot["matti"] = ; cout << nimi << " " << puhelinnumerot[nimi] << endl;

10 OHJ-1150 Ohjelmointi II 284 Jälkimmäiseen käyttötilanteeseen sisältyy vaara: kun map:iä indeksoidaan, indeksoitu alkio lisätään rakenteeseen, vaikka se ei olisi siellä ennestään Jos tätä ei haluta, vaan tarkotus on käyttää arvoa vain jos se on rakenteessa, siitä on ensin varmistuttava: if (puhelinnumerotfind(nimi) == puhelinnumerotend( ) ) { // Hakuavain nimi ei ole luettelossa else { cout << nimi << " " << puhelinnumerot[nimi] << endl; Käytetty "find == end"-mekanismi toimii saman idean mukaisesti kuin joukkojen tapauksessa Kun tuon vaaran pitää mielessä, indeksointi on helpoin tapa käsitellä map-rakennetta Lisäksi on hyvä oivaltaa, että const- tai const-viitemap:iä ei voi indeksoida [ ]-operaattorilla Hakuavain-tieto -parin voi poistaa erase-funktiolla: if ( puhelinnumeroterase("ari") ) { // Poisto onnistui else { // Hakuavain "Ari" ei map:issä, epäonnistui OHJ-1150 Ohjelmointi II 285 Tarkasti ottaen em erase palauttaa poistettujen alkioiden lukumäärän, joka on map-rakenteen tapauksessa 0 tai 1 Kokonaislukujahan voi käyttää C-kielen perintönä ehdoissa nolla on false kaikki muut true Poiston voi myös tehdä tarkistamalla ensin käsin, onko avain rakenteessa: if (puhelinnumerotfind("ari")!= puhelinnumerotend( ) ) { puhelinnumeroterase("ari"); else { // Hakuavain "Ari" ei ole rakenteessa Rakenne tyhjennetääm clear-funktiolla: puhelinnumerotclear( ); Rakenteeseen talletettujen alkioiden lukumäärä ja tieto siitä, onko rakenne tyhjä, tuttuun tapaan sizeja empty-funktioilla OHJ-1150 Ohjelmointi II 286 Myös map-rakenteen alkioiden läpikäynti on toteutettava iteraattorien avulla, kuten set-rakenteellakin tehtiin (s288) Edellä annetut esimerkit ovat hyvin alkeellinen tapa käsitellä map-rakennetta Joustavampi tapa on pair-tyypin käyttö: pair<avaintyyppi, alkiotyyppi> tietopari; joka on vain STL:n kompakti tapa ilmaista, että muuttujan tietopari tyyppi on seuraava tietue: struct { avaintyyppi first; alkiotyyppi second; ; Edellisen kaltaisia pareja saadaan joustavasti luotua make_pair-funktiolla: pair<string, unsigned int> tietopari; tietopari = make_pair("topi", ); Koska parit ovat struct-rakenteita, voidaan niitä käsitellä myös ""-operaattorilla: tietoparifirst = "Topi"; tietoparisecond = ; OHJ-1150 Ohjelmointi II 287 Parin sisältämä hakuavain ja tietoalkio saadaan lisättyä map-rakenteeseen: puhelinnumerotinsert(tietopari); tai ilman tietopari-apumuuttujaa: puhelinnumerotinsert(make_pair("topi", ) ); Vaikka pari-käsite tässä vaiheessa tuntuu tarpeettoman monimutkaiselta, käy ilmi, että maprakenteita iteraattorien avulla käsiteltäessä tietämys pair-tyypistä on välttämätön paha Kaikki mitä sivuilla todettiin alustuslistoista, pätee sellaisenaan myös map-rakenteisiin yhdellä pienellä lisäyksellä Koska map-rakenne sisältää todellisuudessa pareja, on alustuslistankin muodostuttava pareista: map<string, unsigned int> puhelinnumerot = { { "Matti", , { "Maija", ; Tämä on uuden c++-standardin tuoma ominaisuus, joka toimii Ohjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä Jos osallistut jatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissa opetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio kääntäjästä, eikä tämä ominaisuus toimi Älä siis tule liian riippuvaiseksi ominaisuuden olemassaolosta

11 OHJ-1150 Ohjelmointi II 288 STL-iteraattorit Iteraattorit ovat STL-kirjaston tarjoamia tietotyyppejä, joiden avulla voidaan käsitellä (tutkia ja muuttaa) säiliöihin talletettuja alkioita Tarkoituksena on tarjota yhdenmukaiset työkalut, jotta kaikkia säiliöitä voidaan käsitellä lähes samoin Iteraattoria voi ajatella kirjanmerkkinä, joka muistaa yhden säiliössä olevan alkion sijainnin Kahdella iteraattorilla voidaan esittää jokin osaväli säiliöön talletetuista alkioista: mikä on osavälin esimmäinen alkio ja mikä viimeinen alkio Jokainen STL-säiliö tarjoaa ohjelmoijalle joukon tietotyyppejä ja funkioita, joilla voidaan käsitellä kyseiseen säiliötyyppiin liittyviä iteraattoreita Tavallisimmin tarvitut iteraattorityypit ovat: vector<alkiotyyppi>::iterator deque<alkiotyyppi>::iterator list<alkiotyyppi>::iterator set<alkiotyyppi>::iterator map<avaintyyppi, alkiotyyppi>::iterator OHJ-1150 Ohjelmointi II 289 Edellisiä iteraattorityyppejä oleviin muuttujiin voidaan tallentaa tieto alkion sijaintipaikasta säiliössä Säiliötyypin jäsenfunktio begin kertoo säiliön ensimmäisen alkion sijainnin Jäsenfunktio end palauttaa iteraattorin joka osoittaa rakenteen loppuun: end ei osoita lailliseen alkioon vaan on eräänlainen loppumerkki Esimerkiksi yhdeksänalkioinen kokonaislukuvektori: vector<int> ivek(9) ivekbegin( ) ivekend( ) Iteraattorin osoittamaa alkiota voidaan käsitellä kohdistamalla iteraattoriin unaarinen *-operaattori Iteraattori saadaan siirrettyä osoittamaan säiliön seuraavaan alkioon ++-operaattorilla ja edelliseen alkioon -operaattorilla ==- ja! =-operaattoreilla voidaan testata, osoittavatko kaksi iteraattoria samaan vai eri alkioon OHJ-1150 Ohjelmointi II 290 Esimerkiksi koodinpätkä, joka käy vektorin alkiot läpi alusta loppuun, kertoo jokaisen alkion kahdella ja tulostaa muutetut alkiot näytölle: vector<int> lukuvektori; vector<int>::iterator iter = lukuvektoribegin( ); while ( iter!= lukuvektoriend( ) ) { *iter = 2 * *iter; // Alkion muuttaminen cout << *iter << endl; // Alkion arvon käyttäminen ++iter; // Seuraavaan alkioon siirtyminen Edellisestä näkyy selvästi, kuinka end-iteraattori ei enää osoita käsittelyä vaativaan alkioon, vaan sen avulla testataan, joko koko rakenne on käyty läpi Usein end-arvoa käytetään myös funktion paluuarvona osoittamaan, että säiliöstä ei löytynyt etsittyä alkiota (s280) Edellä esitetty läpikäyntimekanismi toimii kaikilla STL-säiliöillä toisena esimerkkinä joukon alkioiden tulostaminen (vaihtelun vuoksi for-silmukka): set<string> nimet; set<string>::iterator it; for ( it = nimetbegin( ); it!= nimetend( ); ++it ) { cout << *it << endl; OHJ-1150 Ohjelmointi II 291 Jos iteraattori osoittaa alkioon, joka on tietue (tai myöhemmin myös luokka), voidaan tietueen kenttiin viitata suoraan > -operaattorilla Kuten map-rakenteesta puhuttaessa todettiin, sen alkiot ovat todellisuudessa tietueita, jotka koostuvat hakuavaimesta (first-kenttä) ja varsinaisesta informaatiosta (second-kenttä) Tulostetaan puhelinluettelo-map-rakenteesta kaikkien "T"-kirjaimella alkavien puhelinnumerot: map<string, unsigned int> puhelinnumerot; map<string, unsigned int>::iterator puhiter; puhiter = puhelinnumerotbegin( ); while ( puhiter!= puhelinnumerotend( ) ) { // Avainkenttä: first (string) if ( puhiter >firstat(0) == T ) { // Informaatio: second (unsigned int) cout << puhiter >second << endl; ++puhiter;

12 OHJ-1150 Ohjelmointi II 292 OHJ-1150 Ohjelmointi II 293 Tähän mennessä esiteltyjen iteraattoreiden avulla voidaan operoida vain sellaisiin säiliöihin, joita on sallittua muuttaa ongelma jos funktioiden muodolliset parametrit ovat tehokkyyssyistä constvakioviitteitä Tämä ratkeaa seuraavien iteraattorityyppien avulla: vector<alkiotyyppi>::const_iterator deque<alkiotyyppi>::const_iterator list<alkiotyyppi>::const_iterator set<alkiotyyppi>::const_iterator map<avaintyyppi, alkiotyyppi>::const_iterator Esimerkiksi funktio, joka laskee kokonaislukulistan alkioiden summan: int Summaa(const list<int>& lukulista) { int summa = 0; list<int>::const_iterator it = lukulistabegin( ); while ( it!= lukulistaend( ) ) { summa = summa + *it; ++it: return summa; Kaikki STL-säiliöt map-rakennetta lukuunottamatta voidaan alustaa iteraattorien avulla toisista säiliöistä: vector<double> reavek; list<double> realista( reavekbegin( ), reavekend( ) ); Yllä siis realista alustetaan samassa järjestyksessä ja samoilla lukuarvoilla kuin mitä muuttujassa reavek oli Kannattaa huomata, että alustuksessa ei ole pakko käyttää begin- ja end-funktioita, vaan mikä tahansa iteraattoriväli käy Esimerkiksi lista olisi voitu alustaa siten, että vektorin ensimmäinen ja viimeinen alkio olisi jätetty pois: vector<double> reavek; vector<double>::iterator valin_alku = reavekbegin( ); ++valin_alku; vector<double>::iterator valin_loppu = reavekend( ); valin_loppu; list<double> realista( valin_alku, valin_loppu); const_iterator-tyypit eivät salli iteraattorin osoittaman alkion arvon muuttamista OHJ-1150 Ohjelmointi II 294 Tai jos sattuu tietämään, että vector- ja dequeiteraattoreihin voi lisätä tai vähentää kokonaisluvun ja saada siten uuden iteraattorin, joka osoittaa kyseisen lukumäärän verran alkioita eteentai taaksepäin Edellinen esimerkki menisi siis lyhemmin: list<double> realista( reavekbegin( ) + 1, reavekend( ) 1); Vaikka tähän saakka on jatkuvasti käytetty ilmaisua «iteraattori osoittaa säiliön alkioon»: vector<int> ivek(9) ivekbegin( ) ivekbegin( )+4 ivekend( ) Iteraattorien voi myös ajatella osoittavan alkioiden väliin, jolloin unaarinen *-operaattori ja > -operaattori tulkitaan siten, että halutaan käsitellä heti välin perässä seuraavaa alkiota: vector<int> ivek(9) OHJ-1150 Ohjelmointi II 295 Tämä näkemys auttaa tulkitsemaan tilannetta paremmin silloin, kun kahden iteraattorin avulla esitetään osajoukko säiliön peräkkäisistä alkioista Jos välttämättä haluaa ajatella iteraattorien osoittavan alkioihin välien sijaan, pitää kahdella iteraattorilla esitetyt alkiojoukot aina tulkita ylhäältä avoimiksi: siis ylempi osoitettu alkio ei enää kuulu käsiteltäviin alkioihin Kumpikin esitetty tulkinta on vain tapa ajatella asiaa, kannattaa valita se, joka tuntuu itselle luonnollisimmalta Kirjallisuudessa näkee molempia tapoja, joten kannattaa olla aina tarkkana siitä, kumpaa tapaa kirjoittaja noudattaa Vielä yksi olennainen asia, joka on syytä pitää mielessä: jos säiliöön on lisätty tai siitä on poistettu alkioita, et voi luottaa siihen, että ennen muutosta talletetut iteraattorit toimisivat muutoksen jälkeen oikein ivekbegin( ) ivekbegin( )+4 ivekend( )

13 OHJ-1150 Ohjelmointi II 296 OHJ-1150 Ohjelmointi II 297 Kärjistettynä esimerkkinä: jos iteraattori osoittaa alkioon, joka poistetaan säiliöstä, mihin iteraattori osoittaa poiston jälkeen? Nämä olivat perusideat STL-iteraattoreista Muihin käyttötarkoituksiin palataan heti jatkossa algoritmien yhteydessä Myös C++-kirjastoreferenssi kertoo lisää yksityiskohtia: STL-algoritmit STL-kirjasto algorithm tarjoaa valmiina yleisimmät operaatiot, joita säiliön sisältämille alkioille on tarpeen tehdä Algoritmikirjaston käyttämiseksi on koodiin lisättävä: #include <algorithm> STL:n valmiit algoritmit ovat geneerisiä: ne eivät ota kantaa säiliön tyyppiin, vaan ne osaavat operoida millä tahansa säiliöllä, kunhan säiliön alkioihin voidaan viitata iteraattorien avulla Käsiteltäväksi haluttu osa säiliön alkoista kerrotaan algoritmifunktiolle iteraattorivälin avulla jokaisella funktiolla on aina vähintään kaksi iteraattoriparametria Joskus iteraattoriparametreja on useampiakin, jos funktio tallettaa tuloksia johonkin toiseen säiliöön OHJ-1150 Ohjelmointi II 298 OHJ-1150 Ohjelmointi II 299 Esimerkiksi algoritmi (siis funktio) sort osaa lajitella vector- ja deque-rakenteen kasvavaan järjestykseen, kunhan sille kerrotaan iteraattoreilla lajiteltavaksi haluttu osaväli: vector<int> ivek; deque<double> ddeq; sort(ivekbegin( ), ivekend( ) ); sort(ddeqbegin( ), ddeqend( ) ); Listaa ei voi lajitella sort-funktiolla (sort-algoritmi ei osaa lajitella peräkkäissaantirakennetta), mutta sillä on jäsenfunktio sort, joka osaa: list<string> slist; slistsort( ); Assosiatiivisia säiliöitä ei voi lajitella, sillä kuten muistetaan, set- ja map-rakennetta käytettäessä ohjelmoija ei voi vaikuttaa alkioiden järjestykseen STL-iteraattorit on siinäkin suhteessa nerokkaasti määritelty käsite, että tarpeen vaatiessa myös C++:n omia taulukoita voi ajatella sarjoina ja käsitellä algoritm-kirjaston funktioilla iteraattorimaisesti begin-iteraattoriksi tulkitaan tällöin taulukkomuuttujan_nimi ja end-iteraattoriksi lausekkeen taulukkomuuttujan_nimi + alkioiden_lukumäärä arvo Esimerkiksi kokonaislukutaulukko voitaisiin lajitella sort-funktiolla: int itaulukko[1000]; sort(itaulukko, itaulukko ); Selitys sille, mitä lauseke itaulukko oikeasti tarkoittaa, selviää vasta myöhemmin, kun tutustutaan osoittimiin (s446) Seuraavassa on esiteltynä hyvin lyhykäisesti käyttökelpoisimpia algorithm-kirjaston funktioita Kannattaa pitää mielessä, että kaikissa tapauksissa begin- ja end-iteraattorien paikalla mikä tahansa kahden iteraattorin esittämä osaväli on kelvollinen

14 OHJ-1150 Ohjelmointi II 300 count laskee säiliössä olevien tietyn arvoisten alkioiden lukumäärän: list<string> vihamiehet: cout << count(vihamiehetbegin( ), vihamiehetend( ), "Aki") << " kappaletta Aki-nimisiä vihamiehiä!" << endl; find etsii säiliöstä haluttua alkiota ja palauttaa iteraattorin ensimmäiseen löytämäänsä alkioon tai end-iteraattorin, jos ei löydy: deque<string> potilasjono; deque<string>::iterator iter; iter = find(potilasjonobegin( ), potilasjonoend( ), "Hanski"); if ( iter == potilasjonoend( ) ) { // Ei ole Hanskia potilasjonossa else { // Hanski löytyi ja sijaitse iter:in osoittamassa // paikassa: tulostetaan ja poistetaan jonosta cout << *iter << endl; potilasjonoerase(iter); Edellisessä erase ei ole algorithm-kirjaston funktio, vaan kaikille STL-säiliöille määritelty funktio, jolla iteraattorin osoittama alkio poistetaan säiliöstä (vrt OHJ-1150 Ohjelmointi II 301 min_element ja max_element etsivät säiliöstä arvoltaan pienimmän tai suurimman alkion ja palauttavat iteraattorin kyseiseen alkioon: set<int> lukum; set<int>::iterator pienin_it; pienin_it = min_element(lukumbegin( ), lukumend( ) ); cout << "Pienin lukumäärä: " << *pienin_it << endl; Seuraavat alkioita tai niiden järjestystä muuttavat algoritmit toimivat vain sarjoilla (miksi?) remove "poistaa" (siirtää loppuun) säiliöstä kaikki tietyn arvoiset alkiot: deque<string> potilasjono; remove(potilasjonobegin( ), potilasjonoend( ), "Hanski"); replace korvaa tietyt arvot uusilla arvoilla: replace(sanalistabegin( ), sanalistaend( ), "TTKK", "TTY"); jossa siis kaikki sanat "TTKK" korvataan sanalla "TTY" reverse kääntää alkioiden järjestyksen takaperin: reverse(potilasjonobegin( ), potilasjonoend( ) ); // Taulukon alkiot takaperin int luvut[100]; reverse(luvut, luvut + 100); OHJ-1150 Ohjelmointi II 302 random_shuffle sekoittaa alkiot satunnaiseen järjestykseen: vector<pelikortti> korttipakka(52); random_shuffle(korttipakkabegin( ), korttipakkaend( ) ); copy kopioi säiliön alkiot johonkin toiseen säiliöön: list<double> lukulista; vector<double> lukuvektori(lukulistasize( ) ); copy(lukulistabegin( ), lukulistaend( ), lukuvektoribegin( ) ); Kopioinnin kohteessa (siis siellä minne alkiota kopioidaan) pitää olla valmiiksi tilaa tarjolla yllä lukuvektori on valmiiksi alustettu sisältämään yhtä monta alkiota kuin lukulista Tämä pätee kaikkiin STL-algoritmeihin, jotka tallettavat tuloksia säiliöön: kohdesäiliössä pitää olla valmista tilaa kaikille talletettaville alkioille Tämä voidaan välttää nk lisäysiteraattorien avulla: list<double> lukulista; vector<double> lukuvektori; copy(lukulistabegin( ), lukulistaend( ), back_inserter(lukuvektori) ); OHJ-1150 Ohjelmointi II 303 Jolloin kaikki tallennukset lisäävät uuden alkion lukuvektorin loppuun lukuvektorin koko kasvaa niin monella alkiolla kuin mitä copy kopioi Tämä toimii myös, jos kohdesäiliössä oli alkioita jo ennestään Kahden säiliön sisältämät alkiot voidaan siis yhdistää kolmanteen: list<string> ekasailio; vector<string> tokasailio; deque<string> kolmassailio; copy(ekasailiobegin( ), ekasailioend( ), back_inserter(kolmassailio) ); copy(tokasailiobegin( ), tokasailioend( ), back_inserter(kolmassailio) ); Tämä ei ole ainoa eikä välttämättä paraskaan tapa yhdistää säiliöitä, mutta havainnollistaa lisäysiteraattoria mukavasti On myös olemassa front_inserter-funktio, joka palauttaa säiliön alkuun lisäykset suorittavan iteraattorin lisättyjen alkioiden järjestys muuttuu päinvastaiseksi

15 OHJ-1150 Ohjelmointi II 304 OHJ-1150 Ohjelmointi II 305 for_each-algoritmi kutsuu käyttäjän määräämää aliohjelmaa kaikille iteraattorivälin alkioille: set<string> sanajoukko; cout << "Joukkoon kuuluvat sanat: " << endl; for_each(sanajoukkobegin( ), sanajoukkoend( ), TulostaYksiString); Huomaa, että for_each:ille on annettu parametrina TulostaYksiString-funktio, ei suinkaan TulostaYksiString-funktion paluuarvo Kyseessä on nk funktioparametri TulostaYksiString-funktio pitää määritellä seuraavasti, jotta sen voisi antaa for_each:ille parametrina: void TulostaYksiString(const string& str) { cout << str << endl; for_each:ille parametrina annettavan funktion on noudatettava seuraavia sääntöjä: Paluuarvon tyyppi on void Parametrin tyyppi on sama kuin käsiteltävän säiliön alkioiden tyyppi Jos for_each:in kutsuman funktion muodollinen parametri on viite- eli muuttujaparametri, funktio voi muuttaa alkuperäisen säiliön alkioita: list<int> lukulista; // Kerrotaan kaikki lukulistan alkiot luvulla 2 for_each(lukulistabegin( ), lukulistaend( ), KerroKahdella); jossa KerroKahdella on määritelty seuraavasti: void KerroKahdella(int& luku) { luku = 2 * luku; transform kuvaa säiliön alkioiden arvot uusiksi arvoiksi ja tallettaa saadut arvot toiseen säiliöön: list<string> sanat; vector<int> pituudet; transform(sanatbegin( ), sanatend( ), back_inserter(pituudet), MerkkijononPituus); jossa MerkkijononPituus olisi määritelty: int MerkkijononPituus(const string& str) { return strlength( ); OHJ-1150 Ohjelmointi II 306 OHJ-1150 Ohjelmointi II 307 Edellinen koodi siis kuvaisi MerkkijononPituusfunktion avulla sanat-listassa olevat merkkijonot niiden pituuksiksi ja tallettaisi saadut pituudet samassa järjestyksessä pituudet-vektoriin transform-algoritmin kanssa käytettävän kuvausfunktion täytyy noudattaa seuraavia sääntöjä: Parametrin tyyppi on sama kuin lähtöarvosäiliön alkioiden tyyppi Paluuarvon tyyppi on sama kuin kohdesäiliön alkioiden tyyppi Lähes kaikista algorithm-kirjaston funktioista on versio, jonka toimintaa voidaan säätää funktioparametrin avulla Esimerkiksi count-funktiosta on olemassa versio count_if, joka laskee vain tietyn ehdon täyttävien alkioiden lukumäärän: set<int> joukko; // Montako paritonta luku on joukossa int parittomia = count_if(joukkobegin( ), joukkoend( ), OnkoPariton); Edellisessä OnkoPariton olisi määritelty: bool OnkoPariton(int luku) { // Pariton luku on sellainen, jonka jako- // jäännös kahdella jaettaessa ei ole nolla return luku % 2!= 0; Tapauksissa joissa edellisen kaltainen valintafunktio on käytettävissä, sen täytyy noudattaa seuraavia sääntöjä: Paluuarvon tyyppi on bool Parametrin tyyppi on sama kuin operoitavan säiliön alkioiden tyyppi (voi olla myös const-viite kyseiseen tyyppiin) Paluuarvo true, jos parametrina saatuun alkioon halutaan kohdistaa algoritmifunktion mukainen toimenpide, muutoin paluuarvo false Ainakin seuraavat valintafunktiota hyödyntävät algoritmit on käytettävissä: count_if, find_if, replace_if ja remove_if

16 OHJ-1150 Ohjelmointi II 308 Toinen hyödyllinen tapa säätää joidenkin STLalgoritmin toimintaa ovat vertailufunktiot: funktiot jotka vertailevat kahden alkion suuruutta Esimerkiksi sort-funktiolle voi antaa lisäparametrin, joka kertoo, kuinka alkioiden suuruutta pitäisi tulkita: struct Opiskelija { string nimi; int opnum; ; vector<opiskelija> rekisteri; // Lajittelu nimen mukaiseen järjestykseen sort(rekisteribegin( ), rekisteriend( ), VertaileNimia); // Lajittelu opiskelijanumeron mukaiseen järjestykseen sort(rekisteribegin( ), rekisteriend( ), VertaileOpnumeja); jossa funktiot on määritelty: bool VertaileNimia( const Opiskelija& o1, const Opiskelija& o2) { return o1nimi < o2nimi; OHJ-1150 Ohjelmointi II 309 Vertailufunktioiden on täytettävä seuraavat vaatimukset: Paluuarvon tyyppi on bool Parametreja on kaksi ja niiden tyyppien oltava sama kuin käsiteltävän säiliön alkioiden tyyppi Paluuarvo on true, jos ensimmäinen parametri tulkitaan pienemmäksi kuin toinen parametri, false muussa tapauksessa Myös min_element- ja max_element-funktiot hyväksyvät valinnaisesti kolmannen parametrin, joka on em kaltainen vertailufunktio: // Tulostetaan opiskelijanumeroltaan // suurimman opiskelijan tiedot vector<opiskelija>::iterator suurin_opnum; suurin_opnum = max_element(rekisteribegin( ), rekisteriend( ), VertaileOpnumeja); cout << suurin_opnum >nimi << " " << suurin_opnum >opnum << endl; bool VertaileOpnumeja(const Opiskelija& o1, const Opiskelija& o2) { return o1opnum < o2opnum; OHJ-1150 Ohjelmointi II 310 Nyt STL-algoritmien perusajatusten pitäisi olla hallussa Hiukan lisäinformaatiota löytyy tutusta osoitteesta: Hyvin yksityiskohtainen ja melko selkeä kuvaus C++-standardikirjastosta (STL mukaanlukien) löytyy kirjasta: Josuttis: The C++ Standard Library (Addison-Wesley) OHJ-1150 Ohjelmointi II 311 Monimutkaisten tyyppinimien yksinkertaistaminen (typedef) Monimutkaisia tietotyyppejä käytettäessa käy usein niin, että tyyppien nimistä muodostuu pitkiä, vaikeaselkoisia ja/tai työläitä kirjoittaa C++:ssa on mekanismi, joilla ohjelmoija voi antaa tietotyypeille uusia nimiä, jotka käyttäytyvät identtisesti alkuperäisen tyypin kanssa Ajatellaan seuraavaa määrittelyä: typedef unsigned long int ulong; Mitä tuossa tapahtuu on se, että tietotyypille unsigned long int annetaan uusi nimi ulong Tämän jälkeen C++ ei näe mitään eroa sillä, kumpaa tyyppinimeä käytetään muuttujien jne määrittelyyn: unsigned long int jokumuuttuja; tarkoittaa samaa kuin: ulong jokumuuttuja;

17 OHJ-1150 Ohjelmointi II 312 Tyyppien uudelleenimeäminen tapahtuu siis varatun sanan typedef avulla typedef:in syntaktinen logiikka on: 1 Kirjoitetaan muuttujanmäärittely, jossa muuttujan tyyppinä on lisänimeä kaipaava (alkuperäinen) tietotyyppi: unsigned long int ulong; 2 Lisätään edellisen muuttujanmäärittelyrivin eteen varattu sana typedef, jolloin määrittelyn merkitys muuttuu tyypin nimeämiseksi: typedef unsigned long int ulong; 3 Alkuperäisen tietotyypin uusi lisänimi on se, jota kohdassa 1 oli käytetty muuttujan nimenä (ulong) typedef on hyvä työkalu selkeyttämään ohjelmaa silloin, kun käytettyjen tietotyyppien nimet ovat syystä tai toisesta hankalia Erityisen hyvä esimerkki tästä ovat STL-säiliöt ja -iteraattorit OHJ-1150 Ohjelmointi II 313 Ajatellaan seuraavia tuttuja STL-määrittelyitä: vector<int> vek; vector<int>::iterator iter; vector<int>::size_type koko; Koodia saisi ainakin jossain mielessä selkeämmäksi, jos lisäisi sen alkuun typedef-määrittelyt: typedef vector<int> int_vector; typedef int_vector::iterator int_vector_iterator; typedef int_vector::size_type int_vector_size_type; Huomaa kuinka int_vector-tyyppinimeä voi käyttää heti sen määrittelyn jälkeen myös osana toisia typedef-määrittelyitä Myös sivun ylälaidan muuttujamääritelyt voidaan nyt kirjoittaa yksinkertaisemmin: int_vector vek; int_vector_iterator iter; int_vector_size_type koko; OHJ-1150 Ohjelmointi II 314 Muuttujan tyypin automaattinen määrittely Jos muuttuja alustetaan määrittelyvaiheessa jollain arvolla, kääntäjä osaa haluttaessa määritellä muuttujan tyyppiksi saman kuin alustuslausekkeen tyyppi on Tämä tapahtuu merkitsemällä muuttujan tyypiksi varattu sana auto: auto tulos = 345 * a; Kääntäjää huomaa nyt, että alustuslausekkeen 345 * a arvo on tyypiltään double, jolloin muuttujan tulos tyypiksi tulee myös double Aivan sama olisi saatu aikaan myös kirjoittamalla perinteisemmin: double tulos = 345 * a; Tämä on uuden c++-standardin tuoma ominaisuus, joka toimii Ohjelmointi II-kurssilla käytetyssä ohj2c++-kääntäjässä Jos osallistut jatkossa muille Ohjelmistotekniikan laitoksen järjestämille kursseille, joissa opetuskielenä on c++, siellä saattaa olla käytössä vanhempi versio kääntäjästä, eikä tämä ominaisuus toimi Älä siis tule liian riippuvaiseksi ominaisuuden olemassaolosta OHJ-1150 Ohjelmointi II 315 Varsinainen hyöty saavutetaan silloin, kun määritellään muuttujia, joiden tyypit ovat monimutkaisia tai muuten vain pitkiä ja työläitä kirjoittaa toistuvasti Vertaa esimerkiksi seuraavia täsmälleen samat lopputulokset tuottavia määrittelyitä: tai map<string, vector<list<string>>>::iterator m_iter = mbegin( ); vector<list<string>>::iterator v_iter = mbegin( ) >secondbegin( ); auto m_iter = mbegin( ); auto v_iter = mbegin( ) >secondbegin( ); Myös for-silmukan silmukkamuuttujan tyyppi voidaan määritellä vastaavasti: for ( auto iter = mbegin( ); iter = mend( ); ++iter ) { Muuttujan tyypin määräytyminen alustuslausekkeen tyypin perusteella on mitä ilmeisimmin elämää helpottava apuväline Siitä ei kuitenkaan kannata tulla liian riippuvaiseksi, koska jossain tilanteissa alkuperäisiä tyyppejä on pakko käyttää (esim funktioiden muodollisten parametrien määrittely)

18 OHJ-1150 Ohjelmointi II 316 Abstraktiot Sivistyssanastosta ➀ voi löytää seuraavat määritelmät: abstrakti ajatuksessa eristetty, semmoisenaan katsottu tai ajateltu, käsitteellinen abstraktio epäolennaisten ainesten erottaminen ajatuksessa itse oliosta, käsitteenmuodostus (tai sen tulos), yleistys, käsite Määritelmissä ei sinänsä ole mitään vikaa, ne ovat vain liian yleisellä tasolla esitettyjä, ➁ jotta niitä voisi ymmärtää ilman esimerkkejä Tutkitaan muutama esimerkki sekä elävästä elämästä että tietokoneohjelmoinnin maailmasta ➀ Hagfors, Manninen: Jokamiehen sivistyssanasto, 11painos, WSOY, 1972, ISBN ➁ Siis liian abstrakteja! OHJ-1150 Ohjelmointi II 317 Puhutun kielen sana auto Sana auto tarkoittaa laitetta, jolla pääsee nopeasti paikasta toiseen Jokainen ymmärtää tuon merkityksen ja pystyy keskustelemaan autoista, vaikkei hänellä olisikaan ymmärrystä auton todellisesta luonteesta: esim kuinka polttomoottori tai vaihdelaatikko toimivat, saatika sitten kuinka suunnitella ja rakentaa auto omin käsin Auto on siis abstraktio, joka ihmisten ajatusmaailmassa kuvaa erittäin monimutkaisen laitteen niin, että sitä voi ajatella ja siitä voi keskustella takertumatta epäolennaisiin yksityiskohtiin Itse asiassa kaikki puhutun kielen sanat ovat abstraktioita aivan samoilla perusteilla Toki samasta asiasta voi olla eri tasoisia abstraktioita (abstraktiotasoja) vrt Risto Rikkaan, Antti Autoilijan, Matti Mekaanikon ja Seppo Suunnittelijan näkemys autosta OHJ-1150 Ohjelmointi II 318 Abstraktiot ohjelmoinnissa Kaikki tieto, jota tietokoneohjelmissa käsitellään, on abstraktia Esimerkiksi tietotyyppi int Paitsi että kokonaisluvut itsessään ovat abstraktioita, niin niiden esitys ohjelmointikielessä (siis int) on sitä myös: int:in toteutuksesta konekieli- tai puolijohdetasolla ei ole mitään varmuutta Kuitenkin int-tyyppiä voidaan käyttää, kun ymmärretään sen käyttäytyvän kuin kokonaisluku Usein puhutaan tietoabstraktiosta (data abstraction) Ohjelmointiin liittyy myös toinen abstraktiokäsite: toiminnallinen abstraktio (functional abstraction) Hyvä esimerkki toiminnallisesta abstraktiosta ovat funktiot ja aliohjelmat OHJ-1150 Ohjelmointi II 319 Funktio tai aliohjelma on sarjalle toimintoja annettu abstrakti nimi Esimerkiksi, kun on päätetty, että luvun itseisarvo saadaan funktiolla double Itseisarvo(double d) niin sen jälkeen on yhdentekevää, kuinka funktio on toteutettu, kunhan se tuottaa itseisarvon määritelmän mukaisen tuloksen parametristaan: double Itseisarvo(double d) { if (d < 0) { return d; else { return d; tai #include <cmath> double Itseisarvo(double d) { return abs(d); // kirjastofunktio abs( ) tai jollain vielä aivan toisella tavalla

19 OHJ-1150 Ohjelmointi II 320 Mitä (tietokone)ohjelmointi nyt tämän uuden tiedon valossa on? (vrts3) Uusien abstraktioiden opettamista kääntäjälle/ koneelle, jotta ohjelmoijan olisi helpompi kuvata halutun ongelman ratkaisu muuten niin suppealla ohjelmointikielellä Tosiasiassa abstraktioiden parissa siis painittiin jo koko Ohjelmointi I-kurssi, vaikka asiaa ei näin syvällisesti ja filosofis metafyysisesti pohdittukaan Kun ohjelmoinnin yhteydessä puhutaan abstraktiosta, niin tarkoitetaan toteutuksen ja käytön erottamista toisistaan: tietotyyppejä voi käyttää ja ne toimivat odotetusti ja funktioita ja aliohjelmia voi kutsua ja ne suorittavat tehtävänsa oikein, vaikka toteutuksen yksityiskohdista ei tiedettäisi mitään OHJ-1150 Ohjelmointi II 321 Abstraktit tietotyypit Abstraktit tietotyypit ovat ohjelmoijan määrittelemiä tietotyyppejä, joissa tietoisesti pyritään soveltamaan»toteutuksen ja käytön erottelu»-periaatetta Tarkoitus on suunnitella ja rakentaa tietotyyppejä 1 Joiden toteutuksesta käyttäjällä ei ole tietoa, ja jos onkin, niin hän ei voi vahingossa (tai tarkoituksella) käyttää valitun toteutuksen ominaisuuksia hyväkseen (tiedon kätkentä, data/information hiding) 2 Ohjelmoija voi kuitenkin hyödyntää abstraktia tietotyyppiä, sillä sen alkuperäisen toteuttaja on kirjoittanut myös joukon funktioita ja aliohjelmia, joilla kaikki tarpeelliset operaatiot saadaan suoritettua Tällaista joukkoa abstraktiin tietotyyppiin liittyviä funktioita ja aliohjelmia kutsutaan sen rajapinnaksi tai julkiseksi rajapinnaksi OHJ-1150 Ohjelmointi II 322 Esimerkki jo entuudestaan tutusta abstraktista tietotyypistä on fstream-kirjaston ifstream: 1 Sen toteutuksesta ei ole tietoa: jollain»maagisella» tavalla se kuitenkin esittää fyysiset levytiedostot C++-ohjelmasta käytettävässä muodossa 2 Mukana rajapintafunktiot, joiden avulla fstreamtyyppiä käytetään: getline, peek, ignore ja monta muuta Rajapinnan funktiot kuvaavat abstraktin tietotyypin olennaiset ominaisuudet sillä abstraktiotasolla, jolla tyyppiä on tarkoitus käyttää Usein rajapinnan funktioita kutsutaan myös metodeiksi tai jäsenfunktioiksi OHJ-1150 Ohjelmointi II 323 Yksinkertainen esimerkki Suunnitellaan ensimmäinen abstrakti tietotyyppimme Vektori, mutta ei oteta vielä kantaa sen toteutukseen: katsotaan millainen sen rajapinta on ja miten sitä käytettäisiin ohjelmassa Vektori on kaksiulotteisen avaruuden vektori, jota on tarkoitus käyttää seuraavasti: ohjelmassa voi olla Vektori-tyyppisiä muuttujia, vektorin arvo (double-tyyppiset x- ja y-koordinaatti) voidaan lukea käyttäjältä näppäimistöltä, vektorista on mahdollista saada selville sen x- ja y-koordinaatit, vektoreita voi tulostaa näytölle x y-koordinaattitai polaarikoordinaattimuodossa ja vektoreita voidaan kiertää origon ympäri halutun kulman verran myötäpäivään

20 OHJ-1150 Ohjelmointi II 324 Pieni pääohjelma joka käyttää Vektori-tietotyyppiä: #include <iostream> #include <cstdlib> #include <cmath> using namespace std; vektori-tietotyypin määrittely puuttuu tästä: ks s 327 int main( ) { Vektori vek; vektulosta_xy_muodossa( ); // onko alustettu? vektulosta_polaarimuodossa( ); if (!veklue_nappaimistolta( ) ) { cerr << "Luku epäonnistui!" << endl; return EXIT_FAILURE; vektulosta_xy_muodossa( ); vektulosta_polaarimuodossa( ); vekkierra_origon_ympari(25); vektulosta_xy_muodossa( ); vektulosta_polaarimuodossa( ); double x = vekhae_x_koord( ); double y = vekhae_y_koord( ); cout << "Koordinaatit: " << x << ", " << y << endl; OHJ-1150 Ohjelmointi II 325 Ohjelman suoritus näyttäisi tältä: proffa> /vektorit (x, y) = (1, 0) (a, r ) = (0, 1) Syötä vektori: (x, y) = (3, 4) (a, r ) = (531301, 5) (x, y) = (44094, ) (a, r ) = (281301, 5) Koordinaatit: 44094, proffa> Esimerkissä funktioiden kutsunotaatio on stringtyypistä ja tietovirroista tuttu muuttujafunktio() Tätä notaatiota tullaan jatkossakin käyttämään abstraktien tietotyyppien kanssa Olennaiset huomiot esimerkistä: Tietotyyppiä vektori pystyi käyttämään täydellä teholla ja koodi oli ymmärrettävää, vaikka tyypin toteutuksesta ei ollut mitään tietoa Rajapinnan funktiot määräävät, mitä abstraktilla tietotyypillä voi tehdä: kaikki muuttujalle vek tehdyt operaatiot tapahtuivat sopivaa rajapinnan funktiota kutsumalla OHJ-1150 Ohjelmointi II 326 On hyödyllistä havaita myös, että osa rajapinnan funktioista voidaan jakaa loogisiin ryhmiin: rakentajat eli konstruktorit Alustavat abstraktin tietotyypin muuttujan eli asettavat sille järkevän alkuarvon (esimerkin rakentaja on»piilossa» katso toteutusta) valitsimet eli selektorit Palauttavat toteutukseen kätkettyä tietoa: hae_x_koord( ) ja hae_y_koord( ) muuttajat eli mutaattorit Muuttavat alkion tilaa (eli toteutukseen kätkettyä tietoa): lue_nappaimistolta( ) ja kierra_origon_ympari( ) purkajat eli destruktorit Vapauttavat muuttujan varaamat resurssit sen jälkeen, kun muuttujaa ei enää tarvita Esimerkissä ei purkajaa (mutta myöhemmin tärkeä käsite) Muitakin ryhmiä on, mutta ne eivät tässä vaiheessa ole tärkeitä OHJ-1150 Ohjelmointi II 327 Vektori-tyypin toteutus C++-kielen työkalu abstraktien tietotyyppien toteuttamiseen on luokka (class) Luokkiin sisältyy kuitenkin C++:ssa kiusallisen paljon yksityiskohtia, joten näinkin yksinkertainen esimerkki muodostuu monimutkaiseksi class Vektori { // rajapinnan esittely public: // rakentaja Vektori( ); // valitsimet double hae_x_koord( ) const; double hae_y_koord( ) const; // mutaattorit bool lue_nappaimistolta( ); void kierra_origon_ympari(double kulma); // muut rajapinnan tarjoamat palvelut void tulosta_xy_muodossa( ) const; void tulosta_polaarimuodossa( ) const; // kätketyt toteutusyksityiskohdat private: double x; double y; ;

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

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

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

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

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

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 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

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

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

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

TTY Ohjelmointi I & II C++-kirjastoreferenssi versio 2.2

TTY Ohjelmointi I & II C++-kirjastoreferenssi versio 2.2 TTY Ohjelmointi I & II C++-kirjastoreferenssi versio 2.2 Copyright 2002 2009 Ari Suntioinen aps@cs.tut.fi #include int EXIT_SUCCESS main-funktion paluuarvo int EXIT_FAILURE ok- ja virhetilanteessa.

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

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

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari 1 1. JOHDANTO 1.1 Määritelmiä 1.2 Tietorakenteen ja algoritmin valinta 1.3 Algoritmit ja tiedon määrä 1.4 Tietorakenteet ja toiminnot 1.5 Esimerkki:

Lisätiedot

AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin

AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin AS-0.1103 C-ohjelmoinnin peruskurssi 2013: C-kieli käytännössä ja erot Pythoniin Raimo Nikkilä Aalto-yliopiston sähkötekniikan korkeakoulu - Automaation tietotekniikan tutkimusryhmä 17. tammikuuta 2013

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

Tietorakenteet ja algoritmit - syksy 2015 1

Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 1 Tietorakenteet ja algoritmit - syksy 2015 2 Tietorakenteet ja algoritmit Johdanto Ari Korhonen Tietorakenteet ja algoritmit - syksy 2015 1. JOHDANTO 1.1 Määritelmiä

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

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

Taulukot. Taulukon käsittely. Tämän osan sisältö. Esimerkki. Taulukon esittely ja luonti. Taulukon alustaminen. Taulukon koko

Taulukot. Taulukon käsittely. Tämän osan sisältö. Esimerkki. Taulukon esittely ja luonti. Taulukon alustaminen. Taulukon koko 5 Taulukot Tämän osan sisältö Taulukon esittely ja luonti Taulukon alustaminen Taulukon koko Taulukon käsittely indeksointi peräkkäiskäsittely hajakäsittely harva taulukko Taulukon järjestäminen Kaksiulotteinen

Lisätiedot

tietueet eri tyyppisiä tietoja saman muuttujan arvoiksi

tietueet eri tyyppisiä tietoja saman muuttujan arvoiksi tietueet eri tyyppisiä tietoja saman muuttujan arvoiksi ero taulukkoon taulukossa alkiot samantyyppisiä tietueessa alkiot voivat olla erityyppisiä tiedot kuitenkin yhteen kuuluvia ohjelmoinnin perusteet,

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

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

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

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

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

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

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

Ohjelmoinnin perusteet Y Python

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

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 String-merkkijonoluokka 1 Ohjelmointikielten merkkijonot Merkkijonot ja niiden käsittely on välttämätöntä ohjelmoinnissa Valitettavasti ohjelmointikielten tekijät eivät tätä ole ottaneet

Lisätiedot

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Tietorakenneluokkia 2: HashMap, TreeMap

Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Tietorakenneluokkia 2: HashMap, TreeMap Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Tietorakenneluokkia 2: HashMap, TreeMap Tietorakenneluokkia ja -rajapintoja Java tarjoaa laajan kokoelman tietorakennerajapintoja ja - luokkia. Aiemmin

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

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

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

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

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

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

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

815338A Ohjelmointikielten periaatteet 2014-2015

815338A Ohjelmointikielten periaatteet 2014-2015 815338A Ohjelmointikielten periaatteet 2014-2015 X Skriptiohjelmointi Sisältö 1. Johdanto 2. Skriptikielten yleispiirteitä 3. Python 815338A Ohjelmointikielten periaatteet, Skriptiohjelmointi 2 X.1 Johdanto

Lisätiedot

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python

Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python Pythonin alkeet Syksy 2010 Pythonin perusteet: Ohjelmointi, skriptaus ja Python 8. marraskuuta 2010 Ohjelmointi Perusteet Peruskäsitteitä Olio-ohjelmointi Pythonin alkeet Esittely Esimerkkejä Muuttujat

Lisätiedot

Java kahdessa tunnissa. Jyry Suvilehto

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

Lisätiedot

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.2.2010 1 / 46 Merkkijonot Merkkijonojen avulla ohjelmassa voi esittää tekstitietoa, esim. nimiä, osoitteita ja

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

5.6. C-kielen perusteet, osa 6/8, Taulukko 6.1.2008, pva, kuvat jma

5.6. C-kielen perusteet, osa 6/8, Taulukko 6.1.2008, pva, kuvat jma 5.6. C-kielen perusteet, osa 6/8, Taulukko 6.1.2008, pva, kuvat jma Every cloud has a silver line. - englantilainen sananlasku Tässä osiossa tärkeää: yksi- ja moniulotteinen taulukko Sisältö Yleistä Yksiulotteinen

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

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

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python 31. tammikuuta 2009 Ohjelmointi Perusteet Pythonin alkeet Esittely Esimerkkejä Muuttujat Peruskäsitteitä Käsittely

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

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

Ohjelmoinnin perusteet Y Python

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

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

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

1. C++:n STL-kirjasto

1. C++:n STL-kirjasto 1. C++:n STL-kirjasto C-kielen ongelma on, että taulukkojen koot on tiedettävä etukäteen. Lisäksi C ei tarjoa mitään keinoa automaattiseen indeksin tarkistukseen. Toisin sanoen on täysin ohjelmoijan vastuulla,

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

Kielioppia: toisin kuin Javassa

Kielioppia: toisin kuin Javassa Object Pascal Pascal kielen oliolaajennus (Inprise/Borland:n oma) luokat Voit uudelleenkäyttää luomiasi objekteja esim. komponentteja Periytyminen Kielioppia: toisin kuin Javassa Ei eroa isojen ja pienien

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

Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö C-ohjelmassa

Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö C-ohjelmassa ssa ohjelman käytössä suoritusaikana oleva muisti jakautuu neljään osaan: koodisegmentti datasegmentti pinosegmentti (stack) kasa (heap) ssa ohjelman koodisegmentti sisältää käännetyn ohjelmakoodin sisältö

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

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti Luku 6 Dynaaminen ohjelmointi Dynaamisessa ohjelmoinnissa on ideana jakaa ongelman ratkaisu pienempiin osaongelmiin, jotka voidaan ratkaista toisistaan riippumattomasti. Jokaisen osaongelman ratkaisu tallennetaan

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

Luku 3. Listankäsittelyä. 3.1 Listat

Luku 3. Listankäsittelyä. 3.1 Listat Luku 3 Listankäsittelyä Funktio-ohjelmoinnin tärkein yksittäinen tietorakenne on lista. Listankäsittely on paitsi käytännöllisesti oleellinen aihe, se myös valaisee funktio-ohjelmoinnin ideaa. 3.1 Listat

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

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

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

Määrittelydokumentti

Määrittelydokumentti Määrittelydokumentti Aineopintojen harjoitustyö: Tietorakenteet ja algoritmit (alkukesä) Sami Korhonen 014021868 sami.korhonen@helsinki. Tietojenkäsittelytieteen laitos Helsingin yliopisto 23. kesäkuuta

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

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

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

Ohjelmoinnin peruskurssi Y1

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

Lisätiedot

Algoritmit 1. Luento 10 Ke 11.2.2015. Timo Männikkö

Algoritmit 1. Luento 10 Ke 11.2.2015. Timo Männikkö Algoritmit 1 Luento 10 Ke 11.2.2015 Timo Männikkö Luento 10 Algoritminen ongelman ratkaisu Suunnittelumenetelmät Raaka voima Järjestäminen eli lajittelu Kuplalajittelu Väliinsijoituslajittelu Valintalajittelu

Lisätiedot

TT00AA12-2016 - Ohjelmoinnin jatko (TT10S1ECD)

TT00AA12-2016 - Ohjelmoinnin jatko (TT10S1ECD) TT00AA12-2016 - Ohjelmoinnin jatko (TT10S1ECD) Ohjelmointikäytännöt 21/3/11 Mikko Vuorinen Metropolia Ammattikorkeakoulu 1 Sisältö 1) Mitä on hyvä koodi? 2) Ohjelmointikäytäntöjen merkitys? 3) Koodin asettelu

Lisätiedot

811312A Tietorakenteet ja algoritmit, 2014-2015, Harjoitus 7, ratkaisu

811312A Tietorakenteet ja algoritmit, 2014-2015, Harjoitus 7, ratkaisu 832A Tietorakenteet ja algoritmit, 204-205, Harjoitus 7, ratkaisu Hajota ja hallitse-menetelmä: Tehtävä 7.. Muodosta hajota ja hallitse-menetelmää käyttäen algoritmi TULOSTA_PUU_LASKEVA, joka tulostaa

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

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

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys

C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. C-ohjelma. Operaatioiden suoritusjärjestys Loogisia operaatioita - esimerkkejä Tänään on lämmin päivä ja perjantai Eilen satoi ja oli keskiviikko tai tänään on tiistai. On perjantai ja kello on yli 13 Ei ole tiistai tai ei sada. Ei pidä paikkaansa,

Lisätiedot

Java-kielen perusteita

Java-kielen perusteita Java-kielen perusteita valintalauseet 1 Johdantoa kontrollirakenteisiin Tähän saakka ohjelmissa on ollut vain peräkkäisyyttä eli lauseet on suoritettu peräkkäin yksi kerrallaan Tarvitsemme myös valintaa

Lisätiedot

2 Haku ja lajittelu. 2.1 Luvun hakeminen taulukosta X?? n-1. Haku ja lajittelu 35

2 Haku ja lajittelu. 2.1 Luvun hakeminen taulukosta X?? n-1. Haku ja lajittelu 35 Haku ja lajittelu 35 2 Haku ja lajittelu Tässä luvussa käsitellään tiedon hakemista taulukosta sekä taulukon lajittelua. Useista erilaisista lajittelumenetelmistä on kirjaan otettu suurehko osa. Lajittelumenetelmien

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

1. Olio-ohjelmointi 1.1

1. Olio-ohjelmointi 1.1 1. Olio-ohjelmointi 1.1 Sisällys Olio-ohjelmointi on eräs ohjelmointiparadigma. Olio-ohjelmoinnin muotoja. Ohjelmiston analyysi ja suunnittelu. Olioparadigman etuja ja kritiikkiä. 1.2 Ohjelmointiparadigmoja

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

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä 12.1 12.2 12.3 12.4

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä 12.1 12.2 12.3 12.4 Sisällys 12. Näppäimistöltä lukeminen Arvojen lukeminen näppäimistöltä yleisesti. Arvojen lukeminen näppäimistöltä Java-kielessä.. Luetun arvon tarkistaminen. Tietovirrat ja ohjausmerkit. Scanner-luokka.

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

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 27.1.2010 T-106.1208 Ohjelmoinnin perusteet Y 27.1.2010 1 / 37 If-käsky toistokäskyn sisällä def main(): HELLERAJA = 25.0 print "Anna lampotiloja, lopeta -300:lla."

Lisätiedot

Olio-ohjelmoinnissa luokat voidaan järjestää siten, että ne pystyvät jakamaan yhteisiä tietoja ja aliohjelmia.

Olio-ohjelmoinnissa luokat voidaan järjestää siten, että ne pystyvät jakamaan yhteisiä tietoja ja aliohjelmia. 4. Periytyminen 4.1. 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

14.1 Rekursio tyypitetyssä lambda-kielessä

14.1 Rekursio tyypitetyssä lambda-kielessä Luku 14 Rekursiiviset tyypit Edellisessä luvussa esitetyt tietue- ja varianttityypit eivät yksinään riitä kovin mielenkiintoisten tietorakenteiden toteuttamiseen. Useimmissa ohjelmissa tarvitaan erilaisia

Lisätiedot

Ohjelmoinnin perusteet Pythonilla. Teemu Sirkiä, 2015

Ohjelmoinnin perusteet Pythonilla. Teemu Sirkiä, 2015 Ohjelmoinnin perusteet Pythonilla Teemu Sirkiä, 2015 Päivitetty 16.9.2015 Yleistä Materiaali sisältää lähinnä Aalto-yliopiston Ohjelmoinnin peruskurssi Y1:n harjoitustehtävissä tarvittavia keskeisiä asioita

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

Luento 2: Tiedostot ja tiedon varastointi

Luento 2: Tiedostot ja tiedon varastointi HELIA 1 (19) Luento 2: Tiedostot ja tiedon varastointi Muistit... 2 Päämuisti (Primary storage)... 2 Apumuisti (Secondary storage)... 2 Tiedon tallennuksen yksiköitä... 3 Looginen taso... 3 Fyysinen taso...

Lisätiedot

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 3: SICP kohdat 2.22.3, 33.1 ja 3.33.3.2 Riku Saikkonen 8. 11. 2010 Sisältö 1 Lisää listoista 2 Symbolit ja sulkulausekkeet 3 Derivoijaesimerkki 4 Muuttujan

Lisätiedot

Merkkijonot ja C++ Antti-Juhani Kaijanaho. 5. maaliskuuta 2001. 1 Vanhojen C++-kääntäjien käyttäjät, huomio! 2 Merkkijonojen perusteet

Merkkijonot ja C++ Antti-Juhani Kaijanaho. 5. maaliskuuta 2001. 1 Vanhojen C++-kääntäjien käyttäjät, huomio! 2 Merkkijonojen perusteet Merkkijonot ja C++ Antti-Juhani Kaijanaho 5. maaliskuuta 2001 1 Vanhojen C++-kääntäjien käyttäjät, huomio! Tämä kirjoitus perustuu vuonna 1998 julkistettuun C++-kielen kansainväliseen ISO-standardiin.

Lisätiedot

2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma muuttaa parametrejaan tai globaaleja muuttujia, tulostaa jotakin jne.

2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma muuttaa parametrejaan tai globaaleja muuttujia, tulostaa jotakin jne. Proseduurit Proseduuri voi olla 1) Funktio, joka palauttaa jonkin arvon: real function sinc(x) real x sinc = sin(x)/x... y = sinc(1.5) 2) Aliohjelma, jonka toiminta perustuu sivuvaikutuksiin: aliohjelma

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

OHJ-1151 Ohjelmointi IIe

OHJ-1151 Ohjelmointi IIe Tampereen teknillinen yliopisto Ohjelmistotekniikan laitos OHJ-1151 Ohjelmointi IIe Harjoitustyö Tomaattisota Välipalautus / Loppudokumentaatio Assistentin nimi Välipalautusaika (päivä ja kellonaika) ja

Lisätiedot

Ongelma(t): Miten mikro-ohjelmoitavaa tietokonetta voisi ohjelmoida kirjoittamatta binääristä (mikro)koodia? Voisiko samalla algoritmin esitystavalla

Ongelma(t): Miten mikro-ohjelmoitavaa tietokonetta voisi ohjelmoida kirjoittamatta binääristä (mikro)koodia? Voisiko samalla algoritmin esitystavalla Ongelma(t): Miten mikro-ohjelmoitavaa tietokonetta voisi ohjelmoida kirjoittamatta binääristä (mikro)koodia? Voisiko samalla algoritmin esitystavalla ohjelmoida useita komponenteiltaan ja rakenteeltaan

Lisätiedot

2. Olio-ohjelmoinista lyhyesti 2.1

2. Olio-ohjelmoinista lyhyesti 2.1 2. Olio-ohjelmoinista lyhyesti 2.1 Sisällys Yleistä. Oliot ja luokat. Attribuutit. Olioiden esittely ja alustus. Rakentajat. Olion operaation kutsuminen. 2.2 Yleistä Olio-ohjelmointia käsitellään hyvin

Lisätiedot

1.1 Pino (stack) Koodiluonnos. Graafinen esitys ...

1.1 Pino (stack) Koodiluonnos. Graafinen esitys ... 1. Tietorakenteet Tietorakenteet organisoivat samankaltaisten olioiden muodostaman tietojoukon. Tämä järjestys voidaan saada aikaan monin tavoin, esim. Keräämällä oliot taulukkoon. Liittämällä olioihin

Lisätiedot