Osoittimet. Mikä on osoitin?

Koko: px
Aloita esitys sivulta:

Download "Osoittimet. Mikä on osoitin?"

Transkriptio

1 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 tekevät muillakin tavoilla ohjelmistasi tehokkaita. Tässä luvussa käsittelemme: Mikä on osoitin ja miten sellainen esitellään Miten saadaan selville muuttujan osoite Miten osoittimet liittyvät taulukoihin Miten osoitinlaskenta toimii ja mihin sitä käytetään Mitä standardikirjaston funktioita on käytettävissä null-merkkiin päättyvien merkkijonojen käsittelyyn Miten muistia varataan uusille muuttujille ohjelman suoritusaikana Miten dynaamisesti varattu muisti vapautetaan Miten tietyn tyyppinen osoitin muunnetaan toisentyyppiseksi Mikä on osoitin? Jokaisella muuttujalla ja literaalilla on osoite muistissa - eli sijainti tietokoneen muistissa, johon tieto talletetaan. Vastaavasti funktioiden täytyy sijaita jossain kohtaa muistissa, jotta ne voidaan suorittaa; eli funktiolla on myös osoite. Nämä osoitteet riippuvat siitä, mihin ohjelmasi on muistissa ladattu käynnistäessäsi sen, joten osoitteet saattavat olla erit ohjelman eri suorituskerroilla. Osoitin on muuttuja, johon voidaan tallettaa muistiosoite. Osoittimeen talletettu osoite vastaa yleensä muuttujan sijaintikohtaa muistissa, mutta se voi olla myös funktion osoite, kuten näemme seuraavassa luvussa. 231

2 C++ Ohjelmoijan käsikirja Heksadesimaalinen muistiosoite C long-tyyppinen muuttuja Sisältö on toisen muuttujan osoite C Osoitinmuuttuja Kaaviosta huomaat, mistä osoitin on saanut nimensä: se osoittaa muistikohtaan, johon on talletettu jotain tietoa - muuttuja tai funktio. Ei kuitenkaan riitä, että osoitin tallettaa muistiosoitteen. Jotta kyseiseen muistipaikkaan talletettua tietoa voidaan käyttää hyväksi, tarvitaan myöskin tietoa mitä muistipaikassa on, ei pelkästään missä se on. Kuten tiedät, kokonaisluvulla on varsin erilainen esitysmuoto kuin liukuluvulla ja tavallisesti kokonaisluvun tallettamiseen tarvitaan vähemmän tavujakin. Eli, jotta osoittimen sisältämän osoitteen muistipaikan tietoa voidaan käyttää hyväksi, tarvitaan myös tiedon tyyppi. Tästä yksinkertaisesta logiikasta seuraa se, että osoitin ei ole pelkkä osoitin; se on osoitin tietyntyyppiseen tietoalkioon. Tämä tulee selvemmäksi, kun siirrymme yksityiskohtiin. Käsitellään ensiksi osoittimien luontia. Osoittimen esittely Osoittimen esittely on samanlainen kuin tavallisenkin muuttujan esittely. Erona on se, että osoittimen tyypin perässä on asteriski, mikä kertoo, että olemme esittelemässä muuttujaa, joka on osoitin sen tyyppiseen tietoon. Jos esimerkiksi haluat esitellä osoittimen pnumero, joka osoittaa long-tyyppiseen arvoon, voit käyttää seuraavaa lausetta: long* pnumero; 232 Tämä esittelee osoitinmuuttujan pnumero, joka voi tallettaa long-tyyppisen muuttujan osoitteen. Tämän muuttujan tyyppi on osoitin long-tyyppiseen tietoon, ja kun tyyppi kirjoitetaan yksinään (esimerkiksi eksplisiittisessä tyypinmuunnoksessa), se kirjoitetaan yleensä long*. Yllä oleva esittely on kirjoitettu siten, että asteriski kirjoitettiin tyypin perään, mutta se ei ole ainut tapa kirjoittaa sitä. Voit kirjoittaa esittelyn myös siten, että asteriski on muuttujan nimen edessä, kuten lauseessa: long *pnumero;

3 Osoittimet Tämä esittelee täsmälleen saman muuttujan kuin edelläkin. Kääntäjä hyväksyy molemmat muodot, mutta ensimmäinen on ehkä yleisempi, koska se ilmaisee paremmin tyypin osoitin long-tyyppiseen tietoon. Tässä on kuitenkin sekaannuksen vaara, jos sekoitat tavallisten muuttujien ja osoittimen esittelyjä samaan lauseeseen. Mieti, mitä seuraava lause tekee: long* pnumero, numero; Se määrittelee muuttujan pnumero, jonka tyyppi on osoitin long-tyyppiseen tietoon ja muuttujan numero, joka on tyyppiä long. Eli esitystapa, jossa asteriski yhdistetään tyypin nimeen, ei tuo tätä selkeästi esiin. Jos olisit määritellyt nämä kaksi muuttujaa käyttäen toista muotoa: long *pnumero, numero; Tämä on selkeämpi, koska asteriski on nyt selvästi liitetty muuttujaan pnumero. Paras ratkaisu tähän ongelmaan on kuitenkin se, että ei edes kirjoiteta niitä samaan lauseeseen. Paras tapa on esitellä kaikki muuttujat omilla riveillään, jolloin vältetään kaikki mahdollisesti epäselvyydet: long numero; long* pnumero; //long-tyyppisen muuttujan esittely // osoitin long-tyyppiseen tietoon -esittely Tästä on sekin lisähyöty, että voimme helposti lisätä kommentit muuttujien perään. Esimerkissämme käytimme tunnistetta pnumero osoitinmuuttujan nimenä. Se ei ole pakollista, mutta käytännön sopimuksena C++:ssa on käyttää osoittimien nimien edessä p-merkkiä (osoitin, pointer ). Tällä tavalla ohjelmasta näkyy selvästi, mitkä muuttujat ovat osoittimia, ja tämä helpottaa ohjelman lukemista. Osoittimet muuntyyppiseen tietoon kuin long esitellään aivan samaan tapaan. Voimme esimerkiksi esitellä muuttujat, jotka osoittavat double- ja string-tyyppiseen tietoon lauseilla: double* parvo; string* plause; Osoittimien käyttö //Osoitin double-tyyppiseen tietoon //Osoitin string-tyyppiseen tietoon Jotta voimme käyttää osoitinta, meidän tulee tallettaa siihen toisen, sopivan tyyppisen muuttujan osoite. Katsotaan seuraavaksi, miten saamme selville muuttujan osoitteen. Osoite-operaattori Osoite-operaattori & on unaarinen operaattori, joka kertoo muistiosoitteen, jossa kyseinen muuttuja sijaitsee. Voimme esitellä osoittimen pnumero ja muuttujan numero lauseilla: long numero = 12345; long* pnumero; Koska muuttujan numero ja osoittimen pnumero tyypit ovat yhteensopivat, voimme kirjoittaa seuraavan sijoituksen: pnumero = № //Sijoitetaan numeron osoite osoittimeen pnumero 233

4 C++ Ohjelmoijan käsikirja Tämä tarkoittaa, että osoittimeen pnumero sijoitetaan muuttujan numero osoite. Tämän operaation tulos selvitetään alla olevassa kaaviossa: Heksadesimaalinen muistiosoite C long-tyyppinen muuttuja numero pnumero = &numero; Numeron osoite on talletettu osoittimeen C pnumber on tyyppiä osoitin long- tyyppiseen tietoon Voit lukea &-operaattorilla minkä tyyppisen muuttujan osoitteen tahansa, mutta osoite tulee tallettaa sopivan tyyppiseen osoittimeen. Jos esimerkiksi haluat tallettaa double-tyyppisen muuttujan osoitteen, osoitin tulee olla esitelty double*-tyyppiseksi. Jos yrität tallettaa osoitteen väärän tyyppiseen osoittimeen, ohjelmasi ei käänny. Muuttujan osoitteen lukeminen ja sen tallettaminen osoittimeen on kaikki ihan ok, mutta kaikkein kiinnostavinta kuitenkin on, miten osoitinta voidaan käyttää; eli osoittimen osoittaman muistipaikan sisällön käsittely. Tämä tehdään osoitus-operaattorin avulla. Osoitus-operaattori Osoitus-operaattoria * käytetään osoittimen kanssa, jotta pääsemme käsiksi osoittimen osoittaman muistiosoitteen sisältöön. Katsotaan tätä käytännössä. Kokeile itse - Osoitus-operaattorin käyttö Tämä esimerkki havainnollistaa osoitus-operaattorin käyttöä. Sen avulla tulostetaan osoittimen osoittaman muuttujan sisältö: // Esimerkki Osoitus-operaattorin käyttö #include <iostream> using namespace std; int main() 234

5 Osoittimet long numero = 50L; long* pnumero; // Osoittimen esittely pnumero = &numero; // Talletetaan numeron osoite cout << endl << "Muuttujaan numero talletettu arvo on " << *pnumero << endl; return 0; Kun käännät ja suoritat ohjelman, se tulostaa: Muuttujaan numero talletettu arvo on 50 Kuinka se toimii Ensiksi esittelemme tavallisen long-tyyppisen muuttujan, joka alustetaan arvolla 50. long numero = 50L; Seuraavaksi esittelemme osoitinmuuttujan: long* pnumero; // Osoittimen esittely Koska osoittimen tyyppi on long*, se voi tallettaa long-tyyppisen muuttujan osoitteen. Talletamme muuttujan numero osoitteen osoittimeen pnumero lauseella: pnumero = &numero; // Talletetaan numeron osoite Osoite-operaattorilla & luemme muuttujan numero muistiosoitteen, joka talletetaan osoittimeen pnumero. Voimme nyt tulostaa muuttujaan numero talletetun arvon osoittimen pnumero avulla. Osoittimen yhteydessä käytetty osoitus-operaattori viittaa osoittimen osoittaman muistipaikan sisältöön. Koska pnumero sisältää muuttujan numero osoitteen, *pnumero viittaa muuttujan numero arvoon. Osoitus-operaattorin käyttö saattaa ainakin aluksi tuntua sekavalta, koska meillä on nyt useita eri käyttötarkoituksia samalle *-merkille. Se on kertolaskuoperaattori, osoitus-operaattori ja sitä käytetään myös osoittimen esittelyssä. Joka kerta kun käytät *-merkkiä, kääntäjä pystyy kuitenkin päättelemään sen merkityksen. Kun kerrot kaksi lukua keskenään - esimerkiksi hinta * maara - tätä lauseketta ei voida tulkita muuksi kuin kertolaskuksi. Seuraava esimerkkiohjelma (7.2) havainnollistaa, että kääntäjä todella pystyy tähän päättelyyn. Miksi käyttää osoittimia? Tässä kohtaa tulee yleensä mieleen, Miksi ylipäätään tulisi käyttää osoittimia? Näyttäähän siltä, että jo olemassa olevan muuttujan osoitteen lukeminen ja tallettaminen osoittimeen vain sen takia, että voit myöhemmin viitata muuttujaan osoittimen avulla, olisi tarpeetonta ja tulisit toimeen myös ilman osoitinta. Älä kiirehdi asioiden edelle - osoittimille on useita tärkeitä käyttötarkoituksia! 235

6 C++ Ohjelmoijan käsikirja Ensinnäkin, kuten kohta näet, voit käyttää osoitinmuotoa taulukon alkioiden käsittelyssä, joka yleensä toimii nopeammin kuin taulukkomuodon käyttö. Toiseksi, kun määrittelemme omia funktioitamme myöhemmin tässä kirjassa, huomaat, että osoittimia käytetään runsaasti, jotta funktion sisältä päästään käsiksi funktion ulkopuolella määriteltyihin suuriin tietojoukkoihin, kuten taulukoihin. Kolmanneksi, mikä onkin kaikkein tärkein syy, näet myöhemmin, kuinka osoittimien avulla voit varata muistia uusille muuttujille dynaamisesti - eli ohjelman suorituksen aikana. Tämä mahdollistaa ohjelmasi säätävän käyttämäänsä muistia syötteen mukaan. Voit luoda uusia muuttujia suorituksen aikana aina kun tarvitset sellaisen. Koska et etukäteen tiedä, kuinka monta muuttujaa luot dynaamisesti, ainut tapa tehdä se on käyttää osoittimia - joten opettele osoittimien käyttö tarkasti! Jotta saamme lisää tuntumaa osoittimiin, katsotaan toista varsin yksinkertaista esimerkkiä, joka havainnollistaa edelleen osoittimien käyttöä. Kokeile itse - Osoittimien käyttö Voimme kokeilla jo käsittelemiämme osoittimien operaatioita esimerkin avulla: // Esimerkki Osoittimien käyttö #include <iostream> using namespace std; int main() long* pnumero; long numero1 = 55L; long numero2 = 99L; // Osoittimen esittely // Joitakin muuttujia pnumero = &numero1; // Talleta osoite osoittimeen *pnumero += 11; // Kasvatetaan muuttujaa numero1 cout << endl << "numero1 = " << numero1 << " &numero1 = " << pnumero << endl; pnumero = &numero2; numero1 = *pnumero * 10; // Muutetaan osoitin osoittamaan numero2:ta // 10 kertaa numero2 cout << "numero1 = " << numero1 << " pnumero = " << pnumero << " *pnumero = " << *pnumero << endl; return 0; Minun tietokoneessa ohjelma tulostaa seuraavaa: 236 numero1 = 66 &numero1 = 0068FDF4 numero1 = 990 pnumero = 0068FDF0 *pnumero = 99

7 On todennäköistä, että osoitteiden arvot sinun tietokoneessasi ovat erit kuin edellä olleet. Osoittimet Kuinka se toimii Tällä esimerkillä ei ole lainkaan syötteitä; kaikki operaatiot suoritetaan ohjelmassa määritetyillä arvoilla. Kun muuttujan numero1 osoite on talletettu osoittimeen pnumero, muuttujan numero1 arvoa kasvatetaan epäsuorasti osoittimen avulla: *pnumero += 11; // Kasvatetaan muuttujaa numero1 Osoitus-operaattori määrittelee, että lisäämme luvun 11 osoittimen osoittamaan muuttujaan numero1. Tämä havainnollistaa, että voimme kirjoittaa osoittimen ja osoitus-operaattorin sijoitusoperaattorin vasemmalle puolelle. Jos jätämme *-merkin pois, ohjelma yrittää muuttaa osoittimeen talletettua osoitetta. (Käsittelemme osoitinaritmetiikkaa hieman myöhemmin.) Seuraava lause tulostaa muuttujan numero1 arvon ja numero1:n osoitteen, joka on talletettu osoittimeen pnumero: cout << endl << "numero1 = " << numero1 << " &numero1 = " << pnumero << endl; Jos lähetämme numeerisen osoittimen nimen sellaisenaan (eli tässä tapauksessa, pnumero) tulostusvirtaan, tulostuu osoite. Koska kyseessä on osoitin, tulostetaan arvo heksadesimaalisena. Muistiosoitteet esitetään yleensä heksadesimaalimuodossa - muissakin kielissä kuin C++:ssa. Koska muuttuja numero on tavallinen kokonaislukumuuttuja, sen arvo tulostetaan desimaalimuodossa. Ensimmäisen tulostusrivin jälkeen osoittimen pnumero sisällöksi muutetaan muuttujan numero2 osoite: pnumero = &numero2; // Muutetaan osoitin osoittamaan numero2:ta Nyt pnumero osoittaa muuttujaan numero2. Muuttujan numero1 osoite, joka aikaisemmin oli osoittimessa pnumero, kirjoitetaan yli. Voimme nyt muuttaa muuttujan numero1 arvoksi 10 kertaa numero2, johon viitataan osoittimen avulla: numero1 = *pnumero * 10; // 10 kertaa numero2 Sijoitusoperaattorin oikealla puolella olevassa lausekkeessa kerrotaan muuttujan numero2 arvoa epäsuorasti osoittimen avulla luvulla 10. Kääntäjä tietää, miten *-merkit tulkitaan tässä lausekkeessa. Seuraava tulostuslause tulostaa laskutoimitusten tulokset: cout << "numero1 = " << numero1 << " pnumero = " << pnumero << " *pnumero = " << *pnumero << endl; Tämä tulostaa muuttujan numero1 arvon, osoittimeen pnumero talletetun osoitteen ja osoittimen pnumero osoittaman muistipaikan sisällön. Jälleen osoittimen pnumero arvo tulostetaan heksadesimaalisena, koska se on osoite. Lauseke *pnumero tarkoittaa tavallista kokonaislukuarvoa - muuttujan numero2 arvoa - joten se tulostetaan desimaalisena. 237

8 C++ Ohjelmoijan käsikirja Osoittimien alustus Jos mahdollista, alustamattomien osoittimien käyttö on vielä vaarallisempaa kuin alustamattomien muuttujien käyttö. Jos osoittimessa on roskaa, saatat kirjoittaa satunnaiseen muistialueeseen. Tulos riippuu aivan siitä, kuinka epäonninen olit, joten osoittimien alustaminen on enemmän kuin suositeltavaa. Osoittimen alustaminen jo määritellyn muuttujan osoitteen mukaan on hyvin helppoa. Voit alustaa osoittimen pnumero muuttujan numero osoitteella yksinkertaisesti käyttämällä osoiteoperaattoria yhdessä muuttujan nimen kanssa osoittimen alkuarvona: int numero = 0; int* pnumero = &numero; //Alustetaan kokonaislukumuuttuja //Alustetaan osoitin Kun alustat osoittimen käyttämällä toista muuttujaa kuten edellä, muista, että muuttujan tulee olla esitelty ennen osoittimen esittelyä. Jos näin ei ole, kääntäjäsi valittaa asiasta. Jos et halua alustaa osoitinta minkään muuttujan osoitteella, voit alustaa osoittimen alkuarvoksi nollan: int* pnumero = 0; //Osoitin, joka ei osoita mihinkään Tämä esittely varmistaa, että pnumero ei sisällä mitään. Näin ollen, jos yrität käyttää sitä epäsuorassa viittauksessa ennen kuin siinä on arvo, ohjelmasi epäonnistuu tavalla, josta varmasti tiedät mitä tapahtui. Tällä tavalla alustettu osoitin on ns. null-osoitin. Tietysti voit aina testata onko osoitin null, ennen kuin käytät sitä: if(pnumero == 0) cout << endl << pnumero on null. ; Muista käyttää vertailussa yhtäsuuruusmerkkejä ==! Voit yhtä hyvin käyttää seuraavaa vastaavaa lausetta: if(pnumero) cout << endl << pnumero on null. ; Tietysti voit käyttää myös tätä muotoa: if(pnumero!= 0) //Osoitin ei ole null, tee jotain... Symboli NULL on määritelty standardikirjastossa arvoksi 0, ja sitä käytetäänkin usein alustettaessa osoitin nulliksi. NULL on kuitenkin olemassa vain yhteensopivuuden vuoksi C-kielen kanssa. C++-kielessä suositellaan käytettäväksi arvoa

9 char-tyyppisten osoittimien alustus Osoittimet Muuttujalla, jonka tyyppi on osoitin char-tyyppiseen tietoon, on kiinnostava ominaisuus: se voidaan alustaa merkkijonoliteraalilla. Voimme esimerkiksi esitellä ja alustaa tällaisen osoittimen lauseella: char* psananlasku = Tavat tekevät miehen. ; Tämä näyttää varsin samanlaiselta kuin char-tyyppisen taulukon alustus, mutta älä anna ulkomuodon hämätä: se on varsin erilainen. Lause luo null-merkkiin päättyvän merkkijonoliteraalin (itse asiassa const char -tyyppisen taulukon) lainausmerkkien välissä olevista merkeistä ja tallettaa merkkijonoliteraalin ensimmäisen merkin osoitteen osoittimeen psananlasku. Tätä havainnollistetaan seuraavassa kaaviossa: char *psananlasku = "Tavat tekevät miehen. ; Osoite talletetaan psananlasku 2000 Osoite:2000 T a v a t t e k e v ä t m I e h e n. Merkkijonoliteraali talletetaan null-merkkiin päättyvänä merkkijonona Kaikki ei kuitenkaan ole aivan miltä näyttää. Merkkijonoliteraalin tyyppi on const, mutta osoittimen tyyppi ei ole. Lause ei luo merkkijonosta muokattavaa kopiota; se vain tallettaa ensimmäisen merkin osoitteen. Tämä tarkoittaa sitä, että jos kirjoitat koodia, joka yrittää muuttaa merkkijonoa, kuten seuraavan lauseen, joka yrittää muuttaa ensimmäisen merkin merkiksi X *psananlasku = X ; kääntäjä ei valita, koska se ei näe tässä mitään väärää. Mutta kun yrität suorittaa ohjelman, saat virheilmoituksen: merkkijonoliteraali on yhä vakio, jonka arvoa ei saa muuttaa. Saatat oikeutetusti ihmetellä, miksi kääntäjä salli sijoittaa const-tyyppisen arvon ei-consttyyppiin, koska tämähän aiheutti ongelman. Syynä on se, että merkkijonoliteraalit ovat tulleet vakioiksi vasta C++-standardin myötä ja olemassa on runsaasti ohjelmia, joissa käytetään väärää sijoitusta. Sen käyttöä ei kuitenkaan enää suositella ja ongelman oikea ratkaisutapa olisi esitellä osoitin seuraavasti: const char* psananlasku = Tavat tekevät miehen. ; Tämä esittelee, että psananlasku osoittaa const-tyyppiseen tietoon, eli se on yhteensopiva merkkijonoliteraalin tyypin kanssa. const-avainsanan käytöstä osoittimien yhteydessä on vielä paljon muutakin asiaa, joten palaamme tähän aiheeseen myöhemmin tässä luvussa. Nyt katsomme toisen esimerkin avulla, kuinka char*-tyyppisiä muuttujia käytetään. 239

10 C++ Ohjelmoijan käsikirja Kokeile itse - Tähtinäyttelijät osoittimien avulla Voimme kirjoittaa uuden version tähtinäyttelijät -ohjelmastamme (esimerkki 6.5), jossa käytetään osoittimia taulukon sijaan: // Esimerkki Osoittimien alustus merkkijonoilla #include <iostream> using namespace std; int main() // Tähtinäyttelijöihin viitataan osoittimien avulla const char* ptahti1 = "Mae West"; const char* ptahti2 = "Arnold Schwarzenegger"; const char* ptahti3 = "Lassie"; const char* ptahti4 = "Slim Pickens"; const char* ptahti5 = "Greta Garbo"; const char* ptahti6 = "Oliver Hardy"; const char* ptahti = "Tähtinäyttelijäsi on "; int valinta = 0; // Tähden valinta cout << endl << "Valitse tähtinäyttelijäsi!" << " Syötä numero väliltä 1-6: "; cin >> valinta; cout << endl; switch(valinta) case 1: cout << ptahti << ptahti1; break; case 2: cout << ptahti << ptahti2; break; case 3: cout << ptahti << ptahti3; break; case 4: cout << ptahti << ptahti4; break; case 5: cout << ptahti << ptahti5; break; case 6: cout << ptahti << ptahti6; break; default: cout << "Valitan, tähtinäyttelijääsi ei löydy."; 240 cout << endl; return 0;

11 Osoittimet Ohjelman esimerkkitulostus näyttää seuraavalta: Valitse tähtinäyttelijäsi! Syötä numero väliltä 1-6: 5 Tähtinäyttelijäsi on Greta Garbo Kuinka se toimii Alkuperäisen esimerkkimme taulukko on korvattu kuudella osoittimella, ptahti1 - ptahti6. Jokainen niistä alustetaan nimellä. Esittelemme myöskin osoittimen ptahti, joka alustetaan lauseella, jonka haluamme tulostaa normaalin tulostusrivin eteen. Koska kaikkia näitä osoittimia käytetään merkkijonoliteraaleihin osoittamiseen, määrittelemme ne const-tyyppisiksi. Koska meillä on erilliset osoittimet, oikean viestin valinta tapahtuu helpommin switch-lauseella kuin alkuperäisessä versiossa käytetyllä if-lauseella. Kielletyt arvot käsitellään kaikki switchlauseen default-osassa. Osoittimen osoittaman merkkijonon tulostaminen ei voisi olla helpompaa. Kuten huomaat, kirjoitamme yksinkertaisesti osoittimen nimen. Nyt olet saattanutkin jo huomata, että standarditulostusvirta cout kohtelee eri tyyppisiä osoittimien nimiä eri tavalla. Esimerkissä 7.2 lause cout << pnumero; tulostaisi osoittimen pnumero sisältämän osoitteen. Tässä esimerkissä lause: cout << ptahti1; tulostaisi kuitenkin merkkijonoliteraalin - ei osoitetta. Tämä ero johtuu siitä, että pnumero on osoitin numeeriseen tyyppiin, kun taas ptahti1 on osoitin char-tyyppiseen tietoon. Tulostusvirta cout käsittelee muuttujaa, joka on osoitin char-tyyppiseen tietoon, null-merkkiin päättyvänä merkkijonona ja tulostaa sen myös sellaisena. No mitkä ovat tämän version edut? Osoittimien käyttö poisti muistin tuhlauksen, jota tapahtui tämän ohjelman taulukkoratkaisussa, koska nyt jokainen merkkijono vie juuri sen verran tavuja kuin se tarvitsee. Ohjelma näyttää kuitenkin hieman ylipitkältä. Jos nyt ajattelet, että Täytyy olla parempikin tapa, olet aivan oikeassa - voimme käyttää osoitintaulukkoa. Kokeile itse - Osoitintaulukko char-tyyppisessä osoitintaulukossa jokainen alkio osoittaa erilliseen merkkijonoon ja jokaisen merkkijonon pituus voi olla eri. Voimme esitellä osoitintaulukon samaan tapaan kuin esittelemme minkä tahansa muunkin taulukon. Seuraavassa on uusi versio edellisestä esimerkistä. Siinä käytetään osoitintaulukkoa: // Esimerkki char-tyyppisen osoitintaulukon käyttö #include <iostream> using namespace std; int main() 241

12 C++ Ohjelmoijan käsikirja const char* ptahdet[] = "Mae West", // Alustetaan osoitintaulukko "Arnold Schwarzenegger", "Lassie", "Slim Pickens", "Greta Garbo", "Oliver Hardy" ; const char* ptahti = "Tähtinäyttelijäsi on "; int valinta = 0; const int tahtilkm = sizeof ptahdet / sizeof ptahdet[0]; // Taulukon koko cout << endl << "Valitse tähtinäyttelijäsi!" << " Syötä numero väliltä 1 - " << tahtilkm << ": "; cin >> valinta; cout << endl; if(valinta >= 1 && valinta <= tahtilkm) // Tarkistetaan syöte cout << ptahti << ptahdet[valinta - 1]; // Tulostetaan tähden nimi else cout << "Valitan, tähtinäyttelijääsi ei löydy."; // Kielletty syöte cout << endl; return 0; Kuinka se toimii Tämän paremmaksi tätä ohjelmaa ei juuri enää saa. Käytössämme on yksiulotteinen taulukko char-osoittimia esiteltynä siten, että kääntäjä päättelee alkuarvoluettelon perusteella, minkä kokoinen taulukon tulee olla: const char* ptahdet[] = "Mae West", // Alustetaan osoitintaulukko "Arnold Schwarzenegger", "Lassie", "Slim Pickens", "Greta Garbo", "Oliver Hardy" ; 242

13 Osoittimet Tämän lauseen jälkeen muistin käyttö näkyy alla olevasta kaaviosta: M a e W e s t \0 9 tavua Osoitintaulukko A r n o l d S c h w a r z e n e g g e r \0 22 tavua L a s s i e \0 7 tavua S l i m P i c k e n s \0 13 tavua Kukin osoitintaulukon alkio on saman kokoinen - yleensä 4 tavua - joten tämän taulukon koko on 24 tavua. G r e t a G a r b o \0 O l i v e r H a r d y \0 Muistin kokonaiskulutus on 99 tavua. 11 tavua 13 tavua Kuten huomaat, muistia tarvitaan jokaiselle null-merkkiin päättyvälle merkkijonolle sekä taulukon alkioille, jotka ovat osoittimia. Eli yhteensä 99 tavua. Verrattuna char-tyyppiseen taulukkoon, osoitintaulukko tarvitsee vähemmän muistia. Vanhassa staattisessa taulukossa jokaisen rivin pituus on vähintään pisimmän merkkijonon pituus; 6 riviä, jokainen 22 tavua, on yhteensä 132 tavua. Osoitintaulukon avulla säästimme 33 tavua. Säästö riippuu tietysti merkkijonojen lukumäärästä ja pituuksien erilaisuuksista. Joskus säästöä ei synny lainkaan, mutta yleisesti ottaen osoitintaulukko on tehokkaampi. Tilan säästö ei ole ainut hyöty, jonka saat osoittimien käytöstä. Monissa tapauksissa säästät myös suoritusajassa. Mieti esimerkiksi, mitä tapahtuu, jos haluat vaihtaa viidennessä alkiossa olevan merkkijonon Greta Garbo ensimmäisessä alkiossa olevaan merkkijonoon Mae West. Tämä on tyypillinen lajitteluoperaatio, jossa lajittelet merkkijonot aakkosjärjestykseen. Yllä olevassa osoitintoteutuksessa sinun täytyy ainoastaan vaihtaa osoittimet keskenään - merkkijonot voivat sijaita siellä missä ennenkin. Jos merkkijonot olisi talletettu char-tyyppiseen taulukkoon, tarvittaisiin suuri kopiointioperaatio. Koko merkkijono Greta Garbo tulisi kopioida väliaikaiseen muistipaikkaan, kun Mae West kopioidaan sen tilalle. Tämän jälkeen Greta Garbo tulisi kopioida uuteen paikkaan. Tämä vaatii huomattavasti enemmän suoritusaikaa. Tämä logiikka pätee yhtä hyvin string-tyyppisiin olioihinkin. Palataan takaisin esimerkkiimme. Talletamme perusviestin osoitteen toiseen osoittimeen: const char* ptahti = "Tähtinäyttelijäsi on "; Tämän jälkeen laskemme osoitintaulukon ptahdet alkioiden lukumäärän seuraavalla lauseella: const int tahtilkm = sizeof ptahdet / sizeof ptahdet[0]; // Taulukon koko Kun taulukon koko lasketaan tällä tavalla, ohjelman loppuosa käyttää automaattisesti oikeaa taulukon kokoa. Käytämme tätä taulukon kokoa pyytäessämme syötettä, joka talletetaan muuttujaan valinta: 243

14 C++ Ohjelmoijan käsikirja cout << endl << "Valitse tähtinäyttelijäsi!" << " Syötä numero väliltä 1 - " << tahtilkm << ": "; Luettuamme muuttujan valinta arvon samaan tapaan kuin edellisessä esimerkissämmekin, valitsemme tulostettavan merkkijonon yksinkertaisella if-lauseella. Tulostamme joko valitun merkkijonon taulukosta ptahdet tai sopivan viestin, että käyttäjä syötti kielletyn valinnan. iflauseessa käytetään muuttujaa tahtilkm valinnan ylärajana, eli nytkin ohjelma mukautuu automaattisesti valittavien tähtien lukumäärään. Jos haluat ohjelmaan enemmän valintoja, voit yksinkertaisesti lisätä niitä alkuarvoluetteloon. Merkkijonojen lajittelu osoittimien avulla Kuten edellisen esimerkin läpikäynnissä mainitsimme, voit lajitella merkkijonoja ilman, että itse merkkijonoja täytyy siirtää paikasta toiseen, jos käytät niihin osoittavia osoittimia. Voimme tehdä uuden version esimerkin 6.10 ohjelmasta, jossa otimme sanoja merkkijonosta. Tämä antaa meille arvokasta kokemusta string-tyyppisten olioiden käsittelystä ja stringtyyppisiin olioihin osoittavista osoitintaulukoista. Samalla saamme käytännön kokemusta lajittelusta osoittimien avulla. Kokeile itse - Merkkijonojen lajittelu osoittimien avulla Luemme näppäimistöltä merkkijonon ja lajittelemme sen sanat haluamaamme järjestykseen. Tässä on koodi: // Esimerkki Merkkijonojen lajittelu osoittimien avulla #include <iostream> #include <string> using namespace std; int main() string teksti; const string erottimet = ",.\"\n"; const int max_sanoja = 1000; string sanat[max_sanoja]; string* psanat[max_sanoja]; // Lajiteltava merkkijono // Sanojen erotinmerkit // Sanojen maksimimäärä // Sanojen taulukko // osoitintaulukko sanoihin // Luetaan merkkijono näppäimistöltä cout << endl << "Syötä merkkijono, # lopettaa:" << endl; getline(cin, teksti, '#'); 244 // Otetaan tekstin kaikki sanat erilleen int alku = teksti.find_first_not_of(erottimet);// Sanan alkuindeksi int loppu = 0; // Loppuerotinmerkin indeksi int sanalkm = 0; // Sanojen lukumäärä while(alku!= string::npos && sanalkm < max_sanoja) loppu = teksti.find_first_of(erottimet, alku + 1);

15 Osoittimet if(loppu == string::npos) loppu = teksti.length(); // Löytyikö erotinmerkki? // Ei löytynyt sanat[sanalkm] = teksti.substr(alku, loppu - alku); // Talletetaan sana psanat[sanalkm] = &sanat[sanalkm]; // Talletetaan osoitin sanalkm++; // kasvatetaan lukumäärää // Etsitään seuraavan sanan ensimmäinen merkki alku = teksti.find_first_not_of(erottimet, loppu + 1); // lajitellaan sanat nousevaan järjestykseen suoralla osoituksella int pienin = 0; // Pienimmän sanan indeksi for(int j = 0; j < sanalkm - 1; j++) pienin = j; // Asetetaan pienin // Tarkistetaan nyk sana kaikkiin muihin sen jäljessä oleviin for(int i = j + 1 ; i < sanalkm ; i++) if(*psanat[i] < *psanat[pienin]) // Nykyinen on pienin? pienin = i; if(pienin!= j) // Vaihdetaan osoittimet string* papu = psanat[j]; // Talletetaan nykyinen psanat[j] = psanat[pienin]; // Pienin nykyiseen psanat[pienin] = papu; // Palautetaan nykyinen // Tulostetaan sanat nousevassa järjestyksessä for(int i = 0 ; i < sanalkm ; i++) cout << endl << *psanat[i]; cout << endl; return 0; Ohjelman esimerkkitulostus näyttää seuraavalta: Syötä merkkijono, # lopettaa: Tässä maailmassa mikään ei ole niin varmaa kuin kuolema ja verot.# Tässä ei ja kuin kuolema maailmassa mikään niin ole varmaa verot 245

16 C++ Ohjelmoijan käsikirja Kuinka se toimii Merkkijono, jonka sanat lajitellaan, luetaan muuttujaan, joka esitellään seuraavasti: string teksti; // Lajiteltava merkkijono const string erottimet = ",.\"\n"; // Sanojen erotinmerkit Vakio erottimet sisältää kaikki merkit, jotka toimivat sanojen erotinmerkkeinä; eli merkit välilyönti, pilkku, piste, lainausmerkki ja rivinvaihto. Voit lisätä tähän listaan sarkainmerkin, jos haluat. Vaihtoehtoisesti voisit rakentaa erottimien merkkijonon etsimällä merkkijonosta teksti kaikki merkit, jotka eivät ole kirjaimia, numeroita tai heittomerkkejä. Talletamme merkkijonosta teksti irrottamamme sanat taulukkoon, johon mahtuu maksimissaan 1000 sanaa: const int max_sanoja = 1000; // Sanojen maksimimäärä string sanat[max_sanoja]; // Sanojen taulukko string* psanat[max_sanoja]; // osoitintaulukko sanoihin Taulukkoon sanat talletetaan sanat ja osoitintaulukkoon psanat talletetaan sanat-taulukon kunkin alkion osoitteet. Tämä kuulostaa hankalalta, mutta tarvitsemme osoittimet, jos haluamme välttää merkkijonojen toistuvat kopioinnit, kun lajittelemme ne. Meidän täytyy lisäksi varata tilaa max_sanoja string-tyyppiselle oliolle ja osoittimelle, vaikka emme niitä oikeastaan tarvitsekaan. Myöhemmin tässä luvussa käsittelemme parempaa tapaa tehdä tämä, käyttäen dynaamista muistinvarausta. Luemme tarvittaessa useamman rivin tekstiä merkkijonoon teksti samaan tapaan kuin aikaisemminkin; syöttö lopetetaan #-merkillä, joten voit syöttää niin monta riviä kuin haluat: cout << endl << "Syötä merkkijono, # lopettaa:" << endl; getline(cin, teksti, '#'); Yksittäisten sanojen irrottaminen merkkijonosta teksti ja tallettaminen taulukkoon sanat tehdään while-silmukassa: // Otetaan tekstin kaikki sanat erilleen int alku = teksti.find_first_not_of(erottimet); // Sanan alkuindeksi int loppu = 0; // Loppuerotinmerkin indeksi int sanalkm = 0; // Sanojen lukumäärä while(alku!= string::npos && sanalkm < max_sanoja) loppu = teksti.find_first_of(erottimet, alku + 1); if(loppu == string::npos) // Löytyikö erotinmerkki? loppu = teksti.length(); // Ei löytynyt sanat[sanalkm] = teksti.substr(alku, loppu - alku); // Talletetaan sana psanat[sanalkm] = &sanat[sanalkm]; // Talletetaan osoitin sanalkm++; // kasvatetaan lukumäärää 246 // Etsitään seuraavan sanan ensimmäinen merkki alku = teksti.find_first_not_of(erottimet, loppu + 1);

17 Osoittimet Tämä toimii samalla logiikalla kuin viimeksi käsittelimme tämäntapaista ongelmaa. Etsimme sanan ensimmäisen kirjaimen indeksin ja talletamme sen muuttujaan alku. Etsimme sanaa seuraavan ensimmäisen erotinmerkin ja talletamme sen indeksin muuttujaan loppu. Tämän jälkeen käytämme substr()-funktiota irrottamaan sanan string-tyyppisenä oliona, jonka sitten talletamme sanat-taulukon seuraavaan vapaaseen alkioon. Talletamme myös tämän alkion osoitteen taulukon psanat vastaavaan alkioon. Silmukan ehtolauseke varmistaa, että lopetamme sanojen etsinnän, kun olemme saavuttaneet merkkijonon teksti lopun tai kun taulukko sanat täyttyy. Valmistelemme lajittelua esittelemällä muuttujan pienin, joka pitää kirjaa pienimmän sanan indeksistä lajittelun aikana: int pienin = 0; // Pienimmän sanan indeksi Sanojen lajittelu suoritetaan sisäkkäisissä for-silmukoissa: for(int j = 0; j < sanalkm - 1; j++) pienin = j; // Asetetaan pienin // Tarkistetaan nyk sana kaikkiin muihin sen jäljessä oleviin for(int i = j + 1 ; i < sanalkm ; i++) if(*psanat[i] < *psanat[pienin]) // Nykyinen on pienin? pienin = i; if(pienin!= j) // Vaihdetaan osoittimet string* papu = psanat[j]; // Talletetaan nykyinen psanat[j] = psanat[pienin]; // Pienin nykyiseen psanat[pienin] = papu; // Palautetaan nykyinen Operaatio järjestää psanat-taulukon osoittimet uudelleen siten, että ne osoittavat taulukon sanat sanoihin nousevassa järjestyksessä. Tämä tehdään varsin yksinkertaisella tavalla. Ulompi silmukka käy läpi kaikki taulukon psanat alkiot ensimmäisestä viimeiseen. Sisemmässä silmukassa vertaamme kunkin osoittimen osoittamaa sanaa kaikkiin kyseistä osoitinta seuraavien osoittimien osoittamiin sanoihin, jotta löydämme pienimmän indeksin. Jos käsittelemämme sana ei ole pienin, vaihdamme osoittimet käyttämällä osoitinta papu väliaikaisena talletuspaikkana. Tämä prosessi suoritetaan kaikille taulukon psanat alkioille. Tämän jälkeen ensimmäisessä alkiossa on osoitin pienimpään sanaan. Toinen alkio osoittaa seuraavaksi pienempään sanaan ja niin edelleen kaikille taulukkoon talletetuille osoittimille. Huomaa, että tulostuksessa Tässä tulee ennen ei :tä, koska minun tietokoneessani, joka käyttää ASCII-koodeja, merkki T on pienempi kuin e. Lopuksi tulostamme sanat nousevassa järjestyksessä: for(int i = 0 ; i < sanalkm ; i++) cout << endl << *psanat[i]; Taulukon psanat alkiot osoittavat sanoihin nousevassa järjestyksessä. Tulostaaksemme ne järjestyksessä, tulostanne taulukon osoittimien osoittamat sisällöt järjestyksessä. 247

18 C++ Ohjelmoijan käsikirja Tulostuksen ulkoasun parantaminen Yhden sanan tulostaminen yhdelle riville toimii pienen sanamäärän yhteydessä, mutta jos sanoja on paljon, se on varsin epämiellyttävää. Olisi hyvä, jos kaikki sanat, jotka alkavat samalla kirjaimella, tulostettaisiin ryhmänä. Jos haluat hieman monimutkaisemman tulostustavan, voit korvata edellä olleen for-silmukan seuraavalla koodilla: // Tulostetaan max. 6 sanaa samalle riville ryhmiteltynä alkukirjaimen mukaan char ch = (*psanat[0])[0]; // Ensimmäisen sanan ensimmäinen kirjain int sanoja_rivilla = 0; // Sanojen lukumäärä rivillä for(int i = 0; i < sanalkm ; i++) if(ch!= (*psanat[i])[0]) // Uusi ensimmäinen kirjain? cout << endl; // Aloitetaan uusi rivi ch = (*psanat[i])[0]; // Talletetaan uusi ensimmäinen kirjain sanoja_rivilla = 0; // Palautetaan sanojen laskuri cout << *psanat[i] << " "; if(++sanoja_rivilla == 6) // Joka kuudes sana cout << endl; // Aloitetaan uusi rivi sanoja_rivilla = 0; Tämä tulostaa kaikki sanat nousevassa järjestyksessä, mutta nyt kaikki sanat, jotka alkavat samalla kirjaimella, ryhmitellään yhteen ryhmään. Jokainen uusi ryhmä alkaa uudelta riviltä ja rivillä voi olla maksimissaan kuusi sanaa. Ryhmän ensimmäinen kirjain talletetaan muuttujaan ch. Huomaa, kuinka viittaamme ensimmäisen string-tyyppisen olion ensimmäiseen kirjaimeen. Lausekkeen *psanat[0] arvo on taulukon psanat ensimmäisen alkion osoittama sana. Lauseke (*psanat[0])[0] antaa sitten tämän sanan ensimmäisen kirjaimen, koska sulkeiden ulkopuolella olevat toiset hakasulkeet ovat sanan kirjaimia varten. Hakasulkeet ovat suoritusjärjestyksessä *-operaattorin edellä, joten sulkeet ovat tässä välttämättömät. Muuttuja sanoja_rivilla pitää kirjaa rivillä olevien sanojen lukumäärästä; kun se saavuttaa arvon 6, tulostetaan rivinvaihto. Jos tulostettavan sanan ensimmäinen kirjain on eri kuin muuttujan ch sisältö, aloitamme uuden ryhmän, joten tulostamme rivinvaihdon ja muuttujan sanoja_rivilla arvoksi palautetaan Osoitinvakiot ja osoittimet vakioihin Kun käsittelimme char-tyyppisiä osoittimia aikaisemmin tässä luvussa käsitellessämme merkkijonoliteraaleja näimme, että osoittimet vakioihin on tekniikka, johon C++:n standardi pakotti. Tähtinäyttelijät-ohjelmassamme varmistimme, että kääntäjä huomaa kaikki yritykset muuttaa taulukon ptahdet alkioiden osoittamia merkkijonoja, koska esittelimme taulukon const-tyyppisenä: const char* ptahdet[] = "Mae West", "Arnold Schwarzenegger", "Lassie", "Slim Pickens",

19 Osoittimet "Greta Garbo", "Oliver Hardy" ; Tässä esittelyssä esittelemme osoitintaulukon osoittamat oliot vakioiksi. Kääntäjä estää kaikki yritykset muuttaa niitä, joten seuraavanlainen sijoituslause aiheuttaa virheen kääntäjässä ja estää ikävän ongelman suoritusaikana: *ptahdet[0] = X ; Voimme kuitenkin aivan hyvin kirjoittaa seuraavan lauseen, joka kopioi sijoitusoperaattorin oikealla puolella olevan alkion osoitteen vasemmalla puolella olevaan alkioon: ptahdet[0] = ptahdet[5]; Nyt molemmat osoittimet osoittavat samaan nimeen. Huomaa, että tämä ei muuttanut osoitintaulukon alkion osoittaman olion sisältöä - se muutti vain alkion ptahdet[0] sisältämää osoitetta, eli const-määrettä ei tässä rikottu. Meidän pitäisi kyllä estää myös tällainen muutos. Katso seuraavaa lausetta: const char* const ptahdet[] = "Mae West", "Arnold Schwarzenegger", "Lassie", "Slim Pickens", "Greta Garbo", "Oliver Hardy" ; Uusi const-määre esittelee osoitinvakion, joten nyt sekä osoittimet että niiden osoittamat merkkijonot ovat vakioita. Kumpaakaan niistä ei voida muuttaa. Yhteenvetona voimme muodostaa kolme erilaista tilannetta const-määreen käytöstä osoittimien ja niiden osoittamien asioiden yhteydessä: Osoitin vakioon. Tässä sitä mihin osoitetaan, ei voida muuttaa, mutta voimme asettaa osoittimen osoittamaan johonkin muuhun: const char* pmerkkijono = Tekstiä, jota ei voi muuttaa ; Tämä pätee tietysti myös muuntyyppisiin osoittimiin. Esimerkiksi: const int arvo = 20; const int* parvo = &arvo; arvo on vakio, eikä sitä voi muuttaa. parvo on osoitin vakioon, joten siihen voidaan sijoittaa muuttujan arvo osoite. Et voisi sijoittaa osoitetta osoittimeen, joka ei ole osoitin vakioon (koska tällöin voisit muuttaa vakiota osoittimen kautta), mutta voit sijoittaa ei-vakiomuuttujan osoitteen osoittimeen parvo. Jälkimmäisessä tapauksessa muuttujan muokkaus osoittimen kautta ei olisi sallittua. Yleisesti ottaen const-tason kasvattaminen tällä tavalla on aina mahdollista, mutta pienentäminen ei ole mahdollista. 249

20 C++ Ohjelmoijan käsikirja Osoitinvakio. Tässä osoittimeen sijoitettua osoitetta ei voida muuttaa, joten tällainen osoitin voi osoittaa vain siihen osoitteeseen, johon se alustettiin. Osoittimen osoittaman muistipaikan sisältö ei kuitenkaan ole vakio ja sitä voidaan muuttaa. Otetaan numeerinen esimerkki, joka selventää osoitinvakioita. Oletetaan, että esittelemme kokonaislukumuuttujan arvo ja osoitinvakion parvo seuraavasti: int arvo = 20; int* const parvo = &arvo; Tämä esittelee osoittimen parvo const-tyyppiseksi, joten se ei voi osoittaa muuhun kuin muuttujaan arvo. Kaikki yritykset muuttaa osoitin osoittamaan johonkin toiseen int-tyyppiseen muuttujaan saa aikaan kääntäjän virheilmoituksen. Muuttujan arvo sisältö ei ole vakio, joten voit muuttaa sisältöä aina halutessasi. Jos olisit esitellyt muuttujan arvo const-tyyppiseksi, et olisi voinut sijoittaa sen osoitetta osoittimeen parvo. Osoitin parvo voi osoittaa vain muuhun kuin vakiotyyppiseen int-muuttujaan. Osoitinvakio vakioon. Tässä sekä osoittimeen sijoitettu osoite, että osoitettu asia ovat vakioita, joten niitä ei voida kumpaakaan muuttaa. Tarkastellaan numeerista esimerkkiä. Esittelemme muuttujan arvo seuraavasti: const int arvo = 20; arvo on nyt vakio: et voi muuttaa sen arvoa. Voimme silti alustaa osoittimen sen osoitteella: const int* const parvo = &arvo; parvo on osoitinvakio vakioon. Et voi muuttaa sitä, mihin parvo osoittaa, etkä voi muuttaa osoitetun muistipaikan sisältöä. Luonnollisesti tämä toiminnallisuus ei ole vain char- ja int-tyyppien ominaisuus. Tämä pätee kaiken tyyppisille osoittimille. 250 Osoittimet ja taulukot Osoittimien ja taulukon nimien välillä on läheinen yhteys. Itse asiassa monissa tilanteissa voit käyttää taulukon nimeä aivan kuin se olisi osoitin. Jos palaamme takaisin lukuun 6 ja sovellamme nyt tullutta uutta asiaa, huomaamme, että taulukon nimi voi toimia osoittimen tapaan, kun sitä käytetään tulostuslauseessa. Jos yrität tulostaa taulukon sen pelkän nimen avulla (ja jos kyseessä ei ole char-tyyppinen taulukko), tulostuukin taulukon muistipaikan heksadesimaalinen osoite. Koska taulukon nimi toimii näin osoittimen tapaan, voit käyttää sitä osoittimen alustuksessa. Esimerkiksi: double arvot[10]; double* parvo = arvot; Tämä sijoittaa taulukon arvot osoitteen osoittimeen parvo. Haluan kuitenkin nyt muistuttaa, että taulukon nimi ja osoitin ovat varsin erilaisia olioita ja sinun tulee muistaa se. Kaikkein tärkein ero osoittimen ja taulukon nimen välillä on se, että voit muuttaa osoittimen osoitetta, mutta osoite, johon taulukon nimi viittaa, on kiinteä.

21 Osoitinlaskenta Osoittimet Voit suorittaa operaatioita osoittimella, jos haluat muuttaa sen sisältämää osoitetta. Käytössäsi on kuitenkin vain lisäys- ja vähennysoperaattorit, mutta voit myös vertailla osoittimia, jolloin lopputuloksena on totuusarvo. Lisäyksen kohdalla voit lisätä kokonaislukuarvon (tai lausekkeen, joka voidaan muuntaa kokonaisluvuksi) osoittimeen. Lisäyksen tuloksena on osoite. Voit myös vähentää kokonaisluvun osoittimesta ja tuloksena on jälleen osoite. Voit myös laskea kahden osoittimen erotuksen ja tällöin tuloksena on kokonaisluku, ei osoite. Mitkään muut operaattorit eivät ole sallittuja osoittimille. Osoitinlaskenta toimii erikoisella tavalla. Oletetaan, että lisäät arvon 1 osoittimeen: parvo++; Tämä kasvattaa osoitinta yhdellä. Se miten tarkalleen ottaen kasvatat osoittimen arvoa yhdellä, ei ole väliä - voit käyttää sijoitusoperaattoria tai +=-operaattoria, joten seuraavan lauseen tulos on sama kuin äskeisen lauseen: parvo += 1; Mielenkiintoinen asia on kuitenkin se, että osoittimeen sijoitettua osoitetta ei kasvateta yhdellä tavallisen laskennan tapaan. Osoitinlaskenta olettaa automaattisesti, että osoitin osoittaa taulukkoon ja että operaatio suoritetaan osoittimen sisältämälle osoitteelle. Kääntäjä tietää taulukon kunkin alkion koon ja luvun 1 lisääminen osoittimeen kasvattaa osoittimessa olevaa osoitetta alkion koon mukaan. Toisin sanoen luvun 1 lisääminen osoittimeen siirtää sen osoittamaan taulukon seuraavaan alkioon. Esimerkiksi, jos parvo on osoitin double-tyyppiseen tietoon, kuten viimeisimmässä esittelyssämme ja kääntäjä varaa 8 tavua double-tyyppiselle muuttujalle, osoittimen parvo sisältämää osoitetta kasvatetaan kahdeksalla. Tätä havainnollistetaan alla olevassa kaaviossa. double arvot[10]; Taulukko arvot - Heksadesimaaliset muistiosoitteet arvot[0] arvot[1] arvot[2] parvo parvo+1 parvo+2 (1000) (1008) (1010) arvot[3] arvot[4] ja niin edelleen Kunkin alkion pituudeksi oletetaan 8 tavua double *parvo = arvot; 1000 parvo 251

22 C++ Ohjelmoijan käsikirja Kuten kaaviosta näkyy, osoittimen parvo arvo alkaa taulukon ensimmäisen alkion osoitteesta. Luvun 1 lisääminen osoittimeen parvo kasvattaa sen sisältämää osoitetta kahdeksalla, joten tuloksena on taulukon seuraava alkio. Tästä seuraa se, että luvun 2 lisääminen osoittimeen siirtää osoitinta kaksi alkiota eteenpäin. Osoittimen parvo ei tietystikään tarvitse osoittaa taulukon alkuun. Voimme sijoittaa taulukon kolmannen alkion osoitteen osoittimeen lauseella: parvo = &arvot[2]; Tästä seuraa se, että lausekkeen parvo + 1 arvo on arvot[3]:n osoite, taulukon arvot neljäs alkio. Saamme osoittimen osoittamaan tähän alkioon suoraan kirjoittamalla: parvo += 1; Tämä lause kasvattaa osoittimessa parvo olevaa osoitetta taulukon arvot yhden alkion viemän muistimäärän verran. Yleisesti ottaen, lausekkeen parvo + n, jossa n voi olla mikä tahansa lauseke, jonka tulos on kokonaisluku, tulos on sama kuin osoittimen parvo sisältämään osoitteeseen lisätään n * sizeof(double), koska parvo on esitelty osoittimeksi double-tyyppiseen tietoon. Sama logiikka soveltuu myös kokonaisluvun vähentämiseen osoittimesta. Jos parvo sisältää osoitteen arvot[2], lausekkeen parvo - 2 tulos on taulukon ensimmäisen alkion osoite, arvot[0]. Toisin sanoen, osoittimen arvon lisäys ja vähennys tapahtuvat osoitettavan olion mukaan. longtyyppisen osoittimen arvon kasvattaminen yhdellä muuttaa sen sisällön seuraavaan longosoitteeseen, eli osoitetta kasvatetaan sizeof(long) tavua. Osoittimen arvon vähentäminen yhdellä vähentää osoitetta sizeof(long) tavua. Osoitinlaskennan tuloksena oleva osoite voi olla väliltä taulukon ensimmäisen alkion osoite ja taulukon viimeinen osoite + 1. Näiden rajojen ulkopuolella osoittimen toiminta on määrittelemätöntä. Luonnollisestikin voit käyttää osoitinlaskennalla muuttamaasi osoitinta epäsuorassa viittauksessa (muutenhan koko touhussa ei olisi mitään mieltä!). Oletetaan esimerkiksi, että parvo osoittaa yhä alkioon arvot[2], lause *(parvo + 1) = *(parvo + 2); on sama kuin arvot[3] = arvot[4]; Jos haluat käyttää osoitinta epäsuorassa viittauksessa osoitteen muuttamisen jälkeen, sulkeet ovat pakolliset, koska viittausoperaattori on suoritusjärjestyksessä ennen + ja - -operaattoreita. Jos kirjoitat lausekkeen muodossa *parvo + 1, etkä *(parvo + 1), lisätään yksi osoittimen parvo sisältämän muistipaikan sisältöön, mikä on sama kuin arvot[2] + 1. Lisäksi koska tulos on numeerinen arvo, joka ei ole osoite, sen käyttö sijoitusoperaattorin vasemmalla puolella saisi aikaan kääntäjän virheilmoituksen. 252

23 Osoittimet Muista, että lauseke parvo + 1 ei muuta parvo:n sisältämää osoitetta. Se on pelkästään lauseke, jonka arvo on saman tyyppinen kuin parvo. Tässä tapauksessa sen arvo on osoittimen parvo osoittamaa alkiota seuraavan alkion osoite. Luonnollisestikin, jos osoitin sisältää kielletyn osoitteen (esimerkiksi siihen liittyvän taulukon rajojen ulkopuolella olevan osoitteen), ja talletat arvon käyttämällä tätä osoitinta, yrität kirjoittaa kyseiseen muistipaikkaan. Tämä yleensä johtaa tuhoon; ohjelmasi suoritus päättyy tavalla tai toisella. Voi olla, ettei ole niin itsestään selvää, että ongelman aiheutti osoittimen väärä käyttö. Kahden osoittimen välisen eron laskeminen Voit vähentää osoittimen toisesta osoittimesta, mutta sillä on merkitystä vain, jos ne ovat samaa tyyppiä ja osoittavat samaan taulukkoon. Oletetaan, että meillä on yksiulotteinen long-tyyppinen taulukko numerot, joka on esitelty seuraavasti: long numerot[] = 10L, 20, 30, 40, 50, 60, 70, 80; Voimme esitellä ja alustaa kaksi osoitinmuuttujaa: long *pnumero1 = &numerot[6]; long *pnumero2 = &numerot[1]; //Osoittaa taulukon seitsemänteen alkioon //Osoittaa taulukon ensimmäiseen alkioon Nyt voimme laskea näiden kahden osoittimen välisen eron: int ero = pnum1 - pnum2; //Tulos on 5 Muuttujan ero arvoksi tulee 5, koska osoitteiden välinen ero lasketaan alkioissa, ei osoitteissa. Osoitinmuodon käyttö taulukon nimen yhteydessä Voimme käyttää taulukon nimeä osoittimien tapaan käsitellessämme taulukon alkioita. Meillä on yksiulotteinen taulukko esitelty seuraavasti: long data[5]; Voimme nyt osoitinmuodossa viitata alkioon data[3] lausekkeella *(data + 3). Tätä muotoa voidaan soveltaa myös yleisesti, eli viitatessamme alkioihin data[0], data[1], data[2],..., voimme kirjoittaa *data, *(data + 1), *(data + 2) ja niin edelleen. Taulukon nimi sellaisenaan viittaa taulukon alkuosoitteeseen, joten lausekkeen data + 2 tulos on osoite ensimmäisestä alkiosta kaksi eteenpäin. Voit käyttää osoitinmuotoa taulukon nimen yhteydessä aivan samaan tapaan kuin käytät indeksimuotoakin - lausekkeissa tai sijoitusoperaattorin vasemmalla puolella. Voit sijoittaa taulukon data arvoiksi parilliset kokonaisluvut seuraavalla lauseella: for(int i = 0 ; i < 5 ; i++) *(data + i) = 2 * (i + 1); *(data + i) viittaa taulukon peräkkäisiin alkioihin. *(data + 0) vastaa alkiota data[0], *(data + 1) vastaa alkiota data[1] ja niin edelleen. Silmukka sijoittaa taulukon alkioihin arvot 2, 4, 6, 8 ja

24 C++ Ohjelmoijan käsikirja Jos nyt haluaisit laskea taulukon alkiot yhteen, voit kirjoittaa: long summa = 0; for(int i = 0 ; i < 5 ; i++) summa += *(data + i); Kokeillaan joitakin edellä mainittuja tekniikoita esimerkin avulla. Kokeile itse - Taulukon nimet osoittimina Koska olemme jo kokeilleet osoittimia merkkijonojen yhteydessä, kokeillaan nyt taulukon käsittelyä numeerisessa ohjelmassa, joka laskee alkulukuja (alkuluku on luku, joka on jaollinen vain itsellään ja luvulla 1). // Esimerkki Alkulukujen laskenta #include <iostream> #include <iomanip> using namespace std; int main() const int max = 100; long alkuluvut[max] = 2, 3, 5; int lkm = 3; long koe = 5; bool onalkuluku = true; do koe += 2; int i = 0; // Alkulukujen haluttu määrä // Ensimmäiset kolme alkulukua // Laskettujen alkulukujen lukumäärä // Alkulukukandidaatti // Alkuluku on löydetty // Seuraava tarkistettava arvo // Alkulukutaulukon indeksi // Yritetään jakaa kandidaatti kaikilla löydetyillä alkuluvuilla do onalkuluku = koe % *(alkuluvut + i) > 0; // False jos jaollinen while(++i < lkm && onalkuluku); if(onalkuluku) *(alkuluvut + lkm++) = koe; while(lkm < max); // Alkuluku löytyi... //...talletetaan se alkulukuihin // Tulostetaan viisi alkulukua riville for(int i = 0 ; i < max ; i++) if(i % 5 == 0) cout << endl; cout << setw(10) << *(alkuluvut + i); cout << endl; return 0; // Rivinvaihto 1. riville ja joka 5. jälkeen 254

25 Osoittimet Ohjelman tulostus on: Kuinka se toimii Käytämme normaaleja #include-esikääntäjäkomentoja sisällyttämään otsikkotiedoston iostream syöttöä ja tulostusta varten sekä otsikkotiedoston iomanip tulostuksen muokkausfunktiota varten. Käytämme vakiota max määrittelemään haluamiemme alkulukujen lukumäärän: const int max = 100; // Alkulukujen haluttu määrä long alkuluvut[max] = 2, 3, 5; // Ensimmäiset kolme alkulukua int lkm = 3; // Laskettujen alkulukujen lukumäärä Alkuluvut tallettavassa taulukossa alkuluvut on kolme ensimmäistä alkulukua jo alustettu. Näin saamme laskennan mukavasti käyntiin. Muuttuja lkm pitää kirjaa löydettyjen alkulukujen lukumäärästä, joten sen arvoksi on alustettu 3. Alkulukujen testauksessa käytetään seuraavissa lauseissa esiteltyjä muuttujia: long koe = 5; bool onalkuluku = true; // Alkulukukandidaatti // Alkuluku on löydetty Muuttuja koe sisältää seuraavaksi testattavan alkulukukandidaatin, joten sen alkuarvoksi asetetaan arvo 5. Boolean-tyyppinen muuttuja onalkuluku on lippu, jota käytämme ilmaisemaan, että muuttujan koe arvo on alkuluku. Kaikki työ tehdään kahdessa silmukassa: ulompi do-while -silmukka valitsee seuraavaksi tarkistettavan kandidaatin ja lisää sen taulukkoon alkuluvut, jos se oli alkuluku. Sisempi silmukka tarkistaa onko kandidaatti alkuluku vai ei. Ulompaa silmukkaa suoritetaan niin kauan, että taulukko alkuluvut on täynnä. Ennen kuin sisempi silmukka suoritetaan, muuttujaan koe sijoitetaan seuraavaksi tarkistettava kandidaatti lauseella: koe += 2; // Seuraava tarkistettava arvo 255

Osoitin ja viittaus C++:ssa

Osoitin ja viittaus C++:ssa Osoitin ja viittaus C++:ssa Osoitin yksinkertaiseen tietotyyppiin Osoitin on muuttuja, joka sisältää jonkin toisen samantyyppisen muuttujan osoitteen. Ohessa on esimerkkiohjelma, jossa määritellään kokonaislukumuuttuja

Lisätiedot

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset

815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 5 Vastaukset Harjoituksen aiheena ovat aliohjelmat ja abstraktit tietotyypit sekä olio-ohjelmointi. Tehtävät tehdään C-, C++- ja Java-kielillä.

Lisätiedot

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet Tunnus, varattu sana, kommentti Muuttuja, alkeistietotyyppi, merkkijono, Vakio Tiedon merkkipohjainen tulostaminen Ohjelmointi (ict1tx006) Tunnus (5.3) Javan tunnus Java-kirjain Java-numero

Lisätiedot

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

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

Lisätiedot

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin. 2. Ohjausrakenteet Ohjausrakenteiden avulla ohjataan ohjelman suoritusta. peräkkäisyys valinta toisto Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet

Lisätiedot

Muuttujien roolit Kiintoarvo cin >> r;

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

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

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

Lisätiedot

Java-kielen perusteet

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

Lisätiedot

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

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

Lisätiedot

Mallit standardi mallikirjasto parametroitu tyyppi

Mallit standardi mallikirjasto parametroitu tyyppi Mallit 18 Mallit Malli on tehokas mekanismi uusien luokkien generoimiseksi automaattisesti. Standardikirjaston suuri osa, standardi mallikirjasto, rakentuu kokonaan mallien määrittelymahdollisuuden ympärille,

Lisätiedot

Ohjelmoinnin peruskurssi Y1

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

Lisätiedot

Ohjelmointi 1 Taulukot ja merkkijonot

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

Lisätiedot

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus?

11. oppitunti III. Viittaukset. Osa. Mikä on viittaus? Osa III 11. oppitunti Viittaukset Kahdessa viime luvussa opit käyttämään osoittimia kohteiden käsittelyyn vapaalla muistialueella sekä viittaamaan noihin kohteisiin epäsuorasti. Tässä luvussa käsiteltävät

Lisätiedot

Tietotyypit ja operaattorit

Tietotyypit ja operaattorit Tietotyypit ja operaattorit Luennossa tarkastellaan yksinkertaisten tietotyyppien int, double ja char muunnoksia tyypistä toiseen sekä esitellään uusia operaatioita. Numeeriset tietotyypit ja muunnos Merkkitieto

Lisätiedot

Harjoitustyö: virtuaalikone

Harjoitustyö: virtuaalikone Harjoitustyö: virtuaalikone Toteuta alla kuvattu virtuaalikone yksinkertaiselle olio-orientoituneelle skriptauskielelle. Paketissa on testaamista varten mukana kaksi lyhyttä ohjelmaa. Ohjeita Noudata ohjelman

Lisätiedot

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

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

Lisätiedot

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

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

Lisätiedot

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

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

Lisätiedot

Johdatus Ohjelmointiin

Johdatus Ohjelmointiin Johdatus Ohjelmointiin Syksy 2006 Viikko 2 13.9. - 14.9. Tällä viikolla käsiteltävät asiat Peruskäsitteitä Kiintoarvot Tiedon tulostus Yksinkertaiset laskutoimitukset Muuttujat Tiedon syöttäminen Hyvin

Lisätiedot

Sisällys. 11. Javan toistorakenteet. Laskurimuuttujat. Yleistä

Sisällys. 11. Javan toistorakenteet. Laskurimuuttujat. Yleistä Sisällys 11. Javan toistorakenteet Laskuri- ja lippumuuttujat.. Tyypillisiä ohjelmointivirheitä: Silmukan rajat asetettu kierroksen verran väärin. Ikuinen silmukka. Silmukoinnin lopettaminen break-lauseella.

Lisätiedot

Osa. Toimintojen toteuttaminen ohjelmissa vaatii usein haarautumisia ja silmukoita. Tässä luvussa tutustummekin seuraaviin asioihin:

Osa. Toimintojen toteuttaminen ohjelmissa vaatii usein haarautumisia ja silmukoita. Tässä luvussa tutustummekin seuraaviin asioihin: Osa II 8. oppitunti Kehittynyt ohjel- man kulku Toimintojen toteuttaminen ohjelmissa vaatii usein haarautumisia ja silmukoita. Tässä luvussa tutustummekin seuraaviin asioihin: Mitä silmukat ovat ja kuinka

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

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

Lisätiedot

Luokat. Luokat ja olio-ohjelmointi

Luokat. Luokat ja olio-ohjelmointi Luokat 12 Luokat Tässä luvussa laajennamme edellisessä luvussa käsittelemäämme struktuurityyppiä ja siirrymme yhteen C++-ohjelmoijan kaikkein tärkeimmistä välineistä: luokkiin. Käsittelemme myöskin joitakin

Lisätiedot

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille:

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille: Merkkijonot C-kielessä merkkijono on taulukko, jonka alkiot ovat char -tyyppiä. Taulukon viimeiseksi merkiksi tulee merkki '\0', joka ilmaisee merkkijonon loppumisen. Merkkijono määritellään kuten muutkin

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 1.4.2009 T-106.1208 Ohjelmoinnin perusteet Y 1.4.2009 1 / 56 Tentti Ensimmäinen tenttimahdollisuus on pe 8.5. klo 13:00 17:00 päärakennuksessa. Tämän jälkeen

Lisätiedot

Taulukot. Jukka Harju, Jukka Juslin 2006 1

Taulukot. Jukka Harju, Jukka Juslin 2006 1 Taulukot Jukka Harju, Jukka Juslin 2006 1 Taulukot Taulukot ovat olioita, jotka auttavat organisoimaan suuria määriä tietoa. Käsittelylistalla on: Taulukon tekeminen ja käyttö Rajojen tarkastus ja kapasiteetti

Lisätiedot

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

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

Lisätiedot

Ehto- ja toistolauseet

Ehto- ja toistolauseet Ehto- ja toistolauseet 1 Ehto- ja toistolauseet Uutena asiana opetellaan ohjelmointilauseet / rakenteet, jotka mahdollistavat: Päätösten tekemisen ohjelman suorituksen aikana (esim. kyllä/ei) Samoja lauseiden

Lisätiedot

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

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

Lisätiedot

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

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

Lisätiedot

Tietueet. Tietueiden määrittely

Tietueet. Tietueiden määrittely Tietueet Tietueiden määrittely Tietue on tietorakenne, joka kokoaa yhteen eri tyyppistä tietoa yhdeksi asiakokonaisuudeksi. Tähän kokonaisuuteen voidaan viitata yhteisellä nimellä. Auttaa ohjelmoijaa järjestelemään

Lisätiedot

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

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

Lisätiedot

Sisällys. 3. Muuttujat ja operaatiot. Muuttujat ja operaatiot. Muuttujat. Operaatiot. Imperatiivinen laskenta. Muuttujat. Esimerkkejä: Operaattorit.

Sisällys. 3. Muuttujat ja operaatiot. Muuttujat ja operaatiot. Muuttujat. Operaatiot. Imperatiivinen laskenta. Muuttujat. Esimerkkejä: Operaattorit. 3. Muuttujat ja operaatiot Sisällys Imperatiivinen laskenta. Muuttujat. Nimi ja arvo. Muuttujan nimeäminen. Muuttujan tyyppi.. Operandit. Arvon sijoitus muuttujaan. Aritmeettiset operaattorit. Arvojen

Lisätiedot

Ohjelmointitaito (ict1td002, 12 op) Kevät Java-ohjelmoinnin alkeita. Tietokoneohjelma. Raine Kauppinen

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

Lisätiedot

Ohjelmoinnin perusteet Y Python

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

Lisätiedot

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

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

Lisätiedot

3. Muuttujat ja operaatiot 3.1

3. Muuttujat ja operaatiot 3.1 3. Muuttujat ja operaatiot 3.1 Sisällys Imperatiivinen laskenta. Muuttujat. Nimi ja arvo. Muuttujan nimeäminen. Muuttujan tyyppi. Operaattorit. Operandit. Arvon sijoitus muuttujaan. Aritmeettiset operaattorit.

Lisätiedot

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

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

Lisätiedot

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

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

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 9.2.2009 T-106.1208 Ohjelmoinnin perusteet Y 9.2.2009 1 / 35 Listat Esimerkki: halutaan kirjoittaa ohjelma, joka lukee käyttäjältä 30 lämpötilaa. Kun lämpötilat

Lisätiedot

12 Mallit (Templates)

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

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 15.3.2010 T-106.1208 Ohjelmoinnin perusteet Y 15.3.2010 1 / 56 Tiedostoista: tietojen tallentaminen ohjelman suorituskertojen välillä Monissa sovelluksissa ohjelman

Lisätiedot

Virtuaalifunktiot ja polymorfismi

Virtuaalifunktiot ja polymorfismi Virtuaalifunktiot ja polymorfismi 16 Virtuaalifunktiot ja polymorfismi Polymorfismi on niin tehokas olio-ohjelmoinnin ominaisuus, että tulet varmastikin käyttämään sitä lähes kaikissa C++-ohjelmissasi.

Lisätiedot

Operaattoreiden uudelleenmäärittely

Operaattoreiden uudelleenmäärittely Operaattoreiden uudelleenmäärittely 14 Operaattoreiden uudelleenmäärittely Tässä luvussa käsittelemme, kuinka voit lisätä toiminnallisuutta luokkiisi, jotta ne toimivat enemmän C++:n perustietotyyppien

Lisätiedot

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti: 1 (7) Tiedon lukeminen näppäimistöltä Scanner-luokan avulla Miten ohjelma saa käyttöönsä käyttäjän kirjoittamaa tekstiä? Järjestelmässä on olemassa ns. syöttöpuskuri näppäimistöä varten. Syöttöpuskuri

Lisätiedot

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

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

Lisätiedot

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4) 2. Lisää Java-ohjelmoinnin alkeita Muuttuja ja viittausmuuttuja Vakio ja literaalivakio Sijoituslause Syötteen lukeminen ja Scanner-luokka 1 Muuttuja ja viittausmuuttuja (1/4) Edellä mainittiin, että String-tietotyyppi

Lisätiedot

Java-kielen perusteet

Java-kielen perusteet Java-kielen perusteet String-merkkijonoluokka 1 Ohjelmointikielten merkkijonot Merkkijonot ja niiden käsittely on välttämätöntä ohjelmoinnissa Valitettavasti ohjelmointikielten tekijät eivät tätä ole ottaneet

Lisätiedot

Taulukot ja merkkijonot

Taulukot ja merkkijonot Taulukot ja merkkijonot 6 Taulukot ja merkkijonot Olemme käsitelleet kaikki perustietotyypit ja olemme käsitelleet, miten ohjelmissa suoritetaan laskentaa sekä tehdään päätöksiä. Tämän luvun tarkoituksena

Lisätiedot

Ohjelmointi funktioiden avulla

Ohjelmointi funktioiden avulla Ohjelmointi funktioiden avulla 8 Ohjelmointi funktioiden avulla Ohjelman jakaminen hallittaviin osiin on idea, joka on perustana kaikille ohjelmointikielille. Funktio on kaikkien C++-ohjelmien perusosa.

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

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

Lisätiedot

Kääntäjän virheilmoituksia

Kääntäjän virheilmoituksia OHJ-1101 Ohjelmointi 1e 2008-09 1 Kääntäjän virheilmoituksia Kun progvh2 ohjelma käännetään antaa tutg++ seuraavat virheilmoitukset ja varoitukset: proffa> tutg++ progvh2.cc progvh2.cc:29:13: warning:

Lisätiedot

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

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

Lisätiedot

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

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

Lisätiedot

Valinnat ja päätökset

Valinnat ja päätökset Valinnat ja päätökset 4 Valinnat ja päätökset Päätöksenteko on erittäin tärkeässä asemassa kaikissa ohjelmointikielissä. Jos ohjelman lauseiden suoritusjärjestystä ei voitaisi muuttaa tietojen vertailun

Lisätiedot

Ohjelmoinnin perusteet Y Python

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

Lisätiedot

13 Operaattoreiden ylimäärittelyjä

13 Operaattoreiden ylimäärittelyjä 248 13 C++-kielessä voidaan operaattoreita ylimäärittää. Ylimääriteltävää operaattoria voidaan pitää ikäänkuin metodina, joka esitellään luokan esittelyssä ja määritellään luokan ulkopuolella kuten metoditkin.

Lisätiedot

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

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

Lisätiedot

7. Näytölle tulostaminen 7.1

7. Näytölle tulostaminen 7.1 7. Näytölle tulostaminen 7.1 Sisällys System.out.println- ja System.out.print-operaatiot. Tulostus erikoismerkeillä. Edistyneempää tulosteiden muotoilua. 7.2 Tulostusoperaatiot System.out.println-operaatio

Lisätiedot

Ohjelmoinnin perusteet Y Python

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

Lisätiedot

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

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

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

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

Lisätiedot

Osoittimet ja taulukot

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

Lisätiedot

11. Javan toistorakenteet 11.1

11. Javan toistorakenteet 11.1 11. Javan toistorakenteet 11.1 Sisällys Laskuri- ja lippumuuttujat. Sisäkkäiset silmukat. Tyypillisiä ohjelmointivirheitä: Silmukan rajat asetettu kierroksen verran väärin. Ikuinen silmukka. Silmukoinnin

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

815338A 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ätiedot

Java-kielen perusteita

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

Lisätiedot

Algoritmit 1. Demot Timo Männikkö

Algoritmit 1. Demot Timo Männikkö Algoritmit 1 Demot 1 31.1.-1.2.2018 Timo Männikkö Tehtävä 1 (a) Algoritmi, joka tutkii onko kokonaisluku tasan jaollinen jollain toisella kokonaisluvulla siten, että ei käytetä lainkaan jakolaskuja Jaettava

Lisätiedot

VIII. Osa. Liitteet. Liitteet Suoritusjärjestys Varatut sanat Binääri- ja heksamuoto

VIII. Osa. Liitteet. Liitteet Suoritusjärjestys Varatut sanat Binääri- ja heksamuoto Osa VIII Liitteet Liitteet A B C Suoritusjärjestys Varatut sanat Binääri- ja heksamuoto Osa VIII A. Liite Operaattoreiden suoritusjärjestys On tärkeää ymmärtää, että operaattoreilla on prioriteettinsa,

Lisätiedot

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu Taulukot Taulukon määrittely ja käyttö Taulukko metodin parametrina Taulukon sisällön kopiointi toiseen taulukkoon Taulukon lajittelu esimerkki 2-ulottoisesta taulukosta 1 Mikä on taulukko? Taulukko on

Lisätiedot

Tietuetyypin määrittely toteutetaan C-kielessä struct-rakenteena seuraavalla tavalla:

Tietuetyypin määrittely toteutetaan C-kielessä struct-rakenteena seuraavalla tavalla: KERTAUSTEHTÄVIÄ Tietue Tietuetyypin määrittely toteutetaan C-kielessä struct-rakenteena seuraavalla tavalla: struct henkilotiedot char nimi [20]; int ika; char puh [10]; ; Edellä esitetty kuvaus määrittelee

Lisätiedot

Python-ohjelmointi Harjoitus 2

Python-ohjelmointi Harjoitus 2 Python-ohjelmointi Harjoitus 2 TAVOITTEET Kerrataan tulostuskomento ja lukumuotoisen muuttujan muuttaminen merkkijonoksi. Opitaan jakojäännös eli modulus, vertailuoperaattorit, ehtorakenne jos, input-komento

Lisätiedot

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta 5. 1. Toteuta Pythonilla seuraava ohjelma:

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta 5. 1. Toteuta Pythonilla seuraava ohjelma: Kerta 2 Kerta 3 Kerta 4 Kerta 5 Kerta 2 1. Toteuta Pythonilla seuraava ohjelma: 2. Tulosta Pythonilla seuraavat luvut allekkain a. 0 10 (eli, näyttää tältä: 0 1 2 3 4 5 6 7 8 9 10 b. 0 100 c. 50 100 3.

Lisätiedot

16. Ohjelmoinnin tekniikkaa 16.1

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

Lisätiedot

Ohjelmoinnin perusteet Y Python

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

Lisätiedot

Ohjelman virheet ja poikkeusten käsittely

Ohjelman virheet ja poikkeusten käsittely Ohjelman virheet ja poikkeusten käsittely 17 Ohjelman virheet ja poikkeusten käsittely Poikkeukset ovat tapa ilmoittaa virheistä ja odottamattomista tilanteista C++-ohjelmassasi. Poikkeusten käyttö virheiden

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 4 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 4 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten lauseisiin, lausekkeisiin ja aliohjelmiin liittyvät kysymykset. Tehtävä 1. Mitä

Lisätiedot

Perustietotyypit ja laskutoimitukset

Perustietotyypit ja laskutoimitukset Perustietotyypit ja laskutoimitukset 2 Perustietotyypit ja laskutoimitukset Tässä luvussa käsittelemme C++:n perustietotyyppejä, varsinkin sellaisia kuin sinä mitä todennäköisemmin tulet käyttämään omissa

Lisätiedot

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

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

Lisätiedot

Javan perusteet. Ohjelman tehtävät: tietojen syöttö, lukeminen prosessointi, halutun informaation tulostaminen tulostus tiedon varastointi

Javan perusteet. Ohjelman tehtävät: tietojen syöttö, lukeminen prosessointi, halutun informaation tulostaminen tulostus tiedon varastointi 1 Javan perusteet Ohjelmointi IPO-malli Java lähdekoodista suoritettavaksi ohjelmaksi Vakio Muuttuja Miten Javalla näytetään tietoa käyttäjälle, miten Javalla luetaan käyttäjän antama syöte Miten Javalla

Lisätiedot

Ohjelmointiharjoituksia Arduino-ympäristössä

Ohjelmointiharjoituksia Arduino-ympäristössä Ohjelmointiharjoituksia Arduino-ympäristössä Yleistä Arduino-sovelluksen rakenne Syntaksi ja käytännöt Esimerkki ohjelman rakenteesta Muuttujat ja tietotyypit Tietotyypit Esimerkkejä tietotyypeistä Ehtolauseet

Lisätiedot

16. Ohjelmoinnin tekniikkaa 16.1

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

Lisätiedot

Listarakenne (ArrayList-luokka)

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

Lisätiedot

T740103 Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

T740103 Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010 12. Periytyminen Johdantoa Käytännössä vähänkään laajemmissa ohjelmissa joudutaan laatimaan useita luokkia, joiden pitäisi pystyä välittämään tietoa toisilleen. Ohjelmien ylläpidon kannalta olisi lisäksi

Lisätiedot

Metropolia ammattikorkeakoulu 05.02.2015 TI00AA43-3004: Ohjelmointi Kotitehtävät 3

Metropolia ammattikorkeakoulu 05.02.2015 TI00AA43-3004: Ohjelmointi Kotitehtävät 3 : http://users.metropolia.fi/~pasitr/2014-2015/ti00aa43-3004/kt/03/ratkaisut/ Tehtävä 1. (1 piste) Tee ohjelma K03T01.cpp, jossa ohjelmalle syötetään kokonaisluku. Jos kokonaisluku on positiivinen, niin

Lisätiedot

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

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

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

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

Lisätiedot

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset

815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset 815338A Ohjelmointikielten periaatteet 2014-2015. Harjoitus 7 Vastaukset Harjoituksen aiheena on funktionaalinen ohjelmointi Scheme- ja Haskell-kielillä. Voit suorittaa ohjelmat osoitteessa https://ideone.com/

Lisätiedot

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

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

Lisätiedot

LOAD R1, =2 Sijoitetaan rekisteriin R1 arvo 2. LOAD R1, 100

LOAD R1, =2 Sijoitetaan rekisteriin R1 arvo 2. LOAD R1, 100 Tiedonsiirtokäskyt LOAD LOAD-käsky toimii jälkimmäisestä operandista ensimmäiseen. Ensimmäisen operandin pitää olla rekisteri, toinen voi olla rekisteri, vakio tai muistiosoite (myös muuttujat ovat muistiosoitteita).

Lisätiedot

Tietojen syöttäminen ohjelmalle. Tietojen syöttäminen ohjelmalle Scanner-luokan avulla

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

Tutoriaaliläsnäoloista

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

Lisätiedot

Ohjausrakenteet. Valinta:

Ohjausrakenteet. Valinta: Ohjausrakenteet Luento antaa yleiskuvan siitä kuinka ohjelmassa suorittaan vaihtoehtoisia tehtäviä valintarakenteiden avulla ja kuinka samanlaisia ohjelma-askeleita toistetaan toistorakenteiden avulla

Lisätiedot

Table of Contents. T740103 Olio-ohjelmointi C/C++ perusteita Jukka Jauhiainen OAMK Tekniikan yksikkö 2010, 2011

Table of Contents. T740103 Olio-ohjelmointi C/C++ perusteita Jukka Jauhiainen OAMK Tekniikan yksikkö 2010, 2011 Tämän materiaalin lähteenä on käytetty osoitteesta http://www.cplusplus.com/doc/tutorial löytyvää C+ + Language Tutorial. Tämän osan tarkoituksena on pääasiassa kerrata C-kielestä tuttuja perusasioita

Lisätiedot

Sisällys. 3. Pseudokoodi. Johdanto. Johdanto. Johdanto ja esimerkki. Pseudokoodi lauseina. Kommentointi ja sisentäminen.

Sisällys. 3. Pseudokoodi. Johdanto. Johdanto. Johdanto ja esimerkki. Pseudokoodi lauseina. Kommentointi ja sisentäminen. Sisällys 3. Pseudokoodi Johdanto ja esimerkki. Pseudokoodi lauseina. Kommentointi ja sisentäminen. Ohjausrakenteet: Valinta if- ja if--rakenteilla. oisto while-, do-while- ja for-rakenteilla. 3.1 3.2 Johdanto

Lisätiedot

Omat tietotyypit. Mikä on olio?

Omat tietotyypit. Mikä on olio? Omat tietotyypit 11 Omat tietotyypit C++:n suuri vahvuus on sen oliopohjaisuudessa. Siihen liittyy runsaasti asiaa ja kulutammekin seuraavat viisi lukua tässä aiheessa. Tässä ja seuraavassa luvussa käsittelemme

Lisätiedot

Ohjelmoinnin perusteet Y Python

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

Lisätiedot

SQL-perusteet, SELECT-, INSERT-, CREATE-lauseet

SQL-perusteet, SELECT-, INSERT-, CREATE-lauseet SQL-perusteet, SELECT-, INSERT-, CREATE-lauseet A271117, Tietokannat Teemu Saarelainen teemu.saarelainen@kyamk.fi Lähteet: Leon Atkinson: core MySQL Ari Hovi: SQL-opas TTY:n tietokantojen perusteet-kurssin

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

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

Lisätiedot

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

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

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CS-A1111 13.9.2017 CS-A1111 Ohjelmoinnin peruskurssi Y1 13.9.2017 1 / 19 Oppimistavoitteet: tämän luennon jälkeen osaat kirjoittaa Python-ohjelman, joka pyytää käyttäjältä lukuja,

Lisätiedot