Standardi mallikirjasto
|
|
- Hilkka Härkönen
- 8 vuotta sitten
- Katselukertoja:
Transkriptio
1 Standardi mallikirjasto 20 Standardi mallikirjasto Kuten jo tiedätkin C++ sisältää laajan standardikirjaston, joka yksinkertaistaa monia ohjelmointitehtäviä. Tähän saakka näkemäsi lisäksi tämä kirjasto sisältää joukon malleja, jotka tarjoavat vielä suuremmat mahdollisuudet. Voit käyttää näitä malleja luodessasi standardimuotoisia säiliöitä, algoritmeja ja funktioita omille tietotyypeille, jos ne tarvitsevat tällaisia ominaisuuksia ohjelmissasi. Nämä mallit muodostavat yhdessä standardin mallikirjaston (STL). Tässä luvussa esittelemme STL:n perussäiliöt ja algoritmit, jotka toimivat näiden säiliöiden yhteydessä. Luvun aiheita ovat: Standardin mallikirjaston perusrakenne Miten luodaan ja käytetään peräkkäissäiliöitä vector<> ja list<> sekä assosiatiivisia säiliöitä map<> ja multimap<> vector<>- ja list<>-säiliöiden erikoiset talletustavat Miten iteraattorit yhdistävät säiliöt yksinkertaisiin C++:n standarditaulukoihin Miten STL käyttää erikoistumista suorituskyvyn parantamiseksi STL:n arkkitehtuurin perusteet Yksi STL:n tärkeä ominaisuus on se, että se antaa käyttöösi yleisiä työkaluja. Koska STL:n kaikki ominaisuudet ovat mallipohjaisia, ne toimivat lähes kaikkien mahdollisten tietotyyppien kanssa. STL:n avulla voit luoda luokan, joka määrittelee linkitetyn listan mille tahansa tietotyypillesi. Jos tarvitset linkitetyn listan Laatikko-olioille ja JalkapallonPelaaja-olioille, se ei ole mikään ongelma STL:lle. Kun sinun tarvitsee käsitellä olioitasi tavalliseen tapaan, STL voi auttaa tässäkin. Jos sinun tarvitsee lajitella Laatikko-oliosi nousevaan järjestykseen, STL voi muodostaa lajittelufunktion mille tahansa tietotyypille, jolle on määritelty vertailuoperaattori järjestyksen vertailua varten. Käyttääpä ohjelmasi millaisia olioita tahansa, on mahdollista, että STL voi auttaa niiden standardimuotoisessa järjestelyssä tai analysoinnissa. 823
2 C++ Ohjelmoijan käsikirja STL sisältää kolmenlaisia työkaluja - säiliöitä, iteraattoreita ja algoritmeja. Säiliöiden avulla voit järjestää mielivaltaisen tyyppisiä olioita - linkitetty lista on yksi esimerkki säiliöistä. STL:n säiliöt jakaantuvat kahteen luokkaan: Peräkkäissäiliöt (vector, deque ja list), jotka sisältävät tietyn tyyppisiä olioita peräkkäisessä muodossa. Assosiatiiviset säiliöt (map, multimap, set ja multiset) mahdollistavat tietyn tyyppisten olioiden tallettamisen ja hakemisen erityyppisten avainten avulla. Yksinkertainen esimerkki voisi olla Tyontekija-olio, jonka avaimena on henkilönumero. Tyontekija-olio voidaan hakea henkilönumeron perusteella. Iteraattorit ovat liima, joka pitää STL:n kasassa. Riippumatta käytettävästä säiliöstä, sen alkioita käsitellään lähes yksinomaan iteraattoreiden avulla ja iteraattoreita käytetään algoritmien soveltamisessa säiliön olioille. Iteraattori on fiksu osoitin. Luvussa 14 määrittelimme yksinkertaisen iteraattoriluokan - LtkPtr-luokan - AutoKuorma-säiliöllemme. Lisäksi STL sisältää iteraattoreita, joita voidaan käyttää olioiden siirtämiseen virtaan tai virrasta. Algoritmit tarjoavat laskenta- tai analysointimekanismeja iteraattoreiden avulla käytettäville oliojoukoille. Algoritmien esimerkkinä voidaan mainita säiliön olioiden haku ja lajittelu. Kaikille STL:n algoritmeille välitetään parametrinä iteraattori. Emme mitenkään voi käsitellä koko STL:ää tässä luvussa. Koko STL:n käsittely vaatisi oman kirjansa, joten käsittelemme tässä vain pienen osan mahdollisuuksistamme. Käsittelemme joitakin perustyökaluja ja katsomme, miten voimme niitä käyttää yksinkertaisten ongelmien ratkaisuun. Näin pääset alkuun ja saat itseluottamusta kokeilla itse joitakin muita STL:n ominaisuuksia. STL:n kaikkein tärkeimmät työkalut ovat säiliöt - tulet varmastikin käyttämään niitä kaikkein useimmin. Et voi kuitenkaan käyttää säiliöitä ilman iteraattoreita, joten sinun tulee ymmärtää myöskin ne hyvin. Algoritmit ovat STL:n kaikkein suurin työkalukokoelma. Suuri osa niistä ei ole kuitenkaan käyttökelpoisia suurelle osalle ohjelmia ja joidenkin käyttö on varsin erikoistunutta. Emme käsittele STL:n algoritmeja yksityiskohtaisesti tässä luvussa, mutta käytämme joitakin niistä. Seuraava taulukko antaa yleiskuvan tarjolla olevista vaihtoehdoista. Algoritmiperhe Perustuu Esimerkkejä 824 kuuluminen operator= copy, remove, replace sijoittaminen operator=swap random_shuffle, rotate, reverse, permute järjestys operator< sort, partition, merge, find, min, max etsintä ja valinta operator== unique, match, count, search, copy_if, remove_if, replace_if muuntaminen funktio-olio for_each, transform, generate, fill numeeriset funktio-olio inner_product, partial_sum, accumulate, adjacent_difference
3 Standardi mallikirjasto Nämä ovat vapaamuotoisia perheitä ja taulukossa on lueteltu vain pieni osa kaikista käytettävissä olevista algoritmeista. Algoritmit toimivat yleisesti ottaen säiliöihin talletettujen olioiden kanssa, mutta niiden ei tarvitse tietää mitään varsinaisesta käytetystä säiliöstä, koska olioita käsitellään aina iteraattoreiden avulla. Kaksi ensimmäistä ryhmää - kuuluminen ja sijoittaminen - hoitavat alkioiden siirtelyt. Tärkeimmät tässä käytettävät operaattorit ovat sijoitusoperaattori ja swap-operaattori (vaihtooperaattori). Järjestys-ryhmän algoritmit ovat kaikkein tärkeimmät. Lajittelu on itsessään äärettömän suuri tieteenala ja oikean tekniikan käyttö on suorituskyvyn kannalta kriittinen. STL:n tarjoamat lajittelualgoritmit ovat parhaimpien tunnettujen joukossa. Monet STL:n algoritmit ovat suhteellisen helppoja tehdä itsekin uudelleen, mutta lajittelualgoritmit ovat suuri poikkeus. Jos voit opetella vain yhden algoritmiperheen, opettele järjestys-algoritmit. Etsintä ja valinta -algoritmit ovat yksinkertaisia, mutta erittäin käteviä. Näitä algoritmeja käytetään tilanteissa, joissa alkiot ovat samat. Muuntaminen-ryhmän algoritmeja näkyy ohjelmissa harvemmin. Ellei tilanne ole hyvin yksinkertainen, on usein helpompaa kirjoittaa itse for-silmukka. STL:n toteutus näille algoritmeille sallii niiden optimoinnin tavalla, joka ei ole mahdollista omalle koodillesi. Harkitse näiden algoritmien käyttöä, kun hyvä suorituskyky on äärimmäisen tärkeää. Funktio-oliot, joihin muuntaminen- ja numeeriset -ryhmät perustuvat, ovat luokkaolioita, jotka uudelleenmäärittelevät funktion kutsu -operaattorin operator(), ja ovat erityisesti suunnitellut funktion välittämiseen parametrinä tehokkaammin kuin pelkän funktion osoittimen välittäminen tarjoaa. Edellä oleva taulukko jakaa algoritmit tärkeimmän toiminnon mukaan, mutta algoritmit voidaan jakaa ryhmiin myös muilla tavoilla. Usein algoritmit jaetaan muuttaviin ja ei-muuttaviin algoritmeihin. Näistä ensimmäiset ovat algoritmeja, jotka muuttavat säiliön sisältöä ja jälkimmäiset ovat algoritmeja, jotka eivät muuta säiliön sisältöä. STL:n otsikkotiedostot STL:n ominaisuudet esitellään seuraavissa otsikkotiedostoissa: Otsikkotiedosto <vector> <deque> <list> <map> Tarkoitus taulukkosäiliö, jossa on yksi pää taulukkosäiliö, jossa on kaksi päätä molempiin suuntiin linkitetty listasäiliö assosiatiivinen taulukkosäiliö Taulukko jatkuu seuraavalle sivulle 825
4 C++ Ohjelmoijan käsikirja Otsikkotiedosto <set> <queue> <stack> <iterator> <algorithm> <numeric> <functional> <bitset> <valarray> <complex> <utility> Tarkoitus järjestetty joukkosäiliö kaksipäinen jono (säiliömuunnin) pino (säiliömuunnin) iteraattorit ja säiliötuki yleiskäyttöiset algoritmit numeeriset algoritmit algoritmien funktio-olio -tuki bittisarjoja kuvaavat oliot numeeristen arvojen taulukot kompleksilukujen tuki funktio-olioiden tuki Jotkin STL:n osat on esitelty myös virtojen otsikkotiedostoissa - <iostream>, <istream>, <ostream>, <sstream>. Nämä tukevat STL:n algoritmien pohjalta syöttöä ja tulostusta. vector-säiliön käyttö Paras paikka aloittaa STL:n käsittely on vector-säiliö, joka on lähinnä C++:n tavallista taulukkoa. Itse asiassa vector-säiliötä voidaan käyttää lähes kaikissa paikoissa, joissa voidaan käyttää C++:n taulukkoakin. vector-säiliön käyttö on paljon helpompaa kuin C++:n taulukon - taulukon kohdalla sinun tulee itse huolehtia taulukon koosta, mutta vector-säiliön kohdalla kaikki tällainen työ hoidetaan automaattisesti. Kun olet tottunut käyttämään vector-säiliötä, saatat päättääkin, että et enää koskaan käytä tavallista taulukkoa. Yksi tehtävä kuitenkin vaatii yhä C++:n taulukon käyttöä: staattisten alkuarvojen esittely: string nimet[] = Alf, Bjarne, Zaphod ; Suurissa ohjelmissa tällaisten määrittelyjen määrä kannattaa pitää mahdollisimman pienenä. On usein parempi hakea kiinteät alkuarvot ohjelman resurssitiedoista suoritusaikana. 826 Kokeile itse - vector<> vs. C++:n taulukko Katsotaan pikaisesti int-taulukkoa ja int-tyyppistä vector-säiliötä. Huomaamme, että ne toimivat suurelta osin samaan tapaan. // Esimerkki 20.1 Taulukon ja vector-säiliön pikavertailu #include <iostream> #include <vector> using namespace std;
5 Standardi mallikirjasto int main() int a[10]; vector<int> v(10); // C++:n taulukon esittely // vastaava STL:n vector-säiliön esittely cout << "10-alkioisen taulukon koko: " << sizeof a << endl; cout << "10-alkioisen vector-säiliön koko: " << sizeof v << endl; for (int i = 0; i < 10; ++i) a[i] = v[i] = i; int a_summa = 0, v_summa = 0; for (int i = 0; i < 10; ++i) a_summa += a[i]; v_summa += v[i]; cout << "taulukon 10 alkion summa on: " << a_summa << endl; cout << "vector-säiliön 10 alkion summa on: " << v_summa << endl; return 0; Kun suoritat tämän ohjelman, se tulostaa: 10-alkioisen taulukon koko: alkioisen vector-säiliön koko: 16 taulukon 10 alkion summa on: 45 vector-säiliön 10 alkion summa on: 45 Kuinka se toimii Kaikki STL:n oliot ovat osa standardikirjastoa, joten ne on määritelty nimiavaruudessa std. Tarvitsemiasi STL:n ominaisuuksia vastaavat otsikkotiedostot tulee tietysti sisällyttää lähdetekstiin ennen ominaisuuksien käyttöä. Jos haluat käyttää nimiä ilman std:n kirjoittamista aina nimen yhteyteen, voit ottaa std-nimiavaruuden käyttöön using-komennolla: #include <vector> using namespace std; Ainut ero taulukon ja vector-säiliön käytössä on niiden esittelyissä: int a[10]; vector<int> v(10); // C++:n taulukon esittely // vastaava STL:n vector-säiliön esittely C++:n taulukko on sisäänrakennettu tyyppi, joka esitellään []-syntaksilla. Toisaalta vectorsäiliö on mallina toteutettu standardikirjaston tyyppi. Malliparametri määrittelee vector-säiliön sisältämien olioiden tyypin. Tässä olemme esitelleet vector-säiliön, joka tallettaa int-tyyppisiä olioita. 827
6 C++ Ohjelmoijan käsikirja Tässä esimerkissä taulukko a ja vector-säiliö v ovat molemmat automaattisia muuttujia. Taulukon kohdalla tämä tarkoittaa sitä, että 10 kokonaisluvun tila varataan automaattisesta muistista. Minun tietokoneessani tyyppi int vie 4 tavua, joten taulukko a vie tilaa 40 tavua, kuten tulostuksesta huomaat. vector-säiliön olio v on myöskin automaattisessa näkyvyysalueessa, mutta (toisin kuin taulukko) se ei talleta sisältöään automaattiseen muistiin. Se varaa sisäisesti muistia alkioita varten vapaasta muistista. Aluksi se varaa talletettujen alkioiden verran muistia - mutta voit lisätä siihen niin monta alkiota kuin haluat. vector-säiliö huolehtii sisäisesti kaikista muistinvarauksen ongelmista (tietysti suhteessa vapaaseen muistiisi!). vector-olion ilmoitettu koko ei sisällä alkioita varten tarvittua muistia. Tästä syystä tällaista oliota kutsutaan usein kahvaksi. Se sisältää ainoastaan tarvittavan määrän muistia, jotta vectorsäiliö voi käsitellä alkioiden muistia. Kuten tulostuksesta huomaat, vector-olion sizeofoperaattorin palauttama koko on vain 16 tavua. v:n todellinen sisältö - muisti, joka tarvitaan sen tallettamien olioiden arvojen tallettamiseen - on varattu dynaamisesti, ja vie lisäksi 40 tavua vapaasta muistista. Taulukko vie siis selvästikin vähemmän muistia. vector-olion viemä lisätila on kuitenkin varsin pieni. Taulukon ongelma on siinä, että muisti on varattu ohjelmapinosta ja sen koko ja alkioiden lukumäärä on määrätty kiinteäksi jo käännösaikana. vector-olion viemän lisätilan vastapainona on kaksi korvaavaa hyötyä: ensiksikin, muistinhallinta on automaattinen ja toiseksi, voit lisätä alkioita vector-säiliöön aina tarvittaessa. 828 vector-säiliön perusoperaatiot vector-säiliön kanssa työskentely on huomattavasti joustavampaa kuin tavallisen taulukon kohdalla. Voit esimerkiksi lisätä alkioita vector-olion loppuun tai keskelle ja voit poistaa alkioita. Tarvittava muisti hallitaan aina automaattisesti. Saat aina selville vector-oliossa olevien alkioiden lukumäärän (kutsumalla sen size()-jäsenfunktiota) ja sen empty()-jäsenfunktio palauttaa arvon true, jos vector-oliossa ei ole lainkaan alkioita. Perusoperaatiot alkion lisäämiseksi tai poistamiseksi ovat: insert() Lisää yhden tai useamman alkion push_back() Lisää parametrinään saamansa oliot vector-olion perään erase() Poistaa yhden tai useamman alkion clear() Poistaa kaikki alkiot Jotta ymmärrät näiden alkioiden toiminnan, kokeillaan niitä esimerkin avulla. Meidän täytyy jo tässä esimerkissä käyttää iteraattoreita, mutta olet nähnyt iteraattoreita toiminnassa jo luvussa 14, joten tämän ei pitäisi olla kovinkaan pelottavaa. vector-olion begin()-jäsen palauttaa iteraattorin, joka osoittaa ensimmäiseen alkioon ja end()-jäsen palauttaa iteraattorin, joka osoittaa osoittimen, joka osoittaa yhden alkion verran viimeisen alkion ohi. Voit käyttää näitä iteraattoreita käydessäsi vector-olion alkioita läpi - kasvattamalla begin()-jäsenen palauttamaa iteraattoria, kunnes se on sama kuin end()-jäsenen palauttama iteraattori. Voit tietysti käyttää myös []-operaattoria; voit vapaasti päättää kumpaa tapaa käytät.
7 Standardi mallikirjasto Kokeile itse - Lyhyt johdatus vector-säiliöön! Tämä ohjelma käy läpi juuri käsittelemämme yksinkertaiset vector-säiliön operaatiot. Kokeilemme alkioiden lisäämistä ja poistamista vector-oliosta ja erilaisia tapoja tutkia vectorolion sisältöä. Huomaa, että sinun käännösympäristösi STL:n toteutus ei ehkä toimi tämän esimerkin kanssa täsmälleen kirjoitetulla tavalla, koska tällä hetkellä STL:n toteutukset vaihtelevat suurestikin. ANSI/ISO-standardin pitäisi muuttaa tämä tilanne, koska yhä enemmän ja enemmän C++:n toteutuksia päivitetään sen mukaiseksi. Jos esimerkki ei toimi, sinun tulee tarkistaa kirjaston dokumenteista, mikä ohjelman osa tulee muuttaa. Tässä esimerkissä on kirjoitettu funktio nayta_jarjestys(), joka havainnollistaa C++:n osoittimien ja vector-säiliön iteraattoreiden yhtäläisyyttä. tutki_vector()-funktio, joka tulostaa vector-säiliön sisällön ohjelman eri kohdissa, kutsuu nayta_jarjetys()-funktiota. // Esimerkki 20.2 vector<>-säiliön käsittely #include <iostream> #include <vector> #include <algorithm> // STL:n vector-säiliö // copy()-funktio using namespace std; // Näyttää alkiot järjestyksessä void nayta_jarjestys(const int* ensim, const int* viim) cout << " "; copy(ensim, viim, ostream_iterator<int>(cout, " ")); cout << "" << endl; // Näyttää vector-olion sisällön void tutki_vector(const vector<int>& v) cout << " vector-oliolla on " << v.size() << " alkiota: "; nayta_jarjestys(v.begin(), v.end()); int main() vector<int> v; cout << "uusi vektori luotu" << endl; tutki_vector(v); // Luodaan tyhjä vektori cout << "täytetään vektori taulukosta" << endl; int arvot[] = 1, 3, 7, 5; v.insert(v.end(), arvot+1, arvot+3); // Lisätään kaksi alkiota tutki_vector(v); cout << "lisätään arvo 5" << endl; v.push_back(5); tutki_vector(v); // Lisätään alkio loppuun 829
8 C++ Ohjelmoijan käsikirja cout << "poistetaan alkio siirtymässä 1" << endl; v.erase(&v[1]); // Poistetaan toinen alkio tutki_vector(v); cout << "lisätään alkio 4 siirtymään 1" << endl; v.insert (v.begin()+1, 4); // Lisätään alkio tutki_vector(v); cout << "poistetaan kaikki alkiot" << endl; v.clear(); tutki_vector(v); // Poistetaan kaikki alkiot return 0; Tulostus näyttää vector-olion sisällön jokaisen vector-operaation jälkeen: uusi vektori luotu vector-oliolla on 0 alkiota: täytetään vektori taulukosta vector-oliolla on 2 alkiota: 3 7 lisätään arvo 5 vector-oliolla on 3 alkiota: poistetaan alkio siirtymässä 1 vector-oliolla on 2 alkiota: 3 5 lisätään alkio 4 siirtymään 1 vector-oliolla on 3 alkiota: poistetaan kaikki alkiot vector-oliolla on 0 alkiota: Kuten huomaat, vector-säiliö on hyvä pitämään huolta sisällöstään. Tavallisen taulukon kohdalla kaikkien näiden operaatioiden toteuttaminen olisi ollut huomattavasti hankalampaa. Kuinka se toimii Koodi alkaa kahdella #include-komennolla, jotka sisällyttävät kaksi STL:n otsikkotiedostoa: #include <vector> // STL:n vector-säiliö #include <algorithm> // copy()-funktio 830 Otsikkotiedosto vector määrittelee vector-säiliön ja kaikki sen sisäänrakennetut operaatiot. STL mahdollistaa, että voit tehdä vector-oliolla paljon muutakin, kuin mikä kuuluu suoraan vectormallin ilmentymään. Otsikkotiedosto algorithm sisältää sitten loput tarvittavat herkut. Seuraavaksi määrittelemme nayta_jarjestys()-funktion, joka tulostaa alkiot järjestyksessä: void nayta_jarjestys(const int* ensim, const int* viim) cout << " "; copy(ensim, viim, ostream_iterator<int>(cout, " ")); cout << "" << endl;
9 Standardi mallikirjasto Tämä funktio käyttää STL:n copy()-algoritmia, joka tulostaa cout-virtaan kahden osoittimen osoittaman välin. Näet ohjelman tulostuksesta, että tämä myöskin toimii. Palaamme ostream_iterator<>-iteraattoriin myöhemmin, kun käsittelemme tulostusiteraattoreita tarkemmin. Funktio copy() on ainut funktio tässä esimerkissä, joka ei kuulu itse vector-malliin. Sen kaksi ensimmäistä parametriä määrittelevät lähteen välin. Kopiointi alkaa ensim-alkiosta ja jatkuu viim-alkioon saakka. viim-alkiota ei kuitenkaan kopioida. copy-funktio hyväksyy minkä tahansa iteraattorin kahden ensimmäisen parametrinsä arvoksi - tässä olemme käyttäneet tavallisia osoittimia. Kolmas parametri on kohdesijainti, joka määritellään myöskin iteraattorin avulla. Tässä esimerkissä käytämme tulostusiteraattoria, joka luodaan lausekkeella ostream_iterator<int>(cout, " "). STL sallii tällaisen joustavan määrittelyn. copy()-algoritmi sijoittaa jokaisen lähdealkion kohdeolioomme tietämättä tarkasti, minkälaista kohdetta se käsittelee - se vain sijoittaa kopioitavat oliot kolmantena parametrinä olevan iteraattorin mukaan ja olettaa, että iteraattori tietää, minne olio tulee sijoittaa. Tässä tapauksessa kohdeolio tulostaa siihen kopioidut arvot standardiin tulostusvirtaan cout. Voit välittää monia erilaisia iteraattoreita STL:n algoritmeille ja ne toimivat sen mukaisesti. Iteraattori voi olla kuten osoitin, joka lukee ja kirjoittaa arvoja muistiin, tai se voi olla monimutkaisempi olio, joka lukee tai kirjoittaa arvot virtaan. copy()- funktio toimii yhtä hyvin kopioitaessa olio vector-säiliöstä virtaan tai kopioitaessa tietynlainen olio säiliöstä toiseen. Funktio tutki_vector() kutsuu nayta_jarjetys()-funktiotamme: void tutki_vector(const vector<int>& v) cout << " vector-oliolla on " << v.size() << " alkiota: "; nayta_jarjestys(v.begin(), v.end());! Tämä funktio havainnollistaa yhtä vector-säiliön varsin hienoa ominaisuutta. Huomaa, että välitämme vector-olion vain yhtenä parametrinä. Meidän ei tarvitse välittää toista parametriä, joka kertoisi vector-säiliön sisältämien alkioiden lukumäärän - eikä kuinka monta alkiota vectorsäiliöön voi sijoittaa. Tulostamme vector-olion alkioiden lukumäärän kutsumalla sen size()- jäsentä. vector-olio tietää aina, montako alkiota siihen on talletettu. Huomaa, että saamme vector-olion ensimmäisen ja viimeisen alkion iteraattorin selville begin()- ja end()-jäsenillä ja välitämme ne nayta_jarjestys()-funktiolle. Nämä iteraattorit muunnetaan automaattisesti nayta_jarjestys()-funktion parametrien tyyppisiksi, eli int*-tyyppisiksi. Vector-iteraattorit ovat lähes identtiset tavallisiin C++:n osoittimiin. Itse asiassa, monet STL:n toteutukset määrittelevät vector<t>::iterator-tyypin tavalliseksi C++:n T*-tyyppiseksi osoittimeksi. Juuri tämä tekee vector-säiliöstä niin hyvän tavallisten taulukoiden korvaajan. Lähes kaikki, mitä olet tehnyt osoittimien kanssa voit tehdä myös vector-säiliön kanssa. 831
10 C++ Ohjelmoijan käsikirja Kuten olemme jo kertoneet, v.begin() osoittaa ensimmäiseen alkioon. Pääset käsiksi ensimmäisen alkion sisältöön kirjoittamalla lausekkeen *v.begin(), v[0] tai v.front(). Mitä näistä käytät, riippuu käyttötilanteesta. Myöhemmin tässä luvussa näemme tilanteita, joissa jokin näistä on luonnollisempi vaihtoehto kuin muut. Huomaa, että et voi käyttää osoittimen end() osoittamaa arvoa - se osoittaa aina yhden osoitteen säiliön viimeisen alkion yli. Osoitinta end() kutsutaan yleensä lopun yli -osoittimeksi. Eli *v.begin() on sallittu, mutta varsin samanlainen lauseke *v.end() on huono idea. Sen sijaan *(v.end()-1) on sallittu ja hyödyllinen tapa päästä käsiksi viimeiseen alkioon. Viimeiseen alkioon pääset käsiksi myös lausekkeilla *(v.begin()+v.size()-1), v[v.size()-1] tai yksinkertaisesti v.back(). Ennen kuin yrität käsitellä alkiota, sinun tulee varmistaa, että viimeinen alkio on olemassa. Nopea tapa tarkistaa tämä on kutsua jäsenfunktiota v.empty(), joka palauttaa arvon true, kun v ei sisällä ainuttakaan alkiota. Ohjelmamme käyttää vector-mallin ilmentymää vector<int>, joten esittelemme int-tyyppisiä arvoja tallettavan vector-säiliön seuraavasti: vector<int> v; // Luodaan tyhjä vektori Tässä esittelemme v:n mallin vector<int>-ilmentymänä kutsumalla oletusmuodostinfunktiota. Näemme tulostuksesta, että uusi säiliömme on aluksi tyhjä. Käytössäsi on tietysti myös muunlaisia muodostinfunktioita. Jos esimerkiksi haluaisit säiliön 50 double-tyyppiselle arvolle, voisit esitellä vector-säiliön data seuraavasti: vector<double> data(50); Uuteen säiliöömme voimme tallettaa arvoja monella tavalla. Yksi kaikkein tehokkaimmista on insert()-jäsenfunktio, joka kopioi kokonaisen sarjan arvoja: cout << "täytetään vektori taulukosta" << endl; int arvot[] = 1, 3, 7, 5; v.insert(v.end(), arvot+1, arvot+3); // Lisätään kaksi alkiota tutki_vector(v); 832 Tästä huomaa jälleen, että STL mielellään määrittelee sarjat kahden osoittimen väliin jäävällä välillä. Funktion insert() ensimmäinen parametri, v.end(), on osoitin sijaintikohtaan, johon haluamme alkiot sijoittaa. Huomaa, että käytämme tässä lopun yli -osoittavaa osoitinta - sen käyttö on sallittu, kun yhdistät arvoja. Tästä onkin helppo muistaa, mitä lopun yli -osoitin tarkoittaa: se on sijaintikohta, johon seuraava lisättävä arvo sijoitetaan. Eli voit käyttää end()-osoitinta uusien alkioiden lisäämiseen - mutta älä yritä käsitellä sen osoittamaa arvoa. insert()-funktion toinen ja kolmas parametri, eli lausekkeet arvot-1 ja arvot+3, määrittelevät yhdessä lisättävien alkioiden välin. Tässä lähteemme on taulukko arvot ja kopioimme tässä toisen ja kolmannen alkion - eli alkaen kohdasta arvot+1 ja päättyen alkiota arvot+3 edeltävään alkioon.
11 Standardi mallikirjasto! Välit määritellään tavallisesti tällä tavalla STL:ssä - väliä, joka sisältää ensimmäisen alkion, mutta ei viimeistä, kutsutaan puoliavoimeksi väliksi. Tällainen merkitään [alku, loppu), jossa sulkeet osoittavat, että väli on suljettu vasemmasta päästä, mutta avoin oikeasta päästä. Eli väli sisältää kohdan alku, mutta ei kohtaa loppu. Kun määrittelet [alku, loppu) välin, kuten esimerkiksi arvoilla arvot+1 ja arvot+3, varmista, että loppu on suurempi kuin alku - ja että molemmat osoittimet on liitetty samaan lähdeolioon. Nämä ovat varsin yleisiä - ja vaikeasti havaittavia - virheitä. Palataan esimerkin 20.2 käsittelyyn. Lisäämme vector-säiliöön alkion push_back()-jäsenellä: v.push_back(5); // Lisätään alkio loppuun Tämä lisää arvon 5 uudeksi alkioksi v-olion perään. Miksi tätä funktiota ei kutsuta yksinkertaisesti nimellä append()? Jos push saa sinut ajattelemaan pinoja, olet oikeilla jäljillä. Itse asiassa STL sisältää pinomuuntimen (stack adaptor), jolla voit muuntaa vector-säiliön pinoksi. Emme käsittele STL:n muuntimia tässä yhteydessä, saat lisätietoa STL:n dokumenteistasi. Monet STL:n nimet viittaavat siihen, että säiliöt voidaan muuntaa toimimaan toisella tavalla, kuten stack ja queue. Seuraavaksi testaamme erase()- ja insert()-funktioita: v.erase(&v[1]); // Poistetaan toinen alkio erase()- ja insert()-operaatioihin kuuluu alkioiden siirtelyä, jotta lisättäville alkioille saadaan tilaa tai poistettavan alkion aukko poistetaan. Sisäisesti vector-säiliö kopioi alkioita, jotta ne pysyvät oikeassa järjestyksessä. Tämä voi olla hyvin hidas operaatio, kuten näemme, kun käsittelemme vector-säiliön muistinhallintaa. Koska vector-säiliö on malli, se voi sisältää myös luokkaolioita, ja tällöin erase()-funktion tulee kutsua jokaisen poistettavan olion tuhoajafunktiota. Tämä lause poistaa toisen alkion vector-säiliöstä v. Se käyttää erase()-funktion yksinkertaisinta muotoa, jolle välitetään vain yksi iteraattori, joka määrittelee yhden poistettavan alkion. Osoitintyyppinen parametri muunnetaan automaattisesti iteraattoriksi. Sen sijaan, että olisimme käyttäneet begin()- ja end()-jäseniä iteraattoreiden muodostuksessa, olemme käyttäneet taulukkomuotoa. Tällä havainnollistamme sitä, että v teeskentelee olevansa taulukko. Lauseke &v[1] viittaa v:n toisen alkion osoitteeseen. Tämän lauseen tuloksena toinen alkio, jonka arvo on 7, poistetaan vector-säiliöstä v. Seuraavaksi lisäämme uuden alkion lauseella: v.insert (v.begin()+1, 4); // Lisätään alkio 833
12 C++ Ohjelmoijan käsikirja! Olemme jo kerran käyttäneet insert()-funktiota. Tällöin sillä oli kaksi iteraattoriparametriä. Tässä muodossa sillä on kaksi parametriä, joista ensimmäinen on iteraattori ja toinen kokonaisluku. Määrittelemme sijaintikohdan lausekkeella v.begin()+1 ja lisäämme uuden alkion - arvon 4 - tähän sijaintikohtaan. Tässä sijaintikohdassa nyt oleva alkio ja kaikki sitä seuraavat alkiot tulee ensin siirtää eteenpäin, jotta uusi arvo mahtuu väliin. Nytkin vector-olio varaa uuden tilan ja kopioi alkiot automaattisesti. Tämä automaattinen kopiointi on varsin miellyttävää. Ohjelmasi suoritus kuitenkin hidastuu merkittävästi, jos vector-olio on suuri ja lisäät tai poistat alkioita olion alkupäästä. STL sisältää toisen säiliön, listan list<>, joka tekee nämä kaikki samat asiat, mutta mitään kopiointia ei tarvitse tehdä. Näemme listan toiminnassa varsin pian. Lopuksi poistamme kaikki alkiot lauseella: v.clear(); // Poistetaan kaikki alkiot Voimme käyttää clear()-jäsentä, jos haluamme poistaa kaikki alkiot eksplisiittisesti. Tämä ei ole kuitenkaan tarpeen. Kun vector-olion v näkyvyysalue päättyy (lohkon lopussa), v ja sen sisältö poistetaan automaattisesti v:n tuhoajafunktion toimesta. v.clear() on itse asiassa lyhyempi muoto lausekkeesta v.erase(v.begin(), v.end()). vector-säiliön käyttö taulukko-operaatioissa Katsotaan seuraavaksi esimerkkiä, johon törmäsimme ensimmäisen kerran luvussa 8, kun käsittelimme funktioita. Seuraavassa on keskiarvo()-funktio esimerkistä 8.5, joka on kiinnostaja siitä syystä, että sille välitetään parametrinä taulukko[]: // Funktio, joka laskee keskiarvon double keskiarvo(double taulukko[], int lkm) double summa = 0.0; // Tähän lasketaan summa for(int i = 0 ; i < lkm ; i++) summa += taulukko[i]; // Summataan taulukon alkiot return summa / lkm; // Palautetaan keskiarvo 834 Ennen kuin STL oli olemassa, C- ja C++-ohjelmat kirjoitettiin tällä tavalla. Vaikka olemmekin käsitelleet runsaasti uusia asioita luvun 8 jälkeen, muistat varmasti vieläkin, että double taulukko[] ja double* taulukko tarkoittavat tässä yhteydessä aivan samaa - eli keskiarvo()-funktion ensimmäinen parametri on osoitin. Koska taulukko ei tiedä, montako alkiota siinä on, meidän tulee aina välittää myös toinen parametri, joka kertoo taulukon alkioiden lukumäärän (joskus meidän tarvitsee välittää myöskin taulukon kapasiteetti). Katsotaan uudelleen esimerkkimme 20.2 nayta_jarjestys()-funktiotamme. Tälle funktiolle välitetään ensimmäisenä parametrinä myöskin osoitin, mutta käytetään vain erilaista muotoa. Toinen parametri on myöskin osoitin:
13 Standardi mallikirjasto void nayta_jarjestys(const int* ensim, const int* viim) cout << " "; copy(ensim, viim, ostream_iterator<int>(cout, " ")); cout << "" << endl; Koska osoittimet vastaavat iteraattoreita, voimme ajatella parametrien olevan tässä iteraattoreita. Väli ensim - viim on jälleen puoliavoin väli - ensim otetaan mukaan, mutta viim ei oteta. Tämä on kuitenkin täysin eri kuin kahden indeksin käyttäminen, koska välin olioiden tyyppi on iteraattoreiden yhteydessä implisiittinen. Vaikka vector-säiliön ja välin käyttäminen on eri taulukkoon ja muuttujaan lkm verrattuna, saamme kuitenkin helposti selville käsiteltävien alkioiden lukumäärän: int lkm = viim - ensim; Eli miksi STL käyttää välejä, eikä taulukoita ja lukumääriä? Tähän on useita syitä. Ensinnäkin, jos taulukoita käytetään runsaasti, osoittimien käyttö on miellyttävämpää. Toiseksi, se on myös huomattavasti tehokkaampaa. Kun näet lauseen, jossa on moniulotteinen taulukko, kääntäjä joutuu tekemään runsaasti töitä lauseen kohdalla. Tutkitaan esimerkiksi seuraavaa koodia: // kun kirjoitat seuraavaa double ilmanpaine[200][200][200]; double paine_keskella = ilmanpaine[99][100][101]; Kääntäjä löytää alkion ilmanpaine[99][100][101] suorittamalla seuraavat lauseet: // kääntäjä tekee todellisuudessa seuraavaa double* apu = ilmanpaine + 99 * sizeof (ilmanpaine[0]) * sizeof (ilmanpaine[0][0]) + 101; double paine_keskella = *apu; Kuten huomaat, kääntäjä tekee kaiken tämän laskennan vain muuntaakseen kaikki takaisin osoitinlausekkeeksi. Hyvä kääntäjä tekee lisäksi paljon yksinkertaistaakseen tätä aina, kun se vain on mahdollista - mutta silti kaikki nämä laskennat ja lisäykset vaativat aikaa. Yksinkertainen totuus on, että osoittimet ovat yksinkertaisempia kuin taulukot ja lisäksi, kun muistamme, että iteraattori on olio, joka toimii osoittimen tapaan, niin tässä on syy siihen, miksi STL:ssä käytetään yleensä välejä, jotka on määritelty iteraattoriparin avulla. Keskiarvon laskeminen iteraattoreiden avulla Voimme määritellä mallin keskiarvo()-funktiolle, joka käyttää iteraattoreita taulukkojen sijaan. Mallin koodi olisi tässä tapauksessa seuraava: template <typename Iter> double keskiarvo(iter a, Iter loppu) double summa = 0.0; // Tähän lasketaan summa 835
14 C++ Ohjelmoijan käsikirja int lkm = 0 ; for( ; a!= loppu ; lkm++) summa += *a++; // Summataan taulukon alkiot // Palautetaan keskiarvo return summa / lkm; Huomaa, kuinka vähän suoritamme operaatioita parametrimuuttujalle a: a!= loppu tarkistaa viimeisen arvon *a haetaan nykyinen arvo a++ siirrytään seuraavaan arvoon Kaksi viimeistä operaatiota on yhdistetty yhdeksi lausekkeeksi *a++. Huomaat varmastikin jo nyt, että tällainen lauseke on yksi kaikkein useimmin C++:ssa käytetty lauseke. Olemme koodanneet mallin siten, että operaation * ja jälkiliitteellisen ++ täytyy toimia tyypille Iter ja näin on sekä osoittimien että iteraattoreiden kohdalla. Iteraattoreiden käyttö yksinkertaisti koodia varsin paljon. Kokeillaan sitä esimerkin avulla. Kokeile itse - Keskiarvon laskeminen iteraattoreiden avulla Seuraavassa on ohjelma, joka laskee keskiarvot mallimme avulla: // Esimerkki 20.3 Keskiarvon laskeminen iteraattoreiden avulla #include <iostream> #include <vector> using namespace std; template <typename Iter> double keskiarvo(iter a, Iter loppu) double summa = 0.0; int lkm = 0 ; for( ; a!= loppu ; lkm++) summa += *a++; // Tähän lasketaan summa // Summataan taulukon alkiot return summa / lkm; // Palautetaan keskiarvo int main() double lampotila[] = 10.5, 20.0, 8.5 ; cout << "taulukon keskiarvo = " << keskiarvo(lampotila, lampotila + (sizeof lampotila/sizeof lampotila[0])) << endl; vector<int> aurinkoinen; aurinkoinen.push_back(7); aurinkoinen.push_back(12); aurinkoinen.push_back(15); cout << aurinkoinen.size() << " kuukautta" << endl; cout << "aurinkoisten päivien lukumäärän keskiarvo: "; cout << keskiarvo(aurinkoinen.begin(), aurinkoinen.end()) << endl; return 0; 836
15 Standardi mallikirjasto Tämän ohjelman tulostus on seuraava: taulukon keskiarvo = 13 3 kuukautta aurinkoisten päivien lukumäärän keskiarvo: Kuinka se toimii Mallien hyvänä puolena on se, että saat niin monta versiota kuin tarvitset, mutta joudut määrittelemään vain yhden. Tämä esimerkki muodostaa kaksi ilmentymää mallifunktiosta keskiarvo. Ensimmäinen keskiarvo-mallin ilmentymä on tavalliseen C++:n taulukkoon sijoitetuille arvoille: double lampotila[] = 10.5, 20.0, 8.5 ; cout << "taulukon keskiarvo = " << keskiarvo(lampotila, lampotila + (sizeof lampotila/sizeof lampotila[0])) << endl; Mallin ilmentymän tyyppi määritellään automaattisesti funktion parametreistä. Toisen parametrin tulee olla osoitin mukaan haluamaamme viimeistä alkiota seuraavaan alkioon - laskemme tämän lisäämällä taulukon alkioiden lukumäärän osoittimeen lampotila. Toinen keskiarvo-mallin ilmentymä on vector-säiliöön talletetuille int-tyyppisille arvoille. Ensin esittelemme vector<int>-olion aurinkoinen: vector<int> aurinkoinen; Ilmentymä luodaan lauseessa: cout << keskiarvo(aurinkoinen.begin(), aurinkoinen.end()) << endl; aurinkoinen.begin() ja aurinkoinen.end() -funktioiden palauttamat paluuarvot ovat tyyppiä vector<int>::iterator - tätä tyyppiä käytetään mallin toisen version ilmentymän muodostamisessa. Eli mallifunktion keskiarvo() kahden ilmentymän allekirjoitukset näyttävät seuraavilta: double keskiarvo<double*>(double* a, double* loppu); double keskiarvo<vector<int>::iterator>(vector<int>::iterator a, vector<int>::iterator loppu); Kuten olemme maininneet, jotkin STL:n vector-säiliön toteutukset käyttävät osoittimia (kuten int*) iteraattoreina. Tällöin toisen ilmentymän allekirjoitus näyttää seuraavalta: double keskiarvo<int*>(int* a, int* loppu); Kaikki STL:n toteutukset eivät kuitenkaan näin tee eikä muutenkaan ole korrektia olettaa, että voimme käyttää lyhyempää muotoa. Jotta ymmärrät, miksi olemme kirjoittaneet ::iterator-osan tyyppiin, vilkaistaan, miltä vectormallin määrittely näyttäisi: template <typename Arvo> 837
16 C++ Ohjelmoijan käsikirja class vector public: typedef Arvo* iterator; // paljon lisää koodia... ; Kun ilmennämme vector-mallin ilmentymän vector<int>, mallista tulee jotain seuraavankaltaista: class vector<int> public: typedef int* iterator; ; Eli vector<int>::iterator on vain tapa viitata siihen tyyppiin, jota vector-mallin ilmentymässä on käytetty iteraattorin toteutuksessa. Nimi iterator kuvaa tätä tyyppiä. Kuten tulostuksesta huomaat, keskiarvon laskenta sujuu kuten odotimmekin. Funktiomme toimii niin vector-säiliön alkioiden kuin tavallisen taulukonkin yhteydessä. Mallitaulukko-vaihtoehto Olisimme voineet hyödyntää malleja myöskin taulukkomuotoisessa ratkaisussa. Kokeile itse - Keskiarvon laskeminen Mallitaulukon avulla Tässä on vaihtoehtoinen versio esimerkille 20.3: // Esimerkki 20.4 Keskiarvon laskeminen mallitaulukon avulla #include <iostream> #include <vector> using namespace std; template <typename Taulukko> double keskiarvo (Taulukko a, long lkm) // Taulukko voi olla osoitin tai iteraattori double summa = 0.0; for (long i = 0; i < lkm; ++i) summa += a[i]; return summa/lkm; // tapahtuu virhetilanne, jos lkm==0 int main() double lampotila[] = 10.5, 20.0, 8.5 ; // Toinen parametri on nyt lukumäärä cout << "taulukon keskiarvo = " << keskiarvo(lampotila, (sizeof lampotila/sizeof lampotila[0])) << endl; 838
17 Standardi mallikirjasto vector<int> aurinkoinen; aurinkoinen.push_back(7); aurinkoinen.push_back(12); aurinkoinen.push_back(15); cout << aurinkoinen.size() << " kuukautta" << endl; cout << "aurinkoisten päivien lukumäärän keskiarvo: "; cout << keskiarvo(aurinkoinen.begin(), aurinkoinen.end() - aurinkoinen.begin()) << endl; return 0; Tämän ohjelman tulostus on aivan sama kuin esimerkissä Koodi näyttää jopa selkeämmältä! Huomaa, kuinka nyt tarvitsemme ainoastaan yhden operaation alkiolle a, nimittäin a.operator[](long). Tästä huomaamme heti, että indeksointioperaattorin parametri on long-tyyppinen - se kuvaa indeksin arvoa. Tässä versiossa meidän täytyy esitellä oma silmukkamuuttuja i - edellisessä versiossa se oli tarpeeton. Iteraattori istream_iterator Seuraava esimerkki havainnollistaa, kuinka voit käyttää mallialgoritmia epätavallistenkin iteraattoreiden kanssa. Olemme jo nähneet ostream_iterator-iteraattorin toiminnassa - tällä kertaa käytämme sen vastakohtaa, istream_iterator, joka hakee tiedon syöttövirrasta. Kokeile itse - Maaginen istream_iterator<> Esimerkeissä 20.3 ja 20.4 käytimme keskiarvo()-funktiotamme arvoille, jotka olivat olemassa taulukossa tai säiliössä. Tällä kertaa keskiarvo()-funktio lukee arvot suoraan syöttövirrasta. Käytämme tässä jälleen esimerkin 20.3 mallifunktiota: // Esimerkki 20.5 Lasketaan virrasta luettujen arvojen keskiarvo #include <iostream> #include <iterator> // istream_iterator<>-malli using namespace std; template <typename Iter> double keskiarvo(iter a, Iter loppu) double summa = 0.0; // Tähän lasketaan summa int lkm = 0 ; for( ; a!= loppu ; lkm++) summa += *a++; // Summataan taulukon alkiot return summa / lkm; // Palautetaan keskiarvo int main() cout << "Syötä numeroita, eroteltuina tyhjillä merkeillä - välilyönneillä, " << endl << "sarkaimella tai rivinvaihdoilla. Lopuksi paina merkkiyhdistelmää, " << endl << "joka vastaa tiedoston loppua (Ctrl-Z PC:ssä)" << endl; double ka = keskiarvo(istream_iterator<double>(cin), istream_iterator<double>()); cout << "Arvojen keskiarvo on " << ka << endl; return 0; 839
18 C++ Ohjelmoijan käsikirja! Kun suoritat tämän ohjelman, varmista, että käytät oikeaa merkkiyhdistelmää syöttövirran sulkemiseksi. PC-maailmassa tämä merkkiyhdistelmä on Ctrl-Z. Tämän jälkeen voi olla tarpeen painaa Enter. Eräs suosittu ohjelmointiympäristö tulee yhtiöltä, jonka tulee kuulla kaikki kahteen kertaan, joten jos ensimmäinen Ctrl-Z ei sulje virtaa, yritä painaa Ctrl-Z useampaan kertaan eri riveille. Tässä on ohjelman tulostus: Syötä numeroita, eroteltuina tyhjillä merkeillä - välilyönneillä, sarkaimella tai rivinvaihdoilla. Lopuksi paina merkkiyhdistelmää, joka vastaa tiedoston loppua (Ctrl-Z PC:ssä) Arvojen keskiarvo on 4.6 Sinun järjestelmäsi saattaa tulostaa jotain hieman erilaista. Älä yritä suorittaa tätä ohjelmaa liian hartaasti, jos se tuottaa ongelmia. Myöhemmin meillä on toinen esimerkki, jossa vältetään konsolin käyttö. Palaamme istream_iterator-iteraattoriin vielä uudelleen. Kuinka se toimii Seuraava lause muodostaa mallimme ilmentymän: double ka = keskiarvo(istream_iterator<double>(cin), istream_iterator<double>()); Tässä välitämme keskiarvo()-funktiollemme varsin oudon näköisiä lausekkeita! Kirjoitetaan tämä toisella tavalla, jotta voimme tutkia sitä tarkemmin: istream_iterator<double> alku(cin); istream_iterator<double> loppu; double ka = keskiarvo(alku, loppu); Olio alku on mallin istream_iterator<double> ilmentymä. Virtaolio cin välitetään muodostinfunktiolle, jotta iteraattori lukee standardista syöttövirrasta. Olio loppu on myöskin mallin istream_iterator<double> ilmentymä. Luomme end-olion käyttämällä istream_iterator<double>-luokan oletusmuodostinfunktiota. Kun muuttuja end luodaan tällä tavalla, se toimii lopun yli -arvona, joka vastaa tiedoston loppua. Uuden versiomme alku ja loppu eivät todellakaan ole osoittimia - ne ovat luokkaolioita, joten miksi tämä toimii? Vastaus on se, että nämä oliot ovat iteraattoreita, mikä tarkoittaa, että ne voivat käyttäytyä osoittimien tapaan. Ne silti välittävät käyttöömme kolme operaattoria, joista olemme riippuvaisia keskiarvo()-funktiossamme: 840 bool Iter::operator!=(Iter end_value); double Iter::operator*(); Iter Iter::operator++(int); Vertailu Viittaus Lisäys
19 Standardi mallikirjasto Tällä kertaa olemme esittäneet nämä luokkafunktioina, koska ne todellakin ovat luokkafunktioita. Ne ovat luokan istream_iterator<double> uudelleenmääriteltyjä operaattorifunktioita. Palauta mieleen, että operator++(int) ei itse asiassa saa int-tyyppistä parametriä - tällä tavalla vain kerromme kääntäjälle että tarkoitamme lisäysoperaattorin jälkiliitteellistä muotoa. Voimme käyttää näitä operaatioita minkä tahansa istream_iterator<double>-tyyppisen olion kohdalla. Toiminnallisuutta sisältävät istream_iterator-iteraattorit Edellä olleet istream_iterator-oliot teeskentelevät olevansa osoittimia, kuten LtkPtr-luokkamme oliot esimerkissä Nämä oliot pystyvät kuitenkin paljon muuhunkin - ne voivat sisältää monimutkaistakin toiminnallisuutta, kuten virtojen I/O-operaatioita. Tämä on erittäin keskeinen ajatus, sillä sen avulla STL on niin tehokas kirjasto. Kun yhdistämme mallifunktiot ja iteraattorit, voimme hankkia välimme mistä tahansa lähteestä. Tätä et voi tehdä vanhan taulukkomuotoisen esitystavan avulla. Kokeile itse - Lisää istream_iterator-taikaa Korostaaksemme iteraattoreiden yleistä luonnetta, tässä on vielä yksi esimerkki. Tällä kertaa kokeilemme puoliavointa väliä arvoilla, jotka ovat merkkijonossa. Jos sinulla oli vaikeuksia esimerkin 20.5 suorituksessa, kokeile mieluummin tätä. // Esimerkki 20.6 Lasketaan merkkijonovirran arvojen keskiarvo #include <iostream> #include <iterator> // istream_iterator<>-malli #include <sstream> // istringstream-iteraattori using namespace std; template <typename Iter> double keskiarvo(iter a, Iter loppu) double summa = 0.0; // Tähän lasketaan summa int lkm = 0 ; for( ; a!= loppu ; lkm++) summa += *a++; // Summataan taulukon alkiot return summa / lkm; // Palautetaan keskiarvo int main() char* kurssi_lukemat = " "; istringstream kello (kurssi_lukemat); istream_iterator<double> alku(kello); istream_iterator<double> loppu; cout << "Lukemat: " << kurssi_lukemat << ". Päivän keskiarvo on "; cout << keskiarvo (alku, loppu) << endl; return 0; Esimerkin tulostus näyttää seuraavalta: Lukemat: Päivän keskiarvo on
20 C++ Ohjelmoijan käsikirja Kuinka se toimii Jos katsot tarkkaan, tämä esimerkki on lähes identtinen esimerkkiin 20.5 verrattuna. Erona on se, että olemme korvanneet cin-virran omalla kello-virralla käyttämällä luokkaa istringstream: char* kurssi_lukemat = " "; istringstream kello (kurssi_lukemat); Alustamme kello-syöttövirtamme siten, että se lukee arvot suoraan ohjelman merkkijonosta kurssi_lukemat. Tämän jälkeen välitämme virtaolion istream_iterator<doubel>muodostinfunktiolle: istream_iterator<double> alku(kello); Uuden kello-virtamme hienona piirteenä on se, että sitä voidaan käyttää useimmissa tapauksissa, joissa saattaisimme käyttää cin-virtaa - istream_iterator ei ole niin pikkutarkka. Se käyttää tyytyväisenä istingstream-oliotamme kello tai muuta merkkijonojen lähdettä virran cin sijaan. Kaikki muu säilyy aivan samana, mukaan lukien keskiarvo()-mallimme! Lisää iteraattoreista Esimerkeissä olemme päässeet varsin pitkälle käyttämällä mallipohjaista versiotamme keskiarvo()-funktiosta. Olemme kuitenkin muodostaneet vain kolme erilaista ilmentymää: double keskiarvo<double*>(double*, double*); double keskiarvo<int*>(int*, int*); double keskiarvo<istream_iterator<double> > (istream_iterator<double>, istream_iterator<double>); Näistä näet selvästi, että kaksi ensimmäistä versiota käsittelevät yksinkertaisia osoittimia, kun taas kolmas käsittelee istream_iterator-oliota. Esimerkiksi esimerkissä 20.3 välitämme alkiot vector<int>-säiliöstä keskiarvo<int*>-versiolle. Esimerkeissä 20.5 ja 20.6 käytämme istream_iterator-oliota, jolloin voimme lukea numeeriset arvot konsolilta tai suoraan tiedostosta. Osoitinversiot käsittävät sekä C++:n perustaulukot että vector-säiliöt, kun taas istream_iterator-versio käsittää tiedostot ja merkkijonot. Emmekä ole vielä kuin hieman raapaisseet pintaa, mitä iteraattoreihin tulee. Iteraattoriolio näyttää yhä varsin mysteeriseltä, joten pysähdytään hetkeksi ja mennään hieman syvemmälle iteraattoriolioiden toimintaan. Huomaat varsin pian, että omien iteraattoriluokkien luominen ei olekaan niin vaikeaa. 842 Iteraattorit Meillä on jo hieman kokemusta hyvin yksinkertaisesta iteraattorista, kun luvussa 14 loimme LtkPtr-luokan; mutta voimme tehdä huomattavasti enemmänkin. Ymmärrämme paremmin STL:n iteraattoreiden toimintaa, jos luomme oman iteraattorimme aloittamalla ensin aivan tyhjästä. Aloitamme yksinkertaisimmasta mahdollisesta iteraattorista ja laajennamme sitä pikku hiljaa, kunnes se on sellainen kuin haluammekin sen olevan - STL:n iteraattoreiden veljeskunnan täysi jäsen.
21 Standardi mallikirjasto Kokeile itse - Oman iteraattorin luonti Aloitamme yksinkertaisesta iteraattorista, joka käy läpi kokonaislukuja. Seuraavassa on esimerkkimme koodi: // Esimerkki 20.7 Yksinkertainen kokonaislukuiteraattoriluokka #include <iostream> using namespace std; class Kokonaisluku public: Kokonaisluku (int par = 0) : X(par) bool operator!=(const Kokonaisluku& par) const //!= -vertailu if (X == par.x) // Debuggaustulostus cout << endl // Näytetään, että olemme täällä << "operator!= palauttaa arvon false" << endl; return X!= par.x; int operator*() const return X; Kokonaisluku& operator++() ++X; return *this; //Osoitusoperaattori // Etuliitteellinen lisäysoperaattori private: int X; ; int main() Kokonaisluku alku(3); Kokonaisluku loppu(7); cout << "Tämän päivän kokonaisluvut ovat: "; for( ; alku!= loppu ; ++alku) cout << *alku << " "; cout << endl; return 0; Kun esimerkki suoritetaan, se tulostaa: Tämän päivän kokonaisluvut ovat: operator!= palauttaa arvon false Kuinka se toimii Ohjelma toimii aivan kuin olisimme esitelleet muuttujat alku ja loppu tavallisiksi kokonaisluvuiksi ja sijoittaneet niihin samat arvot. Kokonaisluku-luokkamme tulostaa lisäksi lisärivin, jos uudelleenmääritelty!=-operaattori palauttaa arvon false. Määrittelemme Kokonaisluku-luokan muodostinfunktion seuraavasti: 843
22 C++ Ohjelmoijan käsikirja Kokonaisluku (int par = 0) : X(par) Kokonaisluku-luokalla on jäsenmuuttuja X, joka tallettaa nykyisen arvon. Jos emme onnistu alustamaan Kokonaisluku-oliota esittelyn yhteydessä, jäsenmuuttujan X oletusarvo on 0. Luokalle määritellään!=-operaattorifunktio: bool operator!=(const Kokonaisluku& par) const //!= -vertailu if (X == par.x) // Debuggaustulostus cout << endl // Näytetään, että olemme täällä << "operator!= palauttaa arvon false" << endl; return X!= par.x; Tämän oikeanpuolisena parametrinä on Kokonaisluku-olio ja se palauttaa bool-tyyppisen paluuarvon. Ohjelman tulostuksesta huomaat, että heti kun alku on yhtä suuri kuin loppu,!=operaattori palauttaa arvon false ja silmukan suoritus päättyy. Osoitusoperaattori määritellään seuraavasti: int operator*() const return X; //Osoitusoperaattori Tämä palauttaa nykyisen Kokonaisluku-olion jäsenmuuttujan X. Tämä funktio, sekä myös operator!=()-funktio, määritellään const-tyyppisiksi, koska ne eivät muuta olion sisältöä. Etuliitteellinen lisäysoperaattori määritellään seuraavasti: Kokonaisluku& operator++() ++X; return *this; // Etuliitteellinen lisäysoperaattori Edellisten esimerkkien keskiarvo()-funktiossa käytimme lauseketta *a++ jälkiliitteellisen operator++(int)-funktion sijaan. Kokonaisluku-luokallamme on nyt yksinkertaiset funktiot. Tässä on itse asiassa kaikki mitä tarvitsemme, jotta saamme sen toimimaan osoittimen tapaan, jolloin voimme tehdä joitakin varsin mielikuvituksellisia asioita. main()-funktiossa meillä on lause: for( ; alku!= loppu ; ++alku) cout << *alku << " "; 844 Tällaisen lauseen pitäisi näyttää jo varsin tutulta. Käytimme kovin samanlaista lausetta keskiarvo()-algoritmissamme, mutta tällöin käytimme *a++-lauseketta. Itse asiassa tulostuslauseen *alku:n korvaaminen *alku++:lla ei toimi tässä, koska emme ole määritelleet operator++(int)- funktiota, joka tukee Kokonaisluku-luokan jälkiliitteellistä muotoa. Tästä syystä käytämme muotoa *alku tulostuslauseessa ja lauseketta ++alku silmukan kontrollilausekkeessa. Itse asiassa olisimme voineet kirjoittaa:
23 Standardi mallikirjasto for( ; alku!= loppu ; ) cout << *++alku << " "; Tässä silmukka tulostaisi arvot 4-7. Lausekkeen *++alku arvo on jäsenmuuttujan alku.x arvo lisäyksen jälkeen. Iteraattoreiden välitys algoritmille Eli mitä hyötyä Kokonaisluku-luokastamme on? Mitä sellaista Kokonaisluku voi tehdä, mihin vanha kunnon int ei pysty? Katsotaanpa. Kokeile itse - Kokonaisluku-olion välityskeskiarvo<>:lle // Esimerkki 20.8 Kokonaisluku-olion keskiarvojen laskenta #include <iostream> using namespace std; class Kokonaisluku public: Kokonaisluku (int par = 0) : X(par) bool operator!=(const Kokonaisluku& par) const return X!= par.x; //!= -vertailu int operator*() const return X; Kokonaisluku& operator++() ++X; return *this; //Osoitusoperaattori // Etuliitteellinen lisäysoperaattori const Kokonaisluku operator++(int) // Jälkiliitteellinen ++-operaattori Kokonaisluku temp(*this); // Talletetaan nykyinen arvo ++X; // Vaihdetaan uuteen arvoon return temp; // Palautetaan muuttumaton talletettu arvo private: int X; ; template <typename Iter> double keskiarvo(iter a, Iter loppu) double summa = 0.0; // Tähän lasketaan summa int lkm = 0 ; for( ; a!= loppu ; lkm++) summa += *a++; // Summataan taulukon alkiot 845
24 C++ Ohjelmoijan käsikirja return summa / lkm; // Palautetaan keskiarvo int main() Kokonaisluku ensim(1); Kokonaisluku viim(11); cout << "Kokonaislukujen keskiarvo väliltä " << *ensim << " - " << -1+*viim; cout << " on " << keskiarvo(ensim, viim) << endl; return 0; Ohjelman tulostus on seuraava: Kokonaislukujen keskiarvo väliltä 1-10 on 5.5 Kuinka se toimii Emme tehneet kovinkaan suuria muutoksia. Lisäsimme operator++()-operaattorin jälkiliitteellisen muodon: const Kokonaisluku operator++(int) // Jälkiliitteellinen ++-operaattori Kokonaisluku temp(*this); // Talletetaan nykyinen arvo ++X; // Vaihdetaan uuteen arvoon return temp; // Palautetaan muuttumaton talletettu arvo Tiedämme jo entuudestaan, että toteuttaaksemme jälkiliitteellisen lisäysoperaattorin, meidän täytyy luoda kopio nykyisestä oliosta - tätä meidän ei tarvitse tehdä etuliitteellisessä muodossa. Tämä luo tietysti lisätyötä, koska tällöin kutsutaan kopiomuodostinta. Tästä syystä suurin osa seuraavista esimerkeistä käyttää etuliitteellistä muotoa aina, kun se vain on mahdollista, koska se on tehokkaampaa. Yksinkertaisen Kokonaisluku-luokkamme kohdalla tällä ei ole juuri mitään merkitystä, mutta kun teemme mallialgoritmeja, emme voi olla varmoja, miten paljon suoritusaikaa olion kopioiminen vie, kun käytämme lauseketta Iter++. Käytämme Kokonaisluku-luokkaamme seuraavissa lauseissa: Kokonaisluku ensim(1); Kokonaisluku viim(11); cout << "Kokonaislukujen keskiarvo väliltä " << *ensim << " - " << -1+*viim; cout << " on " << keskiarvo(ensim, viim) << endl; Jälleen kerran, viim on lopun yli -arvo. Meidän tulee vähentää siitä 1, jotta saamme sallitun arvon. Lisäksi, jos ensim olisi pelkkä int iteraattorin sijaan, meidän ei tarvitsisi käyttää lauseketta *ensim, jotta saamme sen arvon selville. 846 Jos oikein pysähdyt ajattelemaan, olemme tehneet jotain hyvin erilaista kutsuessamme keskiarvo()-funktiota uudella Kokonaisluku-iteraattorillamme. Kaikissa aikaisemmissa esimerkeissä keskiarvoon lasketut arvot olivat jossain - taulukoissa, vector-säiliöissä tai virroissa. Tässä esimerkissä arvoja ei ole olemassa missään. Ne lasketaan Kokonaisluku-luokan sisällä, kun keskiarvo()-algoritmi kutsuu kolmikkoa operator!=(), operator*() ja operator++().
Osoitin ja viittaus C++:ssa
Osoitin ja viittaus C++:ssa Osoitin yksinkertaiseen tietotyyppiin Osoitin on muuttuja, joka sisältää jonkin toisen samantyyppisen muuttujan osoitteen. Ohessa on esimerkkiohjelma, jossa määritellään kokonaislukumuuttuja
Lisätiedot815338A 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ätiedotDemo 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ätiedotOperaattoreiden 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ätiedot12 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ätiedotOhjelmointi 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ätiedotOlio-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ätiedotC++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ätiedot815338A 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ätiedotOperaattoreiden uudelleenmäärittely
Operaattoreiden uudelleenmäärittely 14 Operaattoreiden uudelleenmäärittely Tässä luvussa käsittelemme, kuinka voit lisätä toiminnallisuutta luokkiisi, jotta ne toimivat enemmän C++:n perustietotyyppien
LisätiedotOsoittimet. Mikä on osoitin?
Osoittimet 7 Osoittimet On aika siirtyä käsittelemään osoittimia, C++:lle elintärkeätä ominaisuutta. Osoittimet ovat tärkeitä, koska ne luovat perustan muistin dynaamiselle varaukselle ja käytölle. Ne
LisätiedotSTL: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ätiedotMallit standardi mallikirjasto parametroitu tyyppi
Mallit 18 Mallit Malli on tehokas mekanismi uusien luokkien generoimiseksi automaattisesti. Standardikirjaston suuri osa, standardi mallikirjasto, rakentuu kokonaan mallien määrittelymahdollisuuden ympärille,
LisätiedotC-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ätiedotKää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ätiedotITKP102 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ätiedotOhjelmassa 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ätiedotOhjelman virheet ja poikkeusten käsittely
Ohjelman virheet ja poikkeusten käsittely 17 Ohjelman virheet ja poikkeusten käsittely Poikkeukset ovat tapa ilmoittaa virheistä ja odottamattomista tilanteista C++-ohjelmassasi. Poikkeusten käyttö virheiden
Lisätiedot13 Operaattoreiden ylimäärittelyjä
248 13 C++-kielessä voidaan operaattoreita ylimäärittää. Ylimääriteltävää operaattoria voidaan pitää ikäänkuin metodina, joka esitellään luokan esittelyssä ja määritellään luokan ulkopuolella kuten metoditkin.
LisätiedotVirtuaalifunktiot ja polymorfismi
Virtuaalifunktiot ja polymorfismi 16 Virtuaalifunktiot ja polymorfismi Polymorfismi on niin tehokas olio-ohjelmoinnin ominaisuus, että tulet varmastikin käyttämään sitä lähes kaikissa C++-ohjelmissasi.
LisätiedotC++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ätiedotOhjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:
1 (7) Tiedon lukeminen näppäimistöltä Scanner-luokan avulla Miten ohjelma saa käyttöönsä käyttäjän kirjoittamaa tekstiä? Järjestelmässä on olemassa ns. syöttöpuskuri näppäimistöä varten. Syöttöpuskuri
LisätiedotTietueet. 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ätiedotOhjelmoinnin 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ätiedotKääntäjän virheilmoituksia
OHJ-1101 Ohjelmointi 1e 2008-09 1 Kääntäjän virheilmoituksia Kun progvh2 ohjelma käännetään antaa tutg++ seuraavat virheilmoitukset ja varoitukset: proffa> tutg++ progvh2.cc progvh2.cc:29:13: warning:
LisätiedotTaulukot. 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ätiedotOhjelmoinnin 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ätiedotJava-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ätiedotLuokan operaatiot. Osoittimet ja viittaukset luokan olioihin
Luokan operaatiot 13 Luokan operaatiot Luokkien olioiden luomiseen ja tuhoamiseen liittyy monia hienouksia, joista sinun tulee olla selvillä, jotta luokkiesi olioiden operaatiot toimivat turvallisesti
Lisätiedot812347A 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ätiedotITKP102 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ätiedotOlion 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ätiedotLyhyt 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ätiedotChapel. 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ätiedot7. 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ätiedotPeriytyminen. Luokat ja olio-ohjelmointi
Periytyminen 15 Periytyminen Tässä luvussa käsittelemme aihetta, joka on olio-ohjelmoinnin kaikkein tärkein osa - periytyvyys. Periytyvyyden avulla voimme luoda uusia luokkia uudelleenkäyttämällä ja laajentamalla
LisätiedotOlio-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ätiedotLuokassa 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ätiedot2. 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ätiedotITKP102 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ätiedotAlkuarvot 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ätiedotC++ 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ätiedotTIETORAKENTEET 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ätiedotSisällys. 3. Muuttujat ja operaatiot. Muuttujat ja operaatiot. Muuttujat. Operaatiot. Imperatiivinen laskenta. Muuttujat. Esimerkkejä: Operaattorit.
3. Muuttujat ja operaatiot Sisällys Imperatiivinen laskenta. Muuttujat. Nimi ja arvo. Muuttujan nimeäminen. Muuttujan tyyppi.. Operandit. Arvon sijoitus muuttujaan. Aritmeettiset operaattorit. Arvojen
LisätiedotOhjelmoinnin 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ätiedotSisä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ätiedotTaulukot. 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ätiedotEsimerkkiprojekti. 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ätiedot3. Muuttujat ja operaatiot 3.1
3. Muuttujat ja operaatiot 3.1 Sisällys Imperatiivinen laskenta. Muuttujat. Nimi ja arvo. Muuttujan nimeäminen. Muuttujan tyyppi. Operaattorit. Operandit. Arvon sijoitus muuttujaan. Aritmeettiset operaattorit.
LisätiedotMuuttujien 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ätiedotINSIDE C++ Ohjelmoijan käsikirja. Ivor Horton WROX PRESS
INSIDE C++ Ohjelmoijan käsikirja Ivor Horton WROX PRESS C++ Ohjelmoijan käsikirja Kirjoittanut Kääntäjä Kansi Kustantaja Ivor Horton Jouni Laaksonen Frank Chaumont IT Press PL 25 00511 HELSINKI Sähköpostiosoite
LisätiedotITKP102 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ätiedot812347A Olio-ohjelmointi, 2015 syksy 2. vsk. V Geneerisyys
812347A Olio-ohjelmointi, 2015 syksy 2. vsk V Geneerisyys Sisältö 1. Johdanto geneerisyyteen 2. Geneeriset funktiot 3. Geneeriset luokat 4. Standard Template Library (STL) 5. IOStream-kirjasto 812347A
LisätiedotOhjelmoinnin 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ätiedotA274101 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ätiedotMerkkijono 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ätiedotOhjelmoinnin 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ätiedotOhjelmoinnin 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ätiedotJavan perusteita. Janne Käki
Javan perusteita Janne Käki 20.9.2006 Muutama perusasia Tietokone tekee juuri (ja vain) sen, mitä käsketään. Tietokone ymmärtää vain syntaksia (sanojen kirjoitusasua), ei semantiikkaa (sanojen merkitystä).
LisätiedotOhjelmointitaito (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ätiedotJava-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ätiedotSisä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ätiedotInformaatioteknologian 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ätiedotListarakenne (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ätiedot815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset
815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 4 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten lauseisiin, lausekkeisiin ja aliohjelmiin liittyvät kysymykset. Tehtävä 1. Mitä
LisätiedotOhjelmoinnin 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ätiedotMetodit. 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ätiedotOhjelmoinnin jatkokurssi, kurssikoe 28.4.2014
Ohjelmoinnin jatkokurssi, kurssikoe 28.4.2014 Kirjoita jokaiseen palauttamaasi konseptiin kurssin nimi, kokeen päivämäärä, oma nimi ja opiskelijanumero. Vastaa kaikkiin tehtäviin omille konsepteilleen.
Lisätiedot1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa:
Tietorakenteet, laskuharjoitus 10, ratkaisuja 1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa: SamaLuku(T ) 2 for i = 1 to T.length 1 3 if T [i] == T [i + 1] 4 return True 5 return
LisätiedotSisä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ätiedotOmat tietotyypit. Mikä on olio?
Omat tietotyypit 11 Omat tietotyypit C++:n suuri vahvuus on sen oliopohjaisuudessa. Siihen liittyy runsaasti asiaa ja kulutammekin seuraavat viisi lukua tässä aiheessa. Tässä ja seuraavassa luvussa käsittelemme
LisätiedotRakenteiset 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ätiedotYleistä. 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ätiedotKirjoita 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ätiedot7. Näytölle tulostaminen 7.1
7. Näytölle tulostaminen 7.1 Sisällys System.out.println- ja System.out.print-operaatiot. Tulostus erikoismerkeillä. Edistyneempää tulosteiden muotoilua. 7.2 Tulostusoperaatiot System.out.println-operaatio
Lisätiedot18. 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ätiedotPong-peli, vaihe Aliohjelman tekeminen. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana
Muilla kielillä: English Suomi Pong-peli, vaihe 3 Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana Jaetaan ohjelma pienempiin palasiin (aliohjelmiin) Lisätään peliin maila (jota ei voi vielä
LisätiedotOlio-ohjelmointi Geneerisyys. 1. Johdanto
Olio-ohjelmointi Geneerisyys Aiemmin käsiteltiin kolme monimuotoisuuden muotoa. Tässä osassa tutustutaan niistä neljänteen geneerisyyteen. Esitys perustuu pääosin teoksen [Bud] lukuun 18. Java-kielen geneerisyyden
LisätiedotAlgoritmit 2. Luento 7 Ti Timo Männikkö
Algoritmit 2 Luento 7 Ti 4.4.2017 Timo Männikkö Luento 7 Joukot Joukko-operaatioita Joukkojen esitystapoja Alkiovieraat osajoukot Toteutus puurakenteena Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 2/26
LisätiedotOpintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen
Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Taulukot & Periytyminen Taulukot: Array Taulukko Javassa pitää aina perustaa (new) Yksinkertaisessa tilanteessa taulukon koko tiedetään etukäteen ja
Lisätiedotetunimi, sukunimi ja opiskelijanumero ja näillä
Sisällys 1. Algoritmi Algoritmin määritelmä. Aiheen pariin johdatteleva esimerkki. ja operaatiot (sijoitus, aritmetiikka ja vertailu). Algoritmista ohjelmaksi. 1.1 1.2 Algoritmin määritelmä Ohjelmointi
LisätiedotOsa. Listaus 2.1. HELLO.CPP esittelee C++ -ohjelman osat. 14: #include <iostream.h> 15: 16: int main() 17: {
Osa I 2. oppitunti C++-ohjelman osat Ennen kuin menemme yksityiskohtaisemmin sisälle C++-luokkiin, -muuttujiin jne, katsokaamme ensin, millaisista osista C++-ohjelma koostuu. Tämän tunnin aikana opit seuraavat
LisätiedotHarjoitus 7. 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:
Harjoitus 7 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti: class Lintu //Kentät private int _siivenpituus; protected double _aivojenkoko; private bool _osaakolentaa; //Ominaisuudet public int
LisätiedotOhjelmoinnin 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ätiedotOlio-ohjelmointi Javalla
1 Olio-ohjelmointi Javalla Olio-ohjelmointi Luokka Attribuutit Konstruktori Olion luominen Metodit Olion kopiointi Staattinen attribuutti ja metodi Yksinkertainen ohjelmaluokka Ohjelmaluokka 1 Olio-ohjelmointi
LisätiedotT740103 Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010
12. Periytyminen Johdantoa Käytännössä vähänkään laajemmissa ohjelmissa joudutaan laatimaan useita luokkia, joiden pitäisi pystyä välittämään tietoa toisilleen. Ohjelmien ylläpidon kannalta olisi lisäksi
LisätiedotTietorakenteet ja algoritmit
Tietorakenteet ja algoritmit Pino Pinon määritelmä Pinon sovelluksia Järjestyksen kääntäminen Palindromiprobleema Postfix-lausekkeen laskenta Infix-lausekkeen muunto postfix-lausekkeeksi Sisäkkäiset funktiokutsut
LisätiedotHarjoitustyö: virtuaalikone
Harjoitustyö: virtuaalikone Toteuta alla kuvattu virtuaalikone yksinkertaiselle olio-orientoituneelle skriptauskielelle. Paketissa on testaamista varten mukana kaksi lyhyttä ohjelmaa. Ohjeita Noudata ohjelman
Lisätiedot1 C++:n standardikirjasto
TIE-20100 Tietorakenteet ja algoritmit 1 1 C++:n standardikirjasto Tässä luvussa käsitellään C++:n standardikirjaston tietorakenteita ja algoritmeja. Tarkoituksena on käsitellä sellaisia asioita, jotka
LisätiedotTietorakenteet ja algoritmit
Tietorakenteet ja algoritmit Rekursio Rekursion käyttötapauksia Rekursio määritelmissä Rekursio ongelmanratkaisussa ja ohjelmointitekniikkana Esimerkkejä taulukolla Esimerkkejä linkatulla listalla Hanoin
LisätiedotT Olio-ohjelmointi Osa 3: Luokka, muodostin ja hajotin, this-osoitin Jukka Jauhiainen OAMK Tekniikan yksikkö 2010
11. Luokka Opetellaan seuraavaksi, miten omia luokkia kirjoitetaan. Aikaisemmin olikin jo esillä, että luokka on tietorakenne, joka sisältää sekä tiedot (attribuutit) että niitä käsittelevät aliohjelmat
LisätiedotLuokat. Luokat ja olio-ohjelmointi
Luokat 12 Luokat Tässä luvussa laajennamme edellisessä luvussa käsittelemäämme struktuurityyppiä ja siirrymme yhteen C++-ohjelmoijan kaikkein tärkeimmistä välineistä: luokkiin. Käsittelemme myöskin joitakin
LisätiedotTehtävä 1. TL5302 Olio-ohjelmointi Koe Malliratkaisuja. Tässä sekä a)- että b)-kohdan toimiva ratkaisu:
TL5302 Olio-ohjelmointi Koe 19.4.2005 Malliratkaisuja Tehtävä 1 Tässä sekä a)- että b)-kohdan toimiva ratkaisu: #include using namespace std; int main() int taul[5]=1,2,3,4,5; int *p,&r=taul[0];
LisätiedotPerusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti
C! Perusteet 19.1.2017 Palautteesta (1. kierros toistaiseksi) Toistaiseksi helppoa Miksi vain puolet pisteistä? Vaikeinta oli ohjelmointiympäristön asennus ja käyttö Vaikeaa eroavuudet Pythonin ja C:n
LisätiedotSisä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ätiedot11. oppitunti III. Viittaukset. Osa. Mikä on viittaus?
Osa III 11. oppitunti Viittaukset Kahdessa viime luvussa opit käyttämään osoittimia kohteiden käsittelyyn vapaalla muistialueella sekä viittaamaan noihin kohteisiin epäsuorasti. Tässä luvussa käsiteltävät
LisätiedotJAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?
JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS Teemu Saarelainen teemu.saarelainen@kyamk.fi Lähteet: http://java.sun.com/docs/books/tutorial/index.html Vesterholm, Kyppö: Java-ohjelmointi,
LisätiedotKoottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.
2. Ohjausrakenteet Ohjausrakenteiden avulla ohjataan ohjelman suoritusta. peräkkäisyys valinta toisto Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet
LisätiedotITKP102 Ohjelmointi 1 (6 op), arvosteluraportti
ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti Tentaattori: Antti-Jussi Lakanen 8. kesäkuuta 2018 Yleistä Tentti 1 meni pistekeskiarvon (11.2) perusteella välttävästi. Omasta tehtäväpaperista saa kopion
Lisätiedot1. Algoritmi 1.1 Sisällys Algoritmin määritelmä. Aiheen pariin johdatteleva esimerkki. Muuttujat ja operaatiot (sijoitus, aritmetiikka ja vertailu). Algoritmista ohjelmaksi. 1.2 Algoritmin määritelmä Ohjelmointi
Lisätiedot