Olio-ohjelmointi Geneerisyys. 1. Johdanto
|
|
- Petri Aaltonen
- 9 vuotta sitten
- Katselukertoja:
Transkriptio
1 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 perusteisiin voi tutustua esimerkiksi teoksen [Ves] luvusta 9.8. C++-kielen geneerisen ohjelmoinnin tukimekanismeja käsitellään kirjan [Stro] luvussa 13, teoksen [Eck] luvussa 16 ja kirjan [Hie] luvussa Johdanto Ohjelman toimintojen toteutus on varsin usein olennaisilta osiltaan riippumaton siinä käytettävistä tietotyypeistä. Tämä ilmenee selvästi rakennettaessa erilaisia säiliöitä tai muita tietorakenteita. Esimerkiksi lineaarinen lista toimii täsmälleen samoin riippumatta siitä, ovatko sen alkiot kokonaislukuja, desimaalilukuja tai merkkijonoja. Geneerisen ohjelmoinnin avulla voidaan välttää kirjoittamasta eri toteutusta jokaiselle tietotyypille. Geneerisyys tarkoittaa monimuotoisuutta, jossa tietotyyppien nimet ovat monimuotoisia. Staattisesti tyypitetyissä kielissä tämä tarkoittaa käytännössä tietotyyppien parametrisoimista siten, että kutakin ohjelmassa esiintyvää konkreettista tyyppiä kohden kääntäjä tekee oman toteutuksen. Geneerisyys on näin ollen monimuotoisuuden käännösaikainen muoto, joka tukee erityisesti koodin uudelleenkäyttöä. Geneeristä ohjelmointia sovelletaan yleisimmin tyyppiriippumattomien säiliöiden ja algoritmien toteuttamiseen. Stroustrupin ([Stro], s. 40) mukaan geneerisen ohjelmoinnin paradigma voidaan kiteyttää lauseeseen: Decide which algorithms you want: parameterize them so that they work for a variety of suitable types and data structures. C++-kielen standardissa C++11 on tehty hieman laajennuksia kielen geneerisyyteen, mutta tässä käsitellään asiaa array-kokoelmaa lukuunottamatta aiemman standardin mukaisesti. 2. Geneeriset funktiot C++-kielessä geneerisyyttä tuetaan ns. template-mekanismin avulla. Tarkastellaan ensin, miten kielessä toteutetaan vapaa geneerinen funktio. Oletetaan, että halutaan tehdä funktio, joka palauttaa kahdesta parametristaan pienemmän. Tämä voidaan toteuttaa seuraavasti: template <typename Type> Type pienempi(type t, Type u) { if(t < u){ return t; return u; Edellä Type on eräänlainen parametri, mutta ei tavallinen funktion parametri, vaan tyyppiparametri, johon kääntäjä sovittaa funktiokutsussa käytettävien parametrien tyypin. Tällaista funktiota kutsutaan geneeriseksi funktioksi tai aliohjelmamalliksi ([Hie], luku 31). Kääntäjä tekee kaikkia erilaisia tyyppejä kohti oman version, mikäli tietotyyppi vain toteuttaa vertailuoperaattorin <. Funktiota voidaan siten kutsua ohjelmassa esimerkiksi seuraavasti: 1
2 int x=10, y=5; double d1 = 5.2, d2 = 8.2; string s1 = "alku"; string s2 = "loppu"; cout << pienempi(x,y) << endl; cout << pienempi<double>(d1,d2) << endl; cout << pienempi(s1,s2) << endl; Jos kääntäjä voi päätellä tietotyypin funktion kutsusta, ohjelmoijan ei tarvitse määritellä sitä välttämättä eksplisiittisesti. Edellä ainoastaan toisessa funktiokutsussa on parametrityyppi annettu. Näissä tapauksissa vertailuoperaattori on toteutettu, joten kääntäminen sujuu ongelmitta. Sen sijaan, jos ohjelmassa olisi määritelty luokka class Vertaamaton { ; joka ei toteuta vertailuoperaattoria, koodi pienempi(v1,v2); ei käänny mikäli muuttujat v1 ja v2 ovat ko. luokan olioita. Geneerisiä funktioita voidaan kyllä soveltaa myös käyttäjän määrittelemiin tyyppeihin, kunhan vain funktiossa tehdään ainoastaan tietotyypin sallimia operaatioita. Jos edelliseen luokkaan määriteltäisiin vertailuoperaattori seuraavasti class Vertaamaton { public: bool operator<(const Vertaamaton &v); ; bool Vertaamaton::operator<(const Vertaamaton &v){ // Palauta vertailun tulos niin funktiota voitaisiin soveltaa myös tähän luokkaan. Java-kielessä geneerisyys on liitetty kielen ominaisuuksiin versiosta 1.5 (eli JDK 5.0:sta) lähtien. Javassa ei vapaita funktioita ole, mutta edellistä esimerkkiä vastaava geneerinen metodi voitaisiin Javassa toteuttaa seuraavasti: public static <T extends Comparable> T pienempi (T x, T y){ if(x.compareto(y)<0) return x; return y; Huomaa, että Javassa on kulmasuluissa esiteltävän tyyppiparametrin jälkeen määriteltävä, että tyyppi perii luokan Comparable, jotta vertailun varsinaisesti suorittava metodi compareto() olisi käytettävissä. 2
3 3. Geneeriset luokat Varsinkin C++:ssa käytetään melko paljon geneerisiä funktioita, mutta vielä paljon yleisempää on parametrisoida luokka, jolloin luokkaa sanotaan geneeriseksi luokaksi tai luokkamalliksi ([Hie], luku 31). Erityisesti erilaisia tietorakenteita toteutettaessa on hyödyllistä tehdä luokista geneerisiä. Tutustaan C++:n geneerisiin luokkiin. Pino on tietorakenne, joka noudattaa LIFO-periaatetta ( Last In First Out ), ts. viimeksi pinoon tallennettu tietoalkio otetaan ensimmäiseksi pois. Oletetaan, että halutaan kirjoittaa pino, jonka eri toteutukset voivat säilöä minkä tahansa tyyppistä tietoa. Luokan rajapinta on // Lueteltu typpi: ei liity erityisesti geneerisyyteen enum PinoPoikkeus { PinoTyhja, PinoTaysi ; template<typename Type> class Pino { private: int koko; int paa; Type* pino; public: Pino(int k):koko(k),paa(0) { pino = new Type[koko]; ~Pino(){delete[] pino; void push(type); Type pop(); bool empty(); ; Tyyppiparametri annetaan luokan määrittelyn alussa ja sitä voi käyttää missä tahansa luokan sisällä. Kun luokasta tehdäänkin luokkamalli, sen metodeista tulee myös automaattisesti geneerisiä funktioita, minkä pitää myös näkyä toteutuksessa: // Malliluokan jäsenfunktioiden määrittelyt: template <typename Type> void Pino<Type>::push(Type elem){ if (paa == koko) throw PinoTaysi; // Ylivuoto pino[paa++] = elem; template <typename Type> Type Pino<Type>::pop(){ if (paa == 0) throw PinoTyhja; // Alivuoto return pino[--paa]; template <typename Type> bool Pino<Type>::empty(){ return (paa==0); 3
4 Huomaa, että tyyppiparametria voidaan käyttää luokassa kuten mitä tahansa tietotyyppiä: se voi olla luokan jäsenmuuttujien tyyppinä, voidaan määritellä ko. tyyppiä sisältäviä taulukoita, voidaan käyttää tyyppiä metodien parametrien ja paluuarvon tyyppinä. Ylläolevassa koodissa yli- ja alivuototilanteissa heitetään poikkeus; poikkeuksiin tutustutaan lyhyesti ihan kurssin lopussa. Jos luokkaa aiotaan käyttää ohjelmassa useammassa kooditiedostossa, on koko luokan koodi sijoitettava normaalista poiketen otsikkotiedostoon, koska kääntäjä tekee jokaiselle tyyppiparametrille oman toteutuksen luokasta. Luokkaa voitaisiin käyttää ohjelmassa esimerkiksi näin: // Pino jossa double-lukuja Pino<double> dpino(3); dpino.push(1.2); dpino.push(-1.3); cout << dpino.pop() << endl; cout << dpino.pop() << endl <<endl; // Pino jossa string-olioita Pino<std::string> spino(3); spino.push("eka"); spino.push("toka"); cout << spino.pop() << endl; cout << spino.pop() << endl << endl; Pino-oliota luotaessa on annettava tyyppi, jota käytetään parametrina. Muuten kääntäjä ei tiedä, minkälainen Pino on luotava. Alityyppijärjestelmä toimii luokkamalleille hieman eri tavalla kuin intuitiivisesti voisi olettaa. Vaikka yhden luokan tyyppiparametri on toisen luokan tyyppiparametrin alityyppi, ei luokkamallien välillä ole alityyppisuhdetta. Oletetaan että edellisessä pino-esimerkissä olisi määritelty luokat class Luokka { // Luokan koodia ; class Aliluokka : public Luokka { // Luokan koodia ; Nyt siis Aliluokka on Luokka-luokan alityyppi. Kuitenkaan Pino<Aliluokka> ei ole luokan Pino<Luokka> alityyppi, joten ohjelmassa ei ole sallittua tehdä sijoitusta Pino<Luokka> pino(2); Pino<Aliluokka> toinenpino(3); pino = toinenpino; Voidaan nimittäin osoittaa, että operaation salliminen johtaisi ongelmiin. Tässä ei kuitenkaan paneuduta asiaan syvemmin. Mainittakoon, että C++:aan liittyy olennaisena osana STL-kirjasto (Standard Template Library), joka on yleiskäyttöinen geneeristen algoritmien ja tietorakenteiden kokoelma. C++-ohjelmoijan on välttämätöntä tuntea ainakin jossain määrin kirjaston käyttöä. STL:n ominaisuuksia tarkastellaan hieman lisää tuonnempana. 4
5 Esitetään lopuksi vertailun vuoksi esimerkki geneerisen luokan toteuttamisesta Javalla. Aiempi geneerinen pinoluokka voitaisiin kirjoittaa Javalla seuraavasti: // Malliluokan määrittely: class Pino<T> { private int koko; private int paa; private T[] pino; public Pino(int k){ koko = k; paa = 0; pino = (T[])new Object[koko]; public void push(t elem){ if (paa == koko){ throw new PinoPoikkeus("Pino täysi"); pino[paa++] = elem; public T pop(){ if (paa == 0){ throw new PinoPoikkeus("Pino tyhjä"); return pino[--paa]; public boolean empty(){ return (paa==0); public boolean full(){ return (paa==koko); Javan kaikki luokat periytyvät viime kädessä Object-luokasta, jonka alityyppejä kaikki luokat ovat Javan periytymismallista johtuen. Näin ollen pinoon voi laittaa minkä tahansa luokan olioita, esimerkiksi Javan merkkijonoluokan String olioita seuraavasti: // Pino jossa string-olioita Pino<String> spino = new Pino<String>(3); spino.push("eka"); spino.push("toka"); System.out.println(sPino.pop()); System.out.println(sPino.pop()); 5
6 Perustietotyyppien muuttujat eivät sen sijaan ole Javassa olioita, joten perustietotyyppien tallentamisessa on käytettävä niiden kääreluokkia, esimerkiksi näin: // Pino jossa Double-olioita Pino<Double> dpino = new Pino<Double>(3); dpino.push(new Double(1.2)); dpino.push(new Double(-1.3)); System.out.println(dPino.pop().doubleValue()); System.out.println(dPino.pop().doubleValue()); Koodista havaitaan merkittävä ero Javan ja C++:n mallien välillä: C++ sallii ongelmitta parametrityyppisen taulukon luomisen, mutta Java antaa käännösvirheen, mikäli yrittää pinon konstruktorissa luoda taulukkoa seuraavasti: pino = new T [koko]; Javassa suositellaan tyyppiparametreina käytettävän yksikirjaimisia isoin kirjaimin kirjoitettuja nimiä. Kun ohjelmaa käännetään, kääntäjä korvaa kaikki muodolliset tyyppiparametrit todellisilla tyyppiparametreilla. Kääntäjä suorittaa ohjelmoijan puolesta tarvittavat tyyppimuunnokset ja -tarkastukset. Java onkin tässä suhteessa huomattavasti C++:aa tarkempi. Toisin kuin C++:ssa, Javassa voi asettaa rajoituksia tyyppiparametrille. Jos haluttaisiin esimerkiksi rajoittaa edellä käsitellyn pinoluokan alkiot numeerisiin tyyppeihin, muutettaisiin vain tyyppiparametrin esittely muotoon class Pino<T extends Number> Lisäksi muutetaan taulukon varaus muodostimessa: pino = (T[])new Number[koko]; Tällöin pinon tyyppiparametriksi ei voi antaa kuin Number-luokasta periytyviä luokkia. Nyt voitaisiin toteuttaa esimerkiksi pinon alkioiden summan laskeminen luokan metodiksi public double sum() { double d = 0.0; for(int i=0; i<paa; i++) { d += (pino[i]).doublevalue(); return d; mikä toimii, koska kaikki Number-luokasta periytyvät luokat toteuttavat metodin doublevalue(), joka palauttaa olion numeerisen arvon reaalilukuna. Javan tyyppiparametreissa voidaan lisäksi käyttää ns. jokereita (wild cards), jotka merkitään kysymysmerkillä. Jokeria tarvitaan erityisesti välitettäessä geneerisiä olioita parametriksi metodeille. Sanokaamme, että halutaan tehdä metodi, jota voi soveltaa mihin tahansa pinoon. Silloin metodin parametriksi tarvitaan parametrityypiltään tuntematon Pino. Tämä saadaan aikaan jokerilla: static void printandclear(pino<?> stack) { while(!stack.empty()) { System.out.println(stack.pop()); Tälle metodille voidaan antaa parametriksi mikä tahansa pino, jonka alkiot metodi tulostaa tyhjentäen samalla pinon. 6
7 4. Standard Template Library Kuten aiemmin mainittiin, C++:n toteutukseen sisältyy melko laaja joukko geneerisiä tietorakenteita, kokoelmia, ja niitä käsitteleviä algoritmeja. Tätä kokoelmaa kutsutaan nimellä Standard Template Library (STL). Tarkastellaan hieman tämän standardikirjaston perusominaisuuksia. Kirjaston pääkomponentteja ovat kokoelmat (tai tietosäiliöt), selaajat (eli iteraattorit) ja algoritmit. Selaajia käytetään kokoelmien läpikäymiseen ja algoritmeja kokoelmien käsittelemiseen, esimerkiksi lajitteluun, tiedon etsimiseen jne. Lisäksi STL sisältää funktio-olioita (funktioiden tapaan käyttäytyviä olioita) ja sovittimia (jotka vaihtavat komponenttien liittymiä) operoinnin helpottamiseksi. Kokoelmat Kokoelmat ovat siis standardikirjastoon integroituja geneerisiä tietorakenteita, joihin voidaan tallentaa millaisia tietoalkioita tahansa. Standardikirjasto sisältää luokkamalleja kokoelmia varten. Nämä kokoelmat voidaan karkeasti jakaa peräkkäisrakenteisiin kokoelmiin (deque, list, forward_list [c++11], vector, array [c++11]) ja avainrakenteisin kokoelmiin (set, unordered_set [c++11], multiset, unordered_multiset [c++11] map, unordered_map [c++11], multimap, unordered_multimap [c++11]). C++11-standardiin on lisätty kokoelmia, jotka on edellä merkitty luetteloon maininnalla [c++11]. Tässä tutustutaan esimerkinomaisesti vector-kokoelmaan, jonka avulla voidaan toteuttaa vaihtuvamittaisia taulukoita. Lisäksi perehdytään C++11-standardin array-kokoelmaan, joka kapseloi sisäänsä kiinteämittaisen taulukon. Vector on dynaamisesti kasvava taulukko, johon voidaan tallentaa minkä tahansa yhden tietotyypin tietoa, myös käyttäjän määrittelemien luokkien olioita. Perehdytään vector-luokan ominaisuuksiin tarkastelemalla seuraavaa ohjelmaa, joka tallentaa käyttäjän syöttämät reaaliluvut vector-kokoelmaan ja laskee niiden keskiarvon käymällä kokoelman läpi. Samalla luvut myös tulostetaan. 7
8 #include <iostream> #include <vector> using namespace std; int main(int argc, char** argv) { // Reaalilukuvektori vector<double> numbers; double input; cout << "Syötä reaalilukuja, nolla lopettaa" << endl; do { cin >> input; if( input!= 0 && cin.good()) { numbers.push_back(input); while(input!=0 && cin.good()); double sum = 0.0; if(!numbers.empty()) { cout << "Lukujen " << endl; for(int i=0; i < numbers.size(); i++){ cout << numbers[i] << " "; sum += numbers[i]; double average = sum/numbers.size(); cout << endl << "keskiarvo on " << average << endl; return 0; Rivi vector<double> numbers; määrittelee double-lukuja tallentavan vectorin. Tämän jälkeen ohjelma lukee silmukassa käyttäjältä lukuja nollasyötteeseen saakka. Luetut luvut lisätään vectoriin kutsumalla luokan metodia push_back: numbers.push_back(input); Metodin kutsu lisää uuden luvun vectorin viimeiseksi alkioksi samalla kasvattaen siitä tarvittaessa. Vectorin alkioihin voidaan viitata kuten taulukon alkioihin, mutta vectorin etu taulukkoon verrattuna on esimerkiksi, että vectorin sisältämien alkioiden lukumäärä saadaan selville kutsumalla luokan size-metodia: numbers.size(); 8
9 Lisäksi metodi numbers.empty() kertoo, onko vectorissa lainkaan alkioita. Mainittakoon vielä, että vectorista voidaan poistaa alkio metodin erase avulla. Tähän tarvitaan kuitenkin ns. selaajaa, johon tutustutaan seuraavaksi. Selaajat Selaajat eli iteraattorit ovat älykkäitä osoittimia eli osoitinolioita, joita STL:n -algoritmit käyttävät kokoelmien alkioiden käsittelyssä. Myös ohjelmoija voi niiden avulla lukea kokoelman alkioita, kirjoittaa alkioita kokoelmaan, kulkea kokoelmassa eteen- ja taaksepäin tai siirtyä suoraan tietyn alkion kohdalle. Selaajia voidaan käyttää indeksien asemesta niissäkin tapauksissa, joissa kokoelma sallii indeksien käytön. Seuraavaksi tutustutaan vector-kokoelman selaajia käyttävään esimerkkiohjelmaan. Edellisen esimerkkiohjelman osa if(!numbers.empty()) { cout << "Lukujen " << endl; for(int i=0; i < numbers.size(); i++){ cout << numbers[i] << " "; sum += numbers[i]; double average = sum/numbers.size(); cout << endl << "keskiarvo on " << average << endl; voitaisiin toteuttaa selaajan avulla seuraavasti: if(!numbers.empty()) { cout << "Lukujen " << endl; vector<double>::iterator iter; for(iter = numbers.begin(); iter!= numbers.end(); iter++){ cout << *iter << " "; sum += *iter; double average = sum/numbers.size(); cout << endl << "keskiarvo on " << average << endl; Nyt vector-kokoelmaa ei käydäkään läpi kuten taulukkoa, vaan ensin esitellään kokoelman selaaja vector<double>::iterator iter; Tässä määritellään double-tyyppisiä alkioita sisältävän vektorin selaaja. Koska ohjelmassa ei ole tarkoitus muuttaa vektorin alkioita, voitaisiin myös käyttää vakioselaajaa, jota ei voi käyttää alkioiden kirjoittamiseen. Näin ollen yllämainittu rivi voitaisiin myös kirjoittaa muotoon vector<double>::const_iterator iter; 9
10 Jokainen kokoelma määrittelee omat selaajansa, joiden avulla kokoelmia voi käyttää ohjelmassa samaan tyyliin. Seuraavassa for-silmukassa for(iter = numbers.begin(); iter!= numbers.end(); iter++){ cout << *iter << " "; sum += *iter; käydään läpi kaikki kokoelman alkiot; kokoelman jäsenfunktio begin palauttaa osoittimen kokoelman ensimmäiseen alkioon ja end palauttaa osoittimen, joka saadaan kun selaajaa siirretään eteenpäin kokoelman viimeisestä alkioista. Selaajaa siirretään eteenpäin operaattorilla ++. Huomaa, että selaaja on osoitin, joten kokoelman alkio saadaan viittaamalla selaajan osoittamaan muistiin käyttämällä operaattoria *. Kokoelmille määritellään algoritmeja alkioiden etsimiseen ja kokoelmien lajittelemiseen otsikkotiedostossa algorithm. Jos halutaan esimerkiksi poistaa kokoelmasta alkion 2.0 ensimmäinen esiintymä, se voidaan tehdä seuraavasti: vector<double>::iterator iter; iter = find(numbers.begin(), numbers.end(), 2.0); if(iter!= numbers.end()){ numbers.erase(iter); Ensin haetaan kokoelmasta mainittu alkio algoritmin find avulla. Parametriksi annetaan selaajilla väli jolta haetaan (yllä koko vector). Paluuarvona saadaan selaaja, joka osoittaa haluttuun arvoon. Mikäli haluttaisiin toteuttaa tulostaminen ja alkioiden summan lasku yleisesti funktioina, jotka käsittelevät minkä tahansa tyyppisiä vector-kokoelmia, voitaisiin laatia geneeriset funktiot: template <typename Type> void tulosta(vector<type> &vektori){ typename vector<type>::const_iterator iter; for(iter = vektori.begin(); iter!= vektori.end(); iter++){ cout << *iter << " "; template <typename Type> Type summa(vector<type> &vektori) { Type sum = 0; typename vector<type>::const_iterator iter; for(iter = vektori.begin(); iter!= vektori.end(); iter++){ sum += *iter; return sum; Nyt kokoelman alkiotyyppi on tyyppiparametrina, joka määräytyy kun ohjelmassa on funktion kutsu: tällöin kääntäjä kiinnittää parametrille Type jonkin tyyppiarvon. Yllä olevissa funktioissa kokoelman selaaja on määriteltävä käyttäen avainsanaa typename, jotta tunnistetaan sen olevan tyyppiparametrin avulla määritelty. Tällöin kokoelman tulostaminen ja summan laskeminen tapahtuisi seuraavasti: 10
11 cout << "Lukujen " << endl; tulosta(numbers); sum = summa(numbers); double average = sum/numbers.size(); cout << endl << "keskiarvo on " << average << endl; array C++11-standardissa on kokoelmien joukkoon lisätty array, joka kapseloi sisäänsä kiinteämittaisen taulukon. Kurssin alkuosasta muistetaan, että tavallinen taulukko ei tiedä omaa kokoansa, joten taulukon koko joudutaan välittämään funktiolle parametrina samalla kuin taulukkokin, mikäli halutaan välttyä taulukon rajojen ylitykseltä. Esimerkiksi funktiot taulukon tulostamiseksi ja lajittelemiseksi kirjoitettaisiin geneerisinä funktioina seuraavasti: // Tavallisen taulukon tulostus. // Huomaa, että // 1. taulukon koko on saatava parametrina // 2. Taulukko välitetään osoittimena ensimmäiseen alkioon // 3. Funktiossa ei voi muuttaa taulukon sisältöä template <typename Type> void tulostataulu(const Type *taulu, int koko) { for(int i = 0; i < koko; i++){ std::cout << "taulukko[" << i <<"] = " << taulu[i] << std::endl; // Tavallisen taulukon lajittelu. // Huomaa, että // 1. taulukon koko on saatava parametrina // 2. Taulukko välitetään osoittimena ensimmäiseen alkioon // 3. Funktiossa voidaan muuttaa taulukon sisältöä template <typename Type> void lajitteletaulu(type *taulu, int koko) { for(int i = 0; i < koko; i++){ for(int j = i+1; j < koko; j++){ if( taulu[i] > taulu[j] ){ Type temp = taulu[i]; taulu[i] = taulu[j]; taulu[j] = temp; Funktiot käsittelevät siis minkä tahansa tietotyypin taulukoita; taulukon koko joudutaan kuitenkin välittämään funktioille parametrina. Taulukon sijasta voidaan käyttää vectorkokoelmaa tämän tarpeen poistamiseksi, mutta tämä tapahtuu tehokkuuden kustannuksella, koska vector on vaihtuvamittainen kokoelma ja vaatii siksi mutkikkaampia operaatioita kuin kiinteämittainen taulukko. Tämän vuoksi C++-standardiin on lisätty array-kokoelma, joka yhdistää taulukon käsittelyn tehokkuuden kokoelmien ohjelmalliseen hallintaan, kokoelmaa voidaan esimerkiksi läpikäydä selaajien avulla. Seuraavassa esimerkissä on toteutettu edelliset taulukkojen käsittelyfunktiot array-kokoelman avulla: 11
12 // array-luokan otsikkotiedosto #include <array> // array-kokoelman tulostus. // Huomaa, että // 1. Taulukon koko voidaan kysyä kokoelmalta // 2. array voidaan välittää viitteenä funktiolle // 3. Funktiossa ei voi muuttaa kokoelman sisältöä template <typename Type, size_t Size> void tulostaarray(const std::array<type,size> &taulu) { for(int i = 0; i < taulu.size(); i++){ std::cout << "taulukko[" << i <<"] = " << taulu[i] << std::endl; // array-kokoelman lajittelu. // Huomaa, että // 1. Taulukon koko voidaan kysyä kokoelmalta // 2. array voidaan välittää viitteenä funktiolle // 3. Funktiossa voidaan muuttaa kokoelman sisältöä template <typename Type, size_t Size> void lajittelearray(std::array<type,size> &taulu) { int koko = taulu.size(); for(int i = 0; i < koko; i++){ for(int j = i+1; j < koko; j++){ if( taulu[i] > taulu[j] ){ Type temp = taulu[i]; taulu[i] = taulu[j]; taulu[j] = temp; Koska array on geneerinen luokka, joka ottaa tyyppiparametreina taulukkoon tallennettavien tietoalkioiden tyypin ja taulukon koon, pitää tyyppiparametrien näkyä myös funktion toteutuksessa. Tässä tapauksessa funktioista on tehty myös geneerisiä, joten ne voivat käsitellä mitä tahansa array-kokoelmia riippumatta niihin tallennettujen tietoalkioiden tyypistä. Funktioita voitaisiin käyttää esimerkiksi näin: int main(int argc, char** argv){ // Luodaan kokonaisulukuja sisältävä array std::array<int,10> intarray = {15, 28, 11, 56, 31, 8, 34, 17, 10, 19; std::cout << std::endl << "Array alussa:" << std::endl; tulostaarray(intarray); lajittelearray(intarray); std::cout << std::endl << "Array lajiteltuna:" << std::endl; tulostaarray(intarray); return 0; Käännettäessä C++11-standardin mukaista koodia kääntäjälle on yleensä ilmaistava tämä erikseen. Esimerkiksi g++-kääntäjälle on annettava käännösparametri std=c
13 5. IOStream-kirjasto Aiemmin osassa Johdanto ohjelmointiin C++-kielellä tutustuttiin hieman perus IOtoimintoihin. Tässä perehdytään hieman tarkemmin C++:n IOStream-kirjastoon, jonka avulla käyttäjän kanssa kommunikoidaan. IOStream-kirjasto toteuttaa IO-toiminnot käyttäen tietovirroiksi tai tietovoiksi (yksikössä siis tietovuo ) kutsuttuja olioita. Vuopohjaisessa tiedonsiirrossa datan ajatellaan koostuvan virrasta samankokoisia yksiköitä, jotka voivat olla esimerkiksi tavuja tai merkkejä. Tällöin luku- ja tulostustoiminnot mielletään käsitteellisesti em. yksiköiden virtana ohjelmasta tai ohjelmaan. Tulostustoimintojen kantaluokka on luokkamalli basic_ostream; ohjelmassa käytetään useimmiten sen tavalliselle merkkityypille (char) kiinnitettyä toteutusta ostream. Esimerkiksi standarditulostusvirran cout tyyppi on ostream. Tulostusoperaattori << on kuormitettu luokassa ostream kaikille sisäisille tietotyypeille. Mikäli ohjelmoija haluaa tulostaa omia tyyppejä käyttäen operaattoria <<, on operaattori ylikuormitettava myös näille tyypeille. Tarkastellaan esimerkiksi koosteolioiden yhteydessä esiintynyttä Henkilo-luokkaa ja lisätään siihen ylikuormitettu tulostusoperaattori: // Tiedosto henkilo.h class Henkilo { private: std::string etunimi; std::string sukunimi; std::string sotu; public: Henkilo(std::string en,std::string sn,std::string stu); ~Henkilo(){; ; std::string getetunimi() const; std::string getsukunimi() const; std::string getsotu() const; // Ylikuormitettu tulostusoperaattori std::ostream& operator<<(std::ostream &os,const Henkilo &h); 13
14 // Tiedosto henkilo.cpp #include <iostream> #include <string> #include "henkilo.h" Henkilo::Henkilo(std::string en,std::string sn,std::string stu): etunimi(en),sukunimi(sn),sotu(stu){ std::string Henkilo::getEtunimi() const{ return etunimi; std::string Henkilo::getSukunimi() const{ return sukunimi; std::string Henkilo::getSotu() const{ return sotu; // Ylikuormitetun tulostusoperaattorin toteutus std::ostream& operator<<(std::ostream &os,const Henkilo &h){ os << h.getetunimi() <<" "<< h.getsukunimi() << std::endl; os << h.getsotu(); return os; Huomaa, että tulostusoperaattori ei ole luokan jäsenfunktio, joten jäsenmuuttujien arvot saadaan ainoastaan luokan saantimetodien kautta. Huomaa myös. että tulostusoperaattori palauttaa viitteen käytettävään tulostusvirtaan, joten tulostuksia voidaan ketjuttaa. Nyt luokan olioita voitaisiin tulostaa esimerkiksi seuraavasti: Henkilo h("aku", "Ankka"," "); Henkilo eco("umberto","eco"," "); cout << h << endl << eco << endl; Lukutoimintojen kantaluokka on basic_istream; luokka istream on sen tavalliselle merkkityypille (char) kiinnitetty toteutus, jota ohjelmassa yleensä käytetään. Lukuoperaattori >> on luokassa kuormitettu sisäisille tietotyypeille ja omille tietotyypeille voidaan lukuoperaattori ylikuormittaa tarvittaessa. Tällöin on kuitenkin huomioitava virhesyötteiden mahdollisuus. Edellä esiteltyyn Henkilo-luokkaan lukuoperaattorin toteutus on suoraviivainen, koska luokan konstruktorille syötetään kolme merkkijonoa. Ensin otsikkotiedostoon lisätään esittely // Ylikuormitettu lukuoperaattori std::istream& operator>>(std::istream &is, Henkilo &h); 14
15 Tämän jälkeen sen toteutus lisätään lähdekooditiedostoon: std::istream& operator>>(std::istream &is, Henkilo &h){ std::string enimi=""; std::string sunimi=""; std::string sotu=""; is >> enimi >> sunimi >> sotu; h = Henkilo(enimi, sunimi, sotu); return is; Nyt operaattoria voidaankin soveltaa ohjelmassa: Henkilo h("aku", "Ankka"," "); cout << "Anna henkilon tiedot" << endl; cin >> h; // Luetaan etunimi, sukunimi ja hetu cout << endl << h << endl; Tiedostot Standarditulostuksen ja lukemisen lisäksi ohjelmissa tarvitaan tiedostojen luku- ja kirjoitustoimintoja. Tiedostojen lukuvirtaluokka ifstream periytyy luokasta istream ja tulostusvirtaluokka ofstream luokasta ostream. Näin ollen luokille istream ja ostream määritellyt luku- ja kirjoitusoperaattorit operoivat myös tiedostoja, esimerkiksi Henkilo-luokan olio voitaisiin kirjoittaa tiedostoon lisäämällä ohjelmaan otsikkotiedosto <fstream>, jossa tiedostovirrat on määritelty, ja kirjoittamalla Henkilo h("aku", "Ankka"," "); ofstream tied_out("henk.txt"); tied_out << h << endl; Tällöin ohjelma kirjoittaa tiedostoon henk.txt rivit Aku Ankka Henkilön tiedot voitaisiin puolestaan lukea ko. tiedostosta seuraavasti: Henkilo aku("","",""); ifstream tied("henk.txt"); tied >> aku; cout << aku << endl; Mikäli tiedostoon pitää kirjoittaa eri tavalla kuin muutoin tulostetaan, voidaan tulostusoperaattori luonnollisesti ylikuormittaa myös tiedoston tulostusvirralle. Sama koskee myös tiedostosta lukemista. Tiedosto on aina käytön jälkeen suljettava, minkä voi tehdä tiedostovirtaolioiden metodilla close. Tämä ei kuitenkaan aina ole tarpeen, sillä tiedostovirtaolion hajotin sulkee vielä avoimen tiedoston. 15
16 Muistipohjainen IO Luku- ja kirjoitusoperaatiot voidaan liittää myös string-luokan merkkijonoihin. Tämän tekee otsikkotiedostossa <sstream> määritelty stringstream-luokka, joka mainittiin jo osassa Johdanto ohjelmointiin C++-kielellä. Luokkaa käytetään useimmiten muuttamaan merkkijonoja jonkin tietotyypin muuttujien arvoiksi ja päinvastoin. Luokan luku- ja kirjoitustoiminnot kohdistuvat sisäiseen puskuriin, jonka sisältö string-oliona voidaan lukea milloin tahansa kutsumalla luokan jäsenfunktiota str. Esimerkiksi seuraava geneerinen funktio muuntaa minkä tahansa tietotyypin, jolle operaattori << on määritelty, muuttujan merkkijonoksi: template<class T> string converttostring(const T& t) { stringstream strm; strm << t; return strm.str(); Ohjelmissa joudutaan myös usein muuntamaan syötetty merkkijono toisen tyyppiseksi, esimerkiksi numeeriseksi tiedoksi. Se voidaan tehdä alla olevalla geneerisellä funktiolla: template <typename T> const T convertfromstring(const string& str) { stringstream strm(str); T tmp; strm >> tmp; return tmp; Jälkimmäisessä funktiossa stringstreamin puskuri alustetaan merkkijonolla, joka yritetään lukea annetun tietotyypin muuttujan arvoksi. Em. funktioita voitaisiin käyttää pääohjelmassa vaikkapa seuraavasti: 16
17 #include <iostream> #include <string> #include <sstream> using namespace std; int main() { string luku1 = "1.234"; string luku2 = "2.33"; cout << convertfromstring<double>(luku1) + convertfromstring<double>(luku2) << endl; int koko1 = 1234, koko2 = 5678; cout << converttostring<int>(koko1)+ converttostring<int>(koko2) << endl; string rivi,sana; cout << "Anna rivi niin erottelen siita sanat: " << endl; getline(cin, rivi); istringstream strm(rivi); int i=1; while(strm >> sana) { cout << "Sana " << i++ << " = " << sana << endl; return 0; Aluksi ohjelmassa muunnetaan kaksi merkkijonoa reaaliluvuiksi ja lasketaan ne yhteen. Tämän jälkeen muunnetaan kaksi kokonaislukua merkkijonoiksi, jolloin yhteenlasku liittää merkkijonot peräkkäin. Lopuksi ohjelmassa demonstroidaan stringstream-olion käyttämistä syötetyn rivin jäsentämiseksi sanoihin. Lähteet [Bud] Budd, Timothy A: An Introduction to Object-Oriented Programming, Addison-Wesley 2002 [Eck] Eckel, Bruce: Thinking in C++, 2 nd edition, Volume 1, Saatavissa osoitteesta: [Stro] Stroustrup, Bjarne: The C++ Programming Language, Addison-Wesley 1997 [Ves] Vesterholm, Kyppö: Java-ohjelmointi, Talentum
812347A Olio-ohjelmointi, 2015 syksy 2. vsk. V Geneerisyys
812347A Olio-ohjelmointi, 2015 syksy 2. vsk V Geneerisyys Sisältö 1. Johdanto geneerisyyteen 2. Geneeriset funktiot 3. Geneeriset luokat 4. Standard Template Library (STL) 5. IOStream-kirjasto 812347A
Lisä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ä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ä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ätiedot15. Ohjelmoinnin tekniikkaa 15.1
15. Ohjelmoinnin tekniikkaa 15.1 Sisällys For-each-rakenne. Geneerinen ohjelmointi. Lueteltu tyyppi enum. 15.2 For-each-rakenne For-rakenteen variaatio taulukoiden ja muiden kokoelmien silmukoimiseen:
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ä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ätiedot15. 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ä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ä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ätiedotGeneeriset luokat. C++ - perusteet Java-osaajille luento 6/7: Template, tyyppi-informaatio, nimiavaruudet. Geneerisen luokan käyttö.
Geneeriset luokat C++ - perusteet Java-osaajille luento 6/7: Template, tyyppi-informaatio, nimiavaruudet Geneerinen luokka tarkoittaa parametroitua luokkamallia, jonka avulla voidaan muodostaa useita,
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ätiedotOsoitin 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ä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ä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ä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ä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ä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ä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ä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ä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ä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ä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ätiedotJava-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ä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ä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. 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ä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ä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ä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ä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ä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ätiedot812336A C++ -kielen perusteet, 21.8.2010
812336A C++ -kielen perusteet, 21.8.2010 1. Vastaa lyhyesti seuraaviin kysymyksiin (1p kaikista): a) Mitä tarkoittaa funktion ylikuormittaminen (overloading)? b) Mitä tarkoittaa jäsenfunktion ylimääritys
LisätiedotOlio-ohjelmointi Poikkeusten käsittelystä. 1. Johdanto
Olio-ohjelmointi Poikkeusten käsittelystä Virheiden käsittely liittyy olennaisesti kaikkeen ohjelmointiin. Monissa sovelluksissa virhetilanteiden käsittelemiseen liittyvää koodia on merkittävä osuus koko
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ä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ätiedotRajapinta (interface)
1 Rajapinta (interface) Mikä rajapinta on? Rajapinta ja siitä toteutettu luokka Monimuotoisuus ja dynaaminen sidonta Rajapinta vs periytyminen 1 Mikä rajapinta on? Rajapintoja käytetään, kun halutaan määritellä
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ä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ätiedotOpintojakso 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ätiedotStandardi 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ä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ä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ä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ä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ätiedotJava kahdessa tunnissa. Jyry Suvilehto
Java kahdessa tunnissa Jyry Suvilehto Ohjelma Ohjelmointiasioita alkeista nippelitietoon n. 45 min Tauko 10 min Oliot, luokat ja muut kummajaiset n. 45 min Kysykää Sisältöä ei oikeasti ole 2x45 min täytteeksi,
LisätiedotEsimerkki luokkahierarkiasta: C++-kielen IOstream-kirjasto
Esimerkki luokkahierarkiasta: C++-kielen IOstream-kirjasto Tässä materiaalissa tutustutaan tarkemmin C++:n luokkahierarkiaan. Koska kyseessä on oliopohjainen kieli, C++:n luokat on järjestetty hierarkisesti
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ä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ätiedotLuokka Murtoluku uudelleen. Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista.
1 Luokka Murtoluku uudelleen Kirjoitetaan luokka Murtoluku uudelleen niin, että murtolukujen sieventäminen on mahdollista. Sievennettäessä tarvitaan osoittajan ja nimittäjän suurin yhteinen tekijä (syt).
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ä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ätiedot1. Olio-ohjelmointi 1.1
1. Olio-ohjelmointi 1.1 Sisällys Olio-ohjelmointi on eräs ohjelmointiparadigma. Olio-ohjelmoinnin muotoja. Ohjelmiston analyysi ja suunnittelu. Olioparadigman etuja ja kritiikkiä. 1.2 Ohjelmointiparadigmoja
Lisä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ätiedotHarjoitustyö: virtuaalikone
Harjoitustyö: virtuaalikone Toteuta alla kuvattu virtuaalikone yksinkertaiselle olio-orientoituneelle skriptauskielelle. Paketissa on testaamista varten mukana kaksi lyhyttä ohjelmaa. Ohjeita Noudata ohjelman
LisätiedotOhjelmoinnin perusteet Y Python
Ohjelmoinnin perusteet Y Python T-106.1208 2.3.2011 T-106.1208 Ohjelmoinnin perusteet Y 2.3.2011 1 / 39 Kertausta: tiedoston avaaminen Kun ohjelma haluaa lukea tai kirjoittaa tekstitiedostoon, on ohjelmalle
LisätiedotMetodien tekeminen Javalla
1 Metodien tekeminen Javalla Mikä metodi on? Metodin syntaksi Metodi ja sen kutsuminen Parametreista Merkkijonot ja metodi Taulukot ja metodi 1 Mikä metodi on? Metodilla toteutetaan luokkaan toiminnallisuutta.
Lisä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ä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ä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ätiedotOhjelmoinnin perusteet Y Python
Ohjelmoinnin perusteet Y Python T-106.1208 16.3.2009 T-106.1208 Ohjelmoinnin perusteet Y 16.3.2009 1 / 40 Kertausta: tiedostosta lukeminen Aluksi käsiteltävä tiedosto pitää avata: tiedostomuuttuja = open("teksti.txt","r")
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ä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ä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ä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ä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ä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ätiedotTaulukot. 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ä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ätiedot4. Luokan testaus ja käyttö olion kautta 4.1
4. Luokan testaus ja käyttö olion kautta 4.1 Olion luominen luokasta Java-kielessä olio määritellään joko luokan edustajaksi tai taulukoksi. Olio on joukko keskusmuistissa olevia tietoja. Oliota käsitellään
LisätiedotMerkkijonot ja C++ Antti-Juhani Kaijanaho. 5. maaliskuuta 2001. 1 Vanhojen C++-kääntäjien käyttäjät, huomio! 2 Merkkijonojen perusteet
Merkkijonot ja C++ Antti-Juhani Kaijanaho 5. maaliskuuta 2001 1 Vanhojen C++-kääntäjien käyttäjät, huomio! Tämä kirjoitus perustuu vuonna 1998 julkistettuun C++-kielen kansainväliseen ISO-standardiin.
Lisä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ä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ä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ätiedotOhjelmointi 2 / 2010 Välikoe / 26.3
Ohjelmointi 2 / 2010 Välikoe / 26.3 Välikoe / 26.3 Vastaa neljään (4) tehtävään ja halutessa bonustehtäviin B1 ja/tai B2, (tuovat lisäpisteitä). Bonustehtävät saa tehdä vaikkei olisi tehnyt siihen tehtävään
Lisätiedot\+jokin merkki tarkoittaa erikoismerkkiä; \n = uusi rivi.
1. Johdanto 1.1 Yleistä Suurten ohjelmien organisointi vaikeaa C:ssä. 1980 Stroustrup lisäsi C:hen olio-ohjelmoinnin (OOP = Object Oriented Programming). C C++: C-ohjelma on (muutamia poikkeuksia lukuunottamatta)
LisätiedotUNIVERSITY OF OULU DEPARTMENT OF INFORMATION PROCESSING SCIENCE
1 UNIVERSITY OF OULU DEPARTMENT OF INFORMATION PROCESSING SCIENCE OPETUSMONISTEET SARJA C11 JUUSTILA ANTTI KETTUNEN HARRI KILPI TEEMU RÄISÄNEN TONI VESANEN ARI C++- OHJELMOINTIKURSSIN OHEISMATERIAALI ISBN
LisätiedotOlio-ohjelmointi Suunnittelumallit Adapter ja Composite. 1. Adapter
Olio-ohjelmointi Suunnittelumallit Adapter ja Composite Rakennemalleissa päähuomio kohdistetaan siihen, miten luokkia ja olioita yhdistellään muodostamaan laajempia rakenteita. Rakenteelliset luokkamallit
LisätiedotTietojen syöttäminen ohjelmalle. Tietojen syöttäminen ohjelmalle Scanner-luokan avulla
Tietojen syöttäminen ohjelmalle Tähän mennessä on käsitelty Javan tulostuslauseet System.out.print ja System.out.println sekä ohjelman perusrakenneosat (muuttujat, vakiot, lauseet). Jotta päästään tekemään
LisätiedotOpintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op. Standardi- ja tietorakenneluokkia
Opintojakso TT00AA11 Ohjelmoinnin jatko (Java): 3 op Standardi- ja tietorakenneluokkia Standardi- ja tietorakenneluokkia Javan API, ArrayList Ohjelmointirajapinta (Application Programming Interface, API)
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ätiedotOlio-ohjelmoinnissa luokat voidaan järjestää siten, että ne pystyvät jakamaan yhteisiä tietoja ja aliohjelmia.
4. Periytyminen 4.1. Johdantoa Käytännössä vähänkään laajemmissa ohjelmissa joudutaan laatimaan useita luokkia, joiden pitäisi pystyä välittämään tietoa toisilleen. Ohjelmien ylläpidon kannalta olisi lisäksi
Lisä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ätiedotOhjelmointi 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ätiedot17. Javan omat luokat 17.1
17. Javan omat luokat 17.1 Sisällys Application Programming Interface (API). Pakkaukset. Merkkijonoluokka String. Math-luokka. Kääreluokat. 17.2 Java API Java-kielen Application Programming Interface (API)
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ätiedot812347A Olio-ohjelmointi, 2015 syksy 2. vsk. VII Suunnittelumallit Adapter ja Composite
2015 syksy 2. vsk VII Suunnittelumallit Adapter ja Composite Sisältö 1. Johdanto rakennemalleihin 2. Adapter (Sovitin) 3. Composite (Rekursiokooste) Suunnittelumallit Adapter ja Composite 2 VII.1 Johdanto
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ä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ätiedot815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset
815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 2 vastaukset Harjoituksen aiheena on BNF-merkinnän käyttö ja yhteys rekursiivisesti etenevään jäsentäjään. Tehtävä 1. Mitkä ilmaukset seuraava
Lisätiedot1. 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ä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ä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ätiedotAS-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ä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ätiedottään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla
2.5. YDIN-HASKELL 19 tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla kirjaimilla. Jos Γ ja ovat tyyppilausekkeita, niin Γ on tyyppilauseke. Nuoli kirjoitetaan koneella
LisätiedotTietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)
Tietorakenteet JAVA-OHJELMOINTI Osa 5: Tietorakenteita Eero Hyvönen Tietojenkäsittelytieteen laitos Helsingin yliopisto Olioita ja tietoja voidaan organisoida määrämuotoisiksi tietorakenteiksi Hyödyllisiä
LisätiedotSisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä 12.1 12.2 12.3 12.4
Sisällys 12. Näppäimistöltä lukeminen Arvojen lukeminen näppäimistöltä yleisesti. Arvojen lukeminen näppäimistöltä Java-kielessä.. Luetun arvon tarkistaminen. Tietovirrat ja ohjausmerkit. Scanner-luokka.
Lisä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ätiedotTieto- 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