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

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

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

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

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

STL:n uudistukset. Seppo Koivisto TTY Ohjelmistotekniikka

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

Lisätiedot

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

Olio-ohjelmointi Syntaksikokoelma

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

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

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

Lisätiedot

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

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

Lisätiedot

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

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

Ohjelmointi 1 Taulukot ja merkkijonot

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

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

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

Lisätiedot

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

Tieto- ja tallennusrakenteet

Tieto- ja tallennusrakenteet Tieto- ja tallennusrakenteet Sisältö Tyyppi, abstrakti tietotyyppi, abstraktin tietotyypin toteutus Tallennusrakenteet Taulukko Linkitetty rakenne Abstraktit tietotyypit Lista (Puu) (Viimeisellä viikolla)

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

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

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

Lisätiedot

Ohjelmoinnin perusteet Y Python

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

Lisätiedot

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

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

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

Lisätiedot

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

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

Lisätiedot

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

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

18. Abstraktit tietotyypit 18.1

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

Lisätiedot

12 Mallit (Templates)

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

Lisätiedot

Ohjelmoinnin perusteet Y Python

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

Lisätiedot

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

Muuttujien roolit Kiintoarvo cin >> r;

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

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

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

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

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

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

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

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

Lisätiedot

Ohjelmoinnin peruskurssi Y1

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

Lisätiedot

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

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

Lisätiedot

Ohjelmoinnin perusteet Y Python

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

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

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

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

Lisätiedot

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

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

Lisätiedot

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

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

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

Lisätiedot

Rakenteiset tietotyypit Moniulotteiset taulukot

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

Lisätiedot

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

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

Lisätiedot

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

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

Lisätiedot

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

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

Lisätiedot

useampi ns. avain (tai vertailuavain) esim. opiskelijaa kuvaavassa alkiossa vaikkapa opintopistemäärä tai opiskelijanumero

useampi ns. avain (tai vertailuavain) esim. opiskelijaa kuvaavassa alkiossa vaikkapa opintopistemäärä tai opiskelijanumero Alkioiden avaimet Usein tietoalkioille on mielekästä määrittää yksi tai useampi ns. avain (tai vertailuavain) esim. opiskelijaa kuvaavassa alkiossa vaikkapa opintopistemäärä tai opiskelijanumero 80 op

Lisätiedot

Java-kielen perusteet

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

Lisätiedot

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

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

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

Ohjelmoinnin peruskurssien laaja oppimäärä

Ohjelmoinnin peruskurssien laaja oppimäärä Ohjelmoinnin peruskurssien laaja oppimäärä Luento 5: Sijoituslause, SICP-oliot, tietorakenteen muuttaminen (mm. SICP 33.1.3, 3.33.3.2) Riku Saikkonen 6. 11. 2012 Sisältö 1 Muuttujan arvon muuttaminen:

Lisätiedot

7. Oliot ja viitteet 7.1

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

Lisätiedot

List-luokan soveltamista. Listaan lisääminen Listan läpikäynti Listasta etsiminen Listan sisällön muuttaminen Listasta poistaminen Listan kopioiminen

List-luokan soveltamista. Listaan lisääminen Listan läpikäynti Listasta etsiminen Listan sisällön muuttaminen Listasta poistaminen Listan kopioiminen 1 List-luokan soveltamista List-luokan metodeja Listaan lisääminen Listan läpikäynti Listasta etsiminen Listan sisällön muuttaminen Listasta poistaminen Listan kopioiminen 1 List-luokan metodeja List-luokan

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

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

Lisätiedot

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

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

Lisätiedot

Olio-ohjelmointi 2. välikoe HYV5SN

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

Lisätiedot

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

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

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

Lisätiedot

Lyhyt kertaus osoittimista

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

Lisätiedot

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

Algoritmit 1. Luento 4 Ke Timo Männikkö

Algoritmit 1. Luento 4 Ke Timo Männikkö Algoritmit 1 Luento 4 Ke 18.1.2017 Timo Männikkö Luento 4 Tietorakenteet Pino Pinon toteutus Jono Jonon toteutus Lista Listaoperaatiot Algoritmit 1 Kevät 2017 Luento 4 Ke 18.1.2017 2/29 Pino Pino, stack,

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

Algoritmit 2. Luento 2 To Timo Männikkö

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

Lisätiedot

Imperatiivisen ohjelmoinnin peruskäsitteet. Meidän käyttämän pseudokielen lauseiden syntaksi

Imperatiivisen ohjelmoinnin peruskäsitteet. Meidän käyttämän pseudokielen lauseiden syntaksi Imperatiivisen ohjelmoinnin peruskäsitteet muuttuja muuttujissa oleva data voi olla yksinkertaista eli primitiivistä (esim. luvut ja merkit) tai rakenteista jolloin puhutaan tietorakenteista. puhuttaessa

Lisätiedot

Algoritmit 1. Luento 10 Ke Timo Männikkö

Algoritmit 1. Luento 10 Ke Timo Männikkö Algoritmit 1 Luento 10 Ke 14.2.2018 Timo Männikkö Luento 10 Algoritminen ongelmanratkaisu Suunnittelumenetelmät Raaka voima Järjestäminen eli lajittelu Kuplalajittelu Lisäyslajittelu Valintalajittelu Permutaatiot

Lisätiedot

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

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

Lisätiedot

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

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

Lisätiedot

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

1. Mitä tehdään ensiksi?

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

Lisätiedot

Ohjelmoinnin 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

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

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

Lisätiedot

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

Tutoriaaliläsnäoloista

Tutoriaaliläsnäoloista Tutoriaaliläsnäoloista Tutoriaaliläsnäolokierroksella voi nyt täyttää anomuksen läsnäolon merkitsemisestä Esim. tagi ei toiminut, korvavaltimon leikkaus, yms. Hyväksyn näitä omaa harkintaa käyttäen Tarkoitus

Lisätiedot

Chapel. TIE Ryhmä 91. Joonas Eloranta Lari Valtonen

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

Lisätiedot

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

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

Lisätiedot

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

Algoritmit 1. Luento 3 Ti Timo Männikkö

Algoritmit 1. Luento 3 Ti Timo Männikkö Algoritmit 1 Luento 3 Ti 17.1.2017 Timo Männikkö Luento 3 Algoritmin analysointi Rekursio Lomituslajittelu Aikavaativuus Tietorakenteet Pino Algoritmit 1 Kevät 2017 Luento 3 Ti 17.1.2017 2/27 Algoritmien

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

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

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

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

Lisätiedot

Ohjelmoinnin perusteet, syksy 2006

Ohjelmoinnin perusteet, syksy 2006 Ohjelmoinnin perusteet, syksy 2006 Esimerkkivastaukset 1. harjoituksiin. Alkuperäiset esimerkkivastaukset laati Jari Suominen. Vastauksia muokkasi Jukka Stenlund. 1. Esitä seuraavan algoritmin tila jokaisen

Lisätiedot

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

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

Lisätiedot

16. Ohjelmoinnin tekniikkaa 16.1

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

Lisätiedot

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

Osoittimet ja taulukot

Osoittimet ja taulukot C! ja taulukot 1.2.2018 Tiedotteita Tämän jälkeen taas pari väliviikkoa (tenttiviikko) Seuraava luento 22.2. Laskareita ei tenttiviikolla 12.2. 16.2. 2 ja muisti Muisti Keskusyksikkö Suorittaa muistissa

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

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

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

11/20: Konepelti auki

11/20: Konepelti auki Ohjelmointi 1 / syksy 2007 11/20: Konepelti auki Paavo Nieminen nieminen@jyu.fi Tietotekniikan laitos Informaatioteknologian tiedekunta Jyväskylän yliopisto Ohjelmointi 1 / syksy 2007 p.1/11 Tämän luennon

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 20.1.2010 T-106.1208 Ohjelmoinnin perusteet Y 20.1.2010 1 / 40 Arvon pyytäminen käyttäjältä Käyttäjän antaman arvon voi lukea raw_input-käskyllä. Käskyn sulkujen

Lisätiedot

Algoritmit 2. Luento 2 Ke Timo Männikkö

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

Lisätiedot

811120P Diskreetit rakenteet

811120P Diskreetit rakenteet 811120P Diskreetit rakenteet 2018-2019 1. Algoritmeista 1.1 Algoritmin käsite Algoritmi keskeinen laskennassa Määrittelee prosessin, joka suorittaa annetun tehtävän Esimerkiksi Nimien järjestäminen aakkosjärjestykseen

Lisätiedot

811312A Tietorakenteet ja algoritmit II Perustietorakenteet

811312A Tietorakenteet ja algoritmit II Perustietorakenteet 811312A Tietorakenteet ja algoritmit 2017-2018 II Perustietorakenteet Sisältö 1. Johdanto 2. Pino 3. Jono 4. Lista 811312A TRA, Perustietorakenteet 2 II.1. Johdanto Tietorakenne on tapa, jolla algoritmi

Lisätiedot

Tietorakenteet ja algoritmit

Tietorakenteet ja algoritmit Tietorakenteet ja algoritmit Elegantti toteutus funktiolle insert_to_list_end Alkion lisäys sisällön mukaan järjestettyyn listaan (insert_to_list) Linkatun listan yleisyys alkiotyypin suhteen source-tasolla

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 21.1.2009 T-106.1208 Ohjelmoinnin perusteet Y 21.1.2009 1 / 32 Tyypeistä Monissa muissa ohjelmointikielissä (esim. Java ja C) muuttujat on määriteltävä ennen

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

Algoritmit 1. Luento 5 Ti Timo Männikkö

Algoritmit 1. Luento 5 Ti Timo Männikkö Algoritmit 1 Luento 5 Ti 24.1.2017 Timo Männikkö Luento 5 Järjestetty lista Järjestetyn listan operaatiot Listan toteutus taulukolla Binäärihaku Binäärihaun vaativuus Algoritmit 1 Kevät 2017 Luento 5 Ti

Lisätiedot

15. Ohjelmoinnin tekniikkaa 15.1

15. Ohjelmoinnin tekniikkaa 15.1 15. Ohjelmoinnin tekniikkaa 15.1 Sisällys For-each-rakenne. Lueteltu tyyppi enum. Override-annotaatio. Geneerinen ohjelmointi. 15.2 For-each-rakenne For-rakenteen variaatio taulukoiden ja muiden kokoelmien

Lisätiedot

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

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

Lisätiedot