Muuttujat imperatiivisissa ohjelmointikielissä

Koko: px
Aloita esitys sivulta:

Download "Muuttujat imperatiivisissa ohjelmointikielissä"

Transkriptio

1 Muuttujat imperatiivisissa ohjelmointikielissä Seuraavaksi keskitytään nykyään valta-asemassa oleviin, imperatiivisiin ohjelmointikieliin. Tässä dokumentissa perehdytään keskeiseen muuttujan käsitteeseen ja tietotyyppeihin. Esimerkeissä esiintyviä kieliä käsitellään yksityiskohtaisemmin mm. seuraavissa teoksissa: [Ker] (C-kieli), [Strou] (C++ -kieli), [Arc] (C#), [Arn] (Java), [Kor] (Pascal), [Kur] (Ada) ja [KLS] (FORTRAN). 1. Muuttujat Imperatiivisen ohjelmoinnin aivan keskeisimpiä asioita on muuttujan käsite. Esimerkiksi Edsger Dijkstra on todennut: "Kun on ymmärtänyt tavan, miten ohjelmoinnissa käsitellään muuttujia, on ymmärtänyt olennaisimman ohjelmoinnista." Kuten aiemmin on todettu, imperatiivinen ohjelmointiparadigma perustuu von Neumannin malliin tietokoneesta. Siinä muuttujat mallintavat tietokoneen muistipaikkoja; näin ollen muuttuja on itse asiassa nimi jollekin tietokoneen muistialueelle, jonka sisältö kuvaa muuttujan arvoa. Tosin muuttuja on muutakin kuin pelkkä nimi, ajatellaan esimerkiksi seuraavaa Pascal-kielen sijoituslausetta e := ; Tässä e on jonkin fyysisen muistiosoitteen nimi, kuvaa muuttujan arvoa, joka sijoitetaan kyseiseen muistipaikkaan lausetta suoritettaessa. Kuitenkin tietokoneen muistissa luvut säilytetään binäärisessä muodossa, joten tarvitaan ennakkotietoa muuttujan tyypistä, jotta se voidaan tulkita kyseiseksi desimaaliluvuksi. Näin ollen muuttujalla on 1. Nimi (name): tapa yksilöidä muuttuja, 2. Osoite (address): tietokoneen muistiosoite, jossa muuttujan arvo sijaitsee ja 3. Arvo (value): se data joka kullakin hetkellä on muuttujan osoitteen osoittamassa muistipaikassa, ja lisäksi siihen liittyvät seuraavat ominaisuudet eli attribuutit:

2 4. Tyyppi (type): muuttujan tietorakenteen nimi, 5. Näkyvyysalue (scope): se ohjelman osa, jossa muuttuja on käytettävissä, 6. Elinaika (lifetime, extent): muuttujan muistinvaraamisen ja muistinvapauttamisen välinen aika. Nimi on merkkijono, jota käytetään tunnistamaan jokin ohjelman itsenäinen kokonaisuus, esimerkiksi muuttuja. Sanaa "tunniste" (identifier) käytetään nimen synonyymina. Varhaisimmat ohjelmointikielet sallivat ainoastaan yksikirjaimisia nimiä muuttujille perintönä matemaatikkojen tavasta merkitä muuttujia matemaattisessa tekstissä. Kuitenkin jo FORTRAN luopui tästä rajoitteesta ja salli maksimissaan kuuden merkin mittaiset nimet muuttujille. Alun perin C-kielessä käytettiin nimen maksimierottelupituutena 31 ensimmäistä merkkiä, mutta nykyään tunnisteen pituutta ei rajoiteta. Jotkin C-kääntäjät voivat kuitenkin asettaa rajoituksia nimien pituudelle. FORTRAN 90 käyttää 31 merkin rajoitusta. Nykyään useimmat kielet, kuten C++ ja Java sallivat mielivaltaisen pitkät nimet. Tosin joissakin C++ -toteutuksissa saattaa rajoituksia esiintyä. Ohjelmoijan on tärkeää tietää myös, erotetaanko nimissä isot ja pienet kirjaimet. Vaikka kirjainten erottaminen heikentää kielen luettavuutta ja johtaa helpommin ohjelmointivirheisiin, useimmat moderneista kielistä, kuten Java, C++ ja C# tekevät eron isojen ja pienten kirjainten välillä. Samoin on C-kielessä. Näin ollen muuttujat Muuttuja, muuttuja, muuttuja ja muuttuja ovat kaikki eri muuttujia näissä kielissä. Sen sijaan Pascal ja FORTRAN eivät tee eroa isojen ja pienten kirjainten välillä ja näissä kyseiset muuttujan nimet viittaisivat samaan muuttujaan. Itse asiassa varhemmat FORTRANin versiot eivät sallineet pieniä kirjaimia käytettävän lainkaan muuttujan nimissä. Sittemmin tässäkin kielessä on siirrytty samaan käytäntöön kuin Pascalissa ja pienet kirjaimet tulkataan isoiksi käännösvaiheessa. Kielen kontrollirakenteita kuvaavat sanat on jotenkin erotettava muuttujista määrittelemällä ne erikoissanoiksi (special words). Tämä tehdään yleisesti kahdella tavalla: käyttämällä varattuja sanoja (reserved words) tai avainsanoja (keywords). Varattua sanaa ei voi ohjelmassa käyttää missään yhteydessä muuten kuin sille varattuun tarkoitukseen; näin ollen esimerkiksi C-, Java- tai Pascal-kielessä ei voi

3 määritellä if -nimistä muuttujaa. Avainsana on erikoismerkityksessä ainoastaan tietyissä yhteyksissä. Joissakin aiemmissa ohjelmointikielissä, kuten PL/I ja FORTRAN on käytetty avainsanoja. Moderneissa kielissä on kuitenkin siirrytty käytännöllisesti katsoen yksinomaan varattujen sanojen käyttöön siitä yksinkertaisesta syystä, että avainsanojen käyttö tekee mahdolliseksi erittäin hankalalukuisen ja virhealttiin koodin kirjoittamisen. Esimerkiksi FORTRAN -kielessä INTEGER tarkoittaa kokonaislukutyyppiä ja REAL liukulukutyyppiä, joten ne ovat avainsanoja. Ne eivät kuitenkaan ole varattuja ([KLS] s. 18), joten on mahdollista määritellä tämän nimiset muuttujat, esimerkiksi INTEGER REAL REAL INTEGER INTEGER = 1.23 REAL = 32 Samoin kontrollirakenteita kuvaavien sanojen käyttäminen muuttujan niminä johtaa kammottavaan ohjelmakoodiin. Muuttujan osoite on muuttujaan liittyvän fyysisen muistiosoitteen arvo, joka yleensä ilmaistaan (mikrotietokoneissa tavallisesti 32-bittisenä) heksalukuna. Muuttujan osoite ei yleensä ole staattinen, vaan samannimisen muuttujan osoite saattaa vaihdella ohjelman suorituksen aikana. Usein muuttujan osoitteesta käytetään nimitystä l-value (left value), koska muuttujan osoite on tiedettävä, kun muuttuja sijaitsee sijoituslauseen vasemmalla puolella. On myös mahdollista, että kaksi erinimistä muuttujaa viittaa samaan muistipaikkaan. Tästä ilmiöstä nimiä käytetään termiä moninimisyys (aliasing) ([Har], s. 58). Moninimisyys heikentää koodin luettavuutta ja luotettavuutta, joten nykyään sitä pidetään ei-toivottuna piirteenä ohjelmointikielessä. Mistään ohjelmointikielestä ei kuitenkaan ole onnistuttu poistamaan kokonaan moninimisyyttä. Aikoinaan FORTRANissa oli jopa erityinen mekanismi ominaisuuden toteuttamiseksi (EQUIVALENCE -lause, ks [KLS], s. 128), mikä katsottiin tarpeelliseksi muistin uudelleenkäyttämiseksi. Tapoihin muodostaa eri kielissä muuttujia viittaamaan samaan muistipaikkaan palataan vielä myöhemmin. Muuttujan tyyppi määrittelee sen arvoalueen ja minkälaisia operaatioita kyseisen tyypin muuttujalle voidaan tehdä. Esimerkiksi Java-kielessä suurin kokonaislukutyypin suurin arvo on

4 Integer.MAX_VALUE ja pienin Integer.MIN_VALUE Tyypin muuttujiin voidaan soveltaa perusaritmetiikan operaatioita. Muuttujan arvo on sen muistiosoitteen kulloinenkin sisältö. Yleensä tietokoneen muistiosoitteen koko on yksi tavu: tässä muistiosoitteella tarkoitetaan kuitenkin hieman abstrahoidusti sellaista muistialuetta, johon koko muuttujan data mahtuu. Esimerkiksi Javan double-tyyppinen muuttuja on kahdeksan tavun kokoinen, joten puhuttaessa tällaisen muuttujan osoitteesta, tarkoitetaan kahdeksan tavun kokoista muistialuetta, jossa säilytetään muuttujan arvoa. Usein muuttujan arvoa nimitetään r- valueksi (right value), koska sitä tarvitaan sijoituslauseen oikealla puolella. Huomaa, että päästäkseen käsiksi r-valueen, on l-value aina määritettävä ensin. Yksi keskeisimmistä muuttujiin liittyvistä käsitteistä on sidonta (binding). Sidonnalla tarkoitetaan jonkin ominaisuuden liittämistä ohjelman itsenäiseen kokonaisuuteen. Muuttujan tapauksessa se tarkoittaa yleensä tyypinsidontaa tai muistinsidontaa. Näistä ensimmäinen liittää muuttujaan jonkin tietotyypin ja jälkimmäinen muistiosoitteen (varaa eli allokoi riittävästi muistia, jotta muuttujan arvo voidaan tallentaa). Erityisesti on tärkeää tarkastella sidonta-aikaa (binding time), ts. milloin tietty sidonta tehdään. Yleisesti ottaen voidaan sanoa, että mahdollisimman varhainen sidonta lisää tehokkuutta, kun taas mahdollisimman myöhäinen sidonta joustavuutta. Ei olekaan ihme, että ohjelmointikielten kehityksen trendi on kohti yhä myöhäisempiä sidontaaikoja, kun resurssit lisääntyvät ja tehokkuus ei ole aina välttämätön kriteeri. Kaikki ennen ajoa tapahtuva sidonta staattista (static binding) ja ajonaikainen dynaamista (dynamic binding). Staattinen sidonta voidaan jakaa moneen osaan. Tutkitaan esimerkiksi C++ -kielen lauseita float desinum = 0.0; desinum = desinum + 1.1;

5 Tässä mahdolliset tyypit muuttujalle desinum on pitänyt sitoa jo ohjelmointikieltä suunniteltaessa ja mahdolliset merkitykset + -operaattorille kieltä määriteltäessä. Sen sijaan muuttujan desinum tyyppi ja operaattorin + merkitys jälkimmäisessä lauseessa sidotaan vasta käännösvaiheessa. Vakioiden 0.0 ja 1.1 esitystapa on sidottu kääntäjän suunnitteluvaiheessa ja lopulta muuttujan desinum arvo jälkimmäisessä lauseessa sidotaan muuttujaan dynaamisesti ajonaikaisesti lausetta suoritettaessa. Erityisesti dynaamisen ja staattisen sidonnan erottaminen ja eron ymmärtäminen on olennaista ohjelman semantiikan ymmärtämiseksi. Staattinen sidonta tapahtuu siis ennen ohjelman suoritusta eikä muutu suorituksen aikana; dynaaminen sidonta tapahtuu vasta ohjelmaa ajettaessa ja voi muuttua ohjelman suorituksen aikana. Ennen kuin muuttujaa voi ohjelmassa käyttää, siihen on liitettävä tietotyyppi. Staattisesti tämä tapahtuu liittämällä tyyppi muuttujaan joko eksplisiittisellä tai implisiittisellä esittelyllä. Eksplisiittinen esittely on ohjelmalause jossa listataan joukko muuttujan nimiä ja määritellään ne tietyn tyyppisiksi, esimerkiksi Java-kielen lause float f1,f2,f3; esittelee kolme reaalilukutyyppistä muuttujaa f1, f2 ja f3. Implisiittinen esittely liittää muuttujaan tietotyypin jonkin sopimuksen mukaan ilman erillistä esittelyä. Esimerkiksi FORTRAN -kielessä voidaan muuttuja eksplisiittisesti esitellä, mutta ilman esittelyä esiintyvä muuttuja on INTEGER-tyyppinen, mikäli sen nimi alkaa I, J, K, L, M tai N - kirjaimella; muussa tapauksessa muuttuja on REAL -tyyppinen ([KLS], kappale 4.2.1). Joissakin BASIC -kielen versioissa on vastaavanlainen ominaisuus: Mikäli muuttujan nimi loppuu merkkiin "%", muuttuja on kokonaisluku, merkkiin "$" loppuvat muuttujat ovat merkkijonoja ja kaikki muut ovat reaalilukutyyppiä. Mahdollisuus implisiittiseen esittelyyn katsotaan nykyään suuremmaksi haitaksi kuin ohjelmoijan saama mukavuushyöty. Implisiittinen esittely tapauksissa, joissa esittelyn poisjäänti on ohjelmoijan laiminlyönti, voi johtaa hankalasti löydettäviin virhetoimintoihin ohjelmassa. Useimmissa (staattista tyypinsidontaa käyttävissä) kielissä eksplisiittinen esittely on pakollinen. Kun muuttujan tyyppi sidotaan dynaamisesti, ei käytetä esittelylausetta, vaan muuttujan tyyppi sidotaan sijoituslauseen yhteydessä. Muuttujan tyyppi määrittyy siis

6 vasta ohjelman suorituksen aikana sijoituslausetta suoritettaessa. Dynaamista tyypinsidontaa käyttävät kielet eroavat voimakkaasti staattiseen tyypinsidontaan perustuvista kielistä. Tällaiset kielet ovat erittäin joustavia ja mahdollistavat monissa tapauksissa yksinkertaisen geneerisen ohjelmoinnin. Varhaisimpia dynaamisia kieliä olivat jo luvun alussa kehitetyt APL ja SNOBOL, joilla on vieläkin käyttäjänsä. Useat skriptikielet, kuten JavaScript ja Python, käyttävät dynaamista tyypinsidontaa. Esimerkiksi JavaScript -kielinen lause xz = [1.5, 2.2, 3.7] aiheuttaa muuttujan xz tyypin muuttumisen lukuja sisältäväksi yksiulotteiseksi taulukoksi, ja mikäli tätä seuraa lause xz = 234 xz muuttuu numeeriseksi muuttujaksi. Saavutetusta joustavuudesta aiheutuu myös haittoja: Aiemmin mainittiin jo tehokkuuden menetys, dynaamisesti tyypitetty kieli häviää suoritusajassa yleensä melkoisesti staattisesti tyypitetyn kielen ohjelmille. Usein dynaamisesti tyypitetyt kielet ovat lisäksi tulkattavia johtuen ongelmista, joita dynaaminen tyypittäminen asettaa kääntäjälle. Toinen haitta on koodin luotettavuuden heikkeneminen, koska kääntäjä ei voi havaita ohjelmoijan tyyppivirheitä. Väärän tyyppinen muuttuja sijoituslauseen oikealla puolella aiheuttaa ainoastaan vasemman puolen muuttujan tyypinvaihdoksen. Kun muuttujan tietotyyppi on määrätty, sille voidaan varata muistista alue (osoite), johon muuttujan arvo voidaan tallentaa. Muistin varaamista kutsutaan myös allokoinniksi (allocation). Allokoinnin käänteisprosessi on varatun muistin vapauttaminen, ts. muistialueen antaminen jälleen käytettäväksi; tätä kutsutaan myös deallokoinniksi (deallocation). Muuttujan elinikä on sen käyttämän muistin varaamisen ja vapauttamisen välinen aika. Muuttujat voidaan jakaa eliniän perusteella neljään eri kategoriaan: 1. staattisiin, 2. pinodynaamisiin, 3. kekodynaamisiin (explicit heap dynamic) ja

7 4. implisiittisesti kekodynaamisiin (implicit heap dynamic). Yleisesti ohjelman muistialue jaetaan kolmeen osaan: 1. staattiseen (globaaliin) osaan, 2. pinomuistiin ([runtime] stack) ja 3. kekomuistiin (heap). Yleensä pino- ja kekomuisti ovat muistialueen vastakkaisissa päissä ja kasvavat toisiansa kohti seuraavan kuvion osoittamalla tavalla: Kuva. Ohjelman muistialue Staattinen muuttuja sidotaan muistosoitteeseen ennen ohjelman suoritusta ja se säilyy sidottuna tähän samaan osoitteeseen, kunnes ohjelman suoritus päättyy. Staattisten muuttujien käyttö tuo tehokkuutta ohjelmaan, mutta tekee ohjelmasta joustamattoman. Esimerkiksi rekursiivisten aliohjelmien toteuttaminen on mahdotonta käyttämällä pelkästään staattisia muuttujia. FORTRANin varhaisemmissa versioissa kaikki muuttujat olivat staattisia. Sen sijaan C-kielessä ohjelmoija voi static-määreellä määritellä muuttujan staattiseksi ([Ker], kappale 4.6). Tämä mahdollistaa esimerkiksi aliohjelman paikallisen muuttujan arvon säilymisen aliohjelmakutsujen välillä. Esimerkiksi Pascal -kielessä staattisia muuttujia ei voi määritellä. Muuttujat, joiden tyyppi on staattisesti sidottu, mutta joiden muistiosoite sidotaan ajonaikaisesti esittelylausetta suoritettaessa, ovat pinodynaamisia muuttujia. Nimitys johtuu siitä, että aina Algol 60 -kielestä lähtien sen sukuisissa kielissä paikallisten muuttujien muisti on varattu pinomuistista dynaamisesti, vaikka muuttujan tyyppi

8 onkin staattisesti sidottu. Tähän kategoriaan kuuluvat yleisimmin käytetyt imperatiiviset nykykielet. Juuri pinon käyttäminen muuttujien muistin varaamiseen sallii rekursiiviset aliohjelmakutsut, koska tällöin aliohjelman tietyn nimiselle muuttujalle varataan jokaista aliohjelmakutsua kohti uusi muistiosoite. Toinen etu, joka saavutetaan pinodynaamisten muuttujien käytöllä, on yhteinen muistialue kaikkien aliohjelmien paikallisille muuttujille. Dynaaminen muistinvaraus hidastaa hieman suoritusta, mutta nykyisillä resursseilla tämä ei ole olennaisesti ohjelman suoritusaikaa rajoittava tekijä. Lisäksi historiatietoja ylläpitävien muuttujien käyttäminen aliohjelmissa ei onnistu pinodynaamisilla muuttujilla vaan vaatii jonkinlaisen staattisen tai globaalin muuttujan. Kekomuistista varattavat muuttujat ovat yleisimmin (eksplisiittisesti) kekodynaamisia. Nämä varataan kekomuistista ohjelmoijan käskystä ajonaikaisesti. Kekodynaamisiin muuttujiin voidaan viitata ainoastaan osoitinmuuttujan tai viitetyypin muuttujan avulla. Tällainen muuttuja voidaan varata joko erityisen operaattorin (Java ja C++ -kielessä new) avulla tai C-kielen tapaan kutsumalla kirjastofunktiota (malloc()), joka huolehtii muistinvarauksesta. Kekodynaamisten muuttujien varaama muisti voidaan vapauttaa automaattisesti, kun muuttujaa ei enää käytetä ohjelmassa, kuten Java -kielessä tapahtuu. Tätä prosessia nimitetään roskien keruuksi (garbage collection). Monissa kielissä (esimerkiksi C ja C++) kekodynaamisten muuttujien muistia ei vapauteta automaattisesti, vaan vapauttaminen on ohjelmoijan vastuulla ja siihen on C++ - kielessä oma operaattorinsa delete ja C:ssä funktio free(). Esimerkki. Kekodynaamisen muuttujan varaaminen (ja vapauttaminen) C ja C++ - kielissä. C: C++: int *pnewint; pnewint = malloc(sizeof(int)); *pnewint = 10; free(pnewint); int *pnewint; pnewint = new int; *pnewint = 10; delete pnewint;

9 Mikäli muistin vapauttaminen jätetään ohjelmoijan vastuulle, on hyvin mahdollista, että ohjelman suorituksen aikana jää käyttämätöntä muistia vapauttamatta ja syntyy ns. roikkuvia osoittimia, ts. osoitinmuuttujia, jotka osoittavat jo vapautettuun muistiin. Tällaisen muistialueen käyttäminen johtaa ohjelman ennustamattomaan käyttäytymiseen. Esimerkiksi C++ koodissa int *pnewint; pnewint = new int; pnewint = 0; muistia, joka varattiin, ei voida enää vapauttaa, koska siihen osoittavaan muuttujaan sijoitettiin 0. Nyt lause delete pnewint; ohjelmassa ei tekisi mitään. Jokin muuttujan nollasta poikkeava arvo, joka ei ole varatun muistipaikan osoite kaataisi ohjelman, koska mainitussa paikassa olevaa muistia ei voisi vapauttaa. Edelleen koodissa int *pnewint, *panothernewint; pnewint = new int; *pnewint = 10; panothernewint = pnewint; delete pnewint; pnewint = 0; muuttuja panothernewint on roikkuva osoitin, koska se osoittaa paikkaan, josta muisti vapautettiin. Jos kyseisen muistipaikan arvoa käytetään kokonaislukuna, arvo on satunnainen. Implisiittisesti kekodynaamiset muuttujat sidotaan kekomuistiin vasta sijoituslauseen yhteydessä. Tällaisten muuttujien käyttö sallii hyvin joustavan ohjelmoinnin ja erittäin geneerisen koodin kirjoittamisen. Monet skriptikielet, kuten Perl ja JavaScript käsittelevät merkkijonomuuttujia ja taulukoita näin. Tyypintarkistuksen (type checking) avulla varmistetaan, että ohjelman kaikissa operaatioissa käytettävien muuttujien tyypit ovat yhteensopivat, esimerkiksi kokonaislukutyyppimuuttujaan ei saisi sijoittaa liukulukumuuttujan arvoa.

10 Tyypintarkistus voi olla joko staattista tai dynaamista. Mikäli tyypit tarkistetaan ajonaikaisesti, kyseessä on dynaaminen tarkistus, muuten staattinen. Kääntäjät käyttävät staattista ja tulkit dynaamista tarkistusta. Tyyppiyhteensopivuus (type compatibility) voidaan määritellä tiukemmin nimityypin yhteensopivuutena (name type compatibility) tai hieman löysemmin rakennetyypin yhteensopivuutena (structure type compatibility). Edellinen tarkoittaa, että muuttujat ovat yhteensopivaa tyyppiä ainoastaan, jos niiden määritellyt tyypit ovat samat. Rakennetyypin yhteensopivuus puolestaan toteutuu, jos muuttujien rakenne on identtinen, vaikka niiden määrittely käyttää eri nimeä. Esimerkiksi Pascal-kielisessä määrittelyssä TYPE MYINT = INTEGER; var a: INTEGER; var ma:myint; muuttujat a ja ma eivät ole nimityyppiyhteensopivat, mutta ovat rakennetyyppiyhteensopivat. Pascal -kielessä ei tarkisteta nimityypin yhteensopivuutta, sijoituslause ma := a; on laillinen ylläolevassa ohjelmassa. Standardi-Pascalissa tyypintarkistus on pääosin rakennetyypin tarkistusta, mutta joissakin tilanteissa vaaditaan nimityypin yhteensopivuutta (ks. [Seb], kappale 5.7 tai [Kor], kappale 5.2). Yleensäkin ohjelmointikielissä käytetään tyypintarkistukseen jotain mainittujen tapojen välimuotoa, koska nimityypin tarkistus on liian rajoittava ja rakennetyypin tarkistus liian hankala toteutettava, esimerkiksi C-kielessä typedef struct { int x; int y; } mystruct; typedef struct { int xx; int yy; } myotherstruct; mystruct str1; myotherstruct str2;

11 muuttujat str1 ja str2 ovat rakennetyyppiyhteensopivat, mutta sijoituslause str1 = str2; ei ole sallittu. Itse asiassa C-kieli käyttää muuten rakenneyhteensopivuutta paitsi tietueiden (struct) ja unionien (union) suhteen ([Ker], Appendix A 8.10). Huomaa, että C- ja C++ -kielen typedef ei oikeastaan määrittele uutta tyyppiä, vaan määrittelee ainoastaan nimen jo olemassa olevalle tyypille. Näin ollen C/C++ -kielisessä määrittelyssä typedef int myint; int i; myint mi; muuttujat i ja mi ovat nimityyppiyhteensopivat ja siten sijoituslause i = mi; on sallittu myös C++ -kielessä, joka käyttää nimityyppiyhteensopivuutta (ks. [Seb], kappale 6.14). Ohjelmointikieltä sanotaan vahvasti tyypitetyksi (strongly typed), mikäli 1. Jokaisella muuttujalla on oltava hyvin määritelty tyyppi. 2. Tyyppivirheet havaitaan aina. Yleensä vahvaa tyypitystä pidetään tavoittelemisen arvoisena piirteenä ohjelmointikielessä aina luvulla rakenteellisen ohjelmoinnin ihanteista alkaen. Ominaisuus estää nimittäin monenlaiset ohjelmointivirheet, jotka johtuvat vääräntyyppisen muuttujan sijoittamisen tai käyttämisen parametrina aliohjelmakutsussa. Kuitenkin vain varsin harvat kielet täyttävät tämän kriteerin, jos sitä sovelletaan tiukasti. Esimerkiksi Pascal-kieli on lähes vahvasti tyypitetty, mutta siinä on mahdollisuus määritellä ns. vaihtelevia tietueita (variant records), joiden tyyppiä ei aina voi tarkistaa. C -kielessä on hieman enemmän tapauksia, joissa tyyppivirhe voi jäädä havaitsematta, joten C-kieli ei ole niin vahvasti tyypitetty kuin Pascal. Myöskään C++ ei ole vahvasti tyypitetty, vaikka tyypintarkistus on vahvempi kuin C:ssä. Adaa, Javaa ja C# -kieliä voidaan pitää vahvasti tyypitettyinä, sillä näissä kielissä tyyppivirhe voi syntyä ainoastaan niin, että ohjelmoija itse pakottaa väärän tyypin muuttujalle. Kielessä käytettävät muunnossäännöt (coercion) vaikuttavat olennaisella tavalla tyypintarkistukseen; nimittäin vahvasti tyypitetyssäkin kielessä saattaa olla esimerkiksi aritmeettisille operaatioille sääntöjä, jotka rikkovat periaatteessa tyypitystä vastaan. Esimerkiksi Javassa saadaan laskea liukulukumuuttuja ja kokonaislukumuuttuja yhteen,

12 jolloin kokonaisluvusta pakotetaan liukuluku ja operaatio suoritetaan. Tällaiset muunnokset heikentävät kielen luotettavuutta. Tässä mielessä Ada on luotettavampi kuin Java, koska se sisältää huomattavasti vähemmän tällaisia muunnoksia. Muuttujan näkyvyysalue (scope) on yksi tärkeimmistä käsitteistä tarkasteltaessa ohjelmointikieliä. Näkyvyysalueella tarkoitetaan niiden ohjelman lauseiden kokonaisuutta, joiden alueella muuttuja on näkyvä (visible), toisin sanoen käytettävissä. Globaalin (global) muuttujan näkyvyysalue on koko ohjelma. Ohjelmalohkon tai muun vastaavan yksikön paikalliset eli lokaalit (local) muuttujat ovat sellaisia muuttujia, jotka on määritelty kyseisessä lohkossa. Lohkon sisällä näkyvät muuttujat, joita kuitenkaan ei ole määritelty kyseisessä lohkossa, ovat lohkon eipaikallisia (nonlocal) muuttujia. Muuttujan näkyvyysalue voi määräytyä staattisesti (static scoping) ennen ohjelman suoritusta tai dynaamisesti (dynamic scoping) ohjelman suorituksen aikana. Staattinen näkyvyysalueen määräytyminen on ollut yleisin menetelmä imperatiivisissa kielissä aina sen jälkeen, kun se esiintyi ensi kertaa Algol 60 -kielessä. Nimensä mukaisesti staattista näkyvyysaluetta käyttävien kielten muuttujien näkyvyysalueet määräytyvät jo ennen ohjelman suoritusta ohjelman rakenteen perusteella. Ohjelman rakenteet voivat olla toisilleen alisteisia, yleensä tämä tarkoittaa ohjelmakoodissa määrittelyjen (ja siten myös näkyvyysalueiden) sisäkkäisyyttä. Useimmissa ohjelmointikielissä aliohjelmilla on oma näkyvyysalueensa; samoin nykyisissä kielissä on useimmiten mahdollista muodostaa uusia näkyvyysalueita määrittelemällä ohjelmalohkoja (blocks). Ohjelmalohkon ja kootun lauseen (compound statement) ero on siinä, että lohkon sisällä voidaan esitellä uusia muuttujia, kun kootun lauseen sisällä tämä ei ole mahdollista. Esimerkiksi Pascal -kielessä voidaan määritellä koottuja lauseita keräämällä niitä begin - end parin sisään, mutta muuttujia ei niissä voi määritellä. Siten koodi (muuttujat a ja b ovat aiemmin esitelty) begin var x:integer; a := a+b; end;

13 on Pascalissa virheellinen. Sen sijaan C, C++ ja Java -kielissä sulkujen { ja } sisällä olevat lauseet muodostavat lohkon ja muuttujia voidaan niissä esitellä. Kaikissa kielissä muuttuja saadaan nykyään esitellä missä kohdassa lohkoa tahansa, mutta C-kielen aiemmissa versioissa esittelyt oli aina sijoitettava lohkon alkuun. Staattisesta näkyvyysalueen määräytymisestä seuraa, että mikäli sisemmissä näkyvyysalueissa esitellään samannimisiä muuttujia kuin jo on alueen sisältävässä lohkossa olemassa, on ulomman alueen muuttuja piilotettava sisemmässä lohkossa, jotta esiteltyä muuttujaa voidaan käyttää. Esimerkiksi C-kielisessä ohjelmassa int i = 100; int ki = 35; { int i = 10; printf("lohkon i = %d\n", i); i = ki; printf("lohkon i = %d\n", i); } printf("ulompi i = %d\n", i); Tulostuu Lohkon i = 10 Lohkon i = 35 Ulompi i = 100 Lohkon sisällä siis aiemmin esitelty muuttuja i on piilotettu ja lohkossa esitelty muuttuja i näkyvissä. Kun lohkosta poistutaan, on jälleen aiemmin esitelty muuttuja i näkyvissä. Joissakin kielissä, kuten Pascalissa, sallitaan myös aliohjelmien sisäkkäisyys, jolloin havaitaan sama ilmiö, vaikka Pascalissa ei voikaan muodostaa lohkoja mielivaltaisesti. Esimerkiksi Pascal -ohjelmassa

14 program main; var x:integer; procedure A; var x:integer; procedure B; begin {scope B...} end; begin {scope A...} end; procedure C; var x: integer; procedure D; begin{scope D...} end; procedure E; var x:integer; var y:integer; begin {scope E...} end; begin {scope C...} end; begin {scope main...} end. aliohjelma A sisältää aliohjelman B ja aliohjelma C aliohjelmat D ja E. Tämä vaikuttaa paitsi muuttujien, myös aliohjelmien näkyvyyteen. Näin ollen pääohjelman rungosta voi kutsua aliohjemia A ja C, mutta ei aliohjelmia B, D ja E. Muuttujien näkyvyysalueet (tässä x(main) tarkoittaa pääohjelmassa esiteltyä muuttujaa x ja x(a) aliohjelmassa A esiteltyä muuttujaa x jne) ovat aliohjelmittain seuraavat:

15 main: x(main) A: x(a), x(main) piilotettu B: x(a), x(main) piilotettu C: x(c), x(main) piilotettu D: x(c), x(main) piilotettu E: y(e), x(e), x(c) piilotettu, x(main) piilotettu Hyvin harvat ohjelmointikielet käyttävät dynaamista näkyvyysalueen määräytyvyyttä. Tällaisia kieliä ovat APL, SNOBOL ja LISP -kielen varhaisimmat versiot. Perl sallii myös dynaamisesti määräytyvän näkyvyysalueen muuttujien määrittelyn. Dynaaminen näkyvyysalueen määräytyminen perustuu aliohjelmien suoritusjärjestykseen eikä aliohjelmien rakenteelliseen sijaintiin ohjelmakokonaisuudessa. Näin ollen aktiivisen aliohjelman muuttujat ovat näkyvissä kaikille aliohjelmille, joita kutsutaan kyseisen aliohjelman käynnistämisen jälkeen. Tällöin voi luonnollisesti sattua samannimisten muuttujien törmäyksiä, staattinen tyypintarkistus on mahdoton, joten se on tehtävä ohjelman suorituksen aikaisesti. Oletetaan että C käyttäisi dynaamista näkyvyysalueen määräytymistä (näin ei tietenkään asia oikeasti ole). Silloin ohjelma

16 int x; void fun_1() { } void fun_2() { } int main() { } printf("%d\n", x); int x = 10; fun_1(); x = 5; fun_2(); return 0; tulostaisi 10, koska paikallinen muuttuja x piilottaisi globaalin muuttujan x. Kun käytetään staattista näkyvyysalueen määräytymistä, ohjelma tulostaa 5, koska aliohjelman fun_2 paikallinen muuttuja x on näkyvissä ainoastaan kyseisessä aliohjelmassa. Dynaaminen näkyvyysalueen määräytyminen aiheuttaa monenlaisia ongelmia: Ohjelman luotettavuus heikkenee, koska aliohjelmien paikallisia muuttujia ei voi suojella niiden ulkopuolista muuttamista vastaan. Edelleen koodin luettavuus huononee, koska muuttujien määräytyminen perustuu suoritusjärjestykseen. Etu tässä näkyvyysalueen määräytymisessä on aliohjelmien tiedonvälityksen helpottuminen. Nykyisin katsotaan haittojen olevan huomattavasti suuremmat, joten juuri mikään moderneista kielistä ei määrää näkyvyysalueita dynaamisesti. Maarit Harsun kirjan ([Har]) kolmas luku sisältää myös yllä mainittuja asioita.

17 2. Tietotyypit Jokainen tietokoneohjelma manipuloi dataa jollakin tavalla; data ohjelman sisällä esitetään tietorakenteiden avulla. Ohjelman logiikka koostuu algoritmeista, joten algoritmit ja tietorakenteet ovat ohjelmien perusrakennusaineita, tämän on Niklaus Wirth sisällyttänyt jopa kirjansa "Algorithms+Data Structures = Programs" nimeen. Näin ollen tietotyyppi (data type) on keskeinen käsite ohjelmoinnissa, koska se luokittelee ohjelman datan. Tietotyypeistä ja tyypin tarkistuksesta on puhuttu jo edellä. Tässä käsitellään ja luokitellaan ohjelmointikielissä esiintyviä tietotyyppejä sekä perehdytään hieman eri tapoihin implementoida niitä. Tietotyyppi voidaan määritellä joukoksi arvoja, joihin liittyy joukko näihin arvoihin sovellettavia operaatioita. Tietotyyppejä käsitellään myös Maarit Harsun kirjan ([Har]) luvussa 4. Tietotyyppejä, joiden määrittelemiseen ei käytetä muita tietotyyppejä, sanotaan primitiiviksi tietotyypeiksi (primitive data types). Lähes jokaisessa ohjelmointikielessä määritellään joukko primitiivisiä kielen mukana tulevia primitiivisiä tietotyyppejä. Käsitteenä primitiivinen tietotyyppi muistuttaa läheisesti Loudenin (ks. [Lou] s. 158) käyttämää yksinkertaisen (simple) tietotyypin käsitettä. Louden määrittelee yksinkertaisen tietotyypin koskemaan kuitenkin sellaisia tietotyyppejä, joilla ei ole muuta rakennetta kuin sisäänrakennettu aritmeettinen tai peräkkäinen rakenne. Tyypillisesti primitiiviset tyypit jaetaan numeeriseen, loogiseen ja merkkitietoon. Useissa varhaisissa ohjelmointikielissä ainoat primitiiviset tietotyypit olivat numeerisia. Kaikkein yleisin numeerinen primitiivinen tietotyyppi on kokonaislukutyyppi (integer). Ohjelmointikielestä ja ympäristöstä riippuen kokonaisluvun pituus voi vaihdella; nykyään yleisin (ja esimerkiksi int Java -kielessä spesifioituna, [Arn] kappale 5.5) on 32 bitin mittainen luku. Lisäksi yleensä voidaan määritellä pitempi kokonaisluku (Javassa ja C:ssä long) sekä lyhempi kokonaisluku (Javassa ja C:ssä short). C-kielessä voidaan myös käyttää eripituisia etumerkittömiä kokonaislukutyyppejä (unsigned int jne). Normaalisti korkein bitti ilmaisee luvun etumerkin (1 tarkoittaa negatiivista lukua), ja yleisimmin negatiiviset luvut tallennetaan ns. kahden komplementtina. Tällöin. luvun merkki vaihdetaan tekemällä sille looginen komplementti ja lisäämällä siihen luku 1.

18 Esimerkiksi 8-bittisten kokonaislukujen ollessa kyseessä, luku -12 esitettäisiin seuraavasti: 12 = , looginen komplementti = joten -12 = = Liukulukutyyppi (floating-point type) esittää reaalilukuja (likimääräisesti) tietokoneessa. On luonnollisesti lukuja, joita ei voi tarkasti esittää millään valittavalla tietokoneen käyttämällä merkintätavalla. Liukulukutyypin luvut esitetään nykyisin useimmiten IEEE:n suosittamaa standardia 754 käyttämällä. Siinä 32-bittinen (monissa kielissä float) liukuluku esitetään tieteellisestä merkintätavasta tutussa muodossa (1+mantissa)*2 eksponentti, missä mantissa on välillä [0,1). Ylin bitti on etumerkki (1 tarkoittaa negatiivista lukua), kahdeksan seuraavaa bittiä on varattu esittämään eksponenttia ja loput 23 bittiä mantissaa. Luku esitetään aina binäärisessä muodossa ja eksponentti esitetään poikkeamana luvusta 127, joten esimerkiksi luvulle 0,46875 = 15/32 saataisiin esitys 0, = 15/8 *2-2 = (1+ 7/8)* 2-2. Siten eksponentti = = 125 ja mantissa on tällöin 7/8 = , joten saadaan esitys Merkki(+) Eksponentti (125) Mantissa (0.111) Kaksinkertaisen tarkkuuden liukuluvuille on vastaavan kaltainen esitysmuoto, siinä käytetään mantissalle 52 bittiä ja eksponentille 11 bittiä, poikkeaman arvo on Joissakin ympäristöissä käytetään lisäksi desimaalityypin esitystä, jolloin tietyn mittaisille desimaaliluvuille saadaan tarkka esitys. Desimaalilukuesitys rajoittaa esitettävien lukujen kokoa, mutta tämä esitysmuoto on käytössä ainakin C# -kielessä, jossa sen pituus on 64 bittiä. Lukujen esittämistä tietokoneessa on käsitelty aiemmin diskreettien rakenteiden kurssilla. Looginen tietotyyppi (boolean, logical type) on - ainakin periaatteessa - tietotyypeistä yksinkertaisin, sillä sen tarvitsee sisältää vain kaksi arvoa, tosi ja epätosi. Loogisen tietotyypin esitystapa vaihtelee kielestä toiseen varsin paljon, esimerkiksi C-kielessä mikä tahansa nollasta poikkeava lukuarvo tulkitaan todeksi ja nolla epätodeksi. Yleensä kuitenkin kehittyneemmissä kielissä loogisella tietotyypillä on mahdollisuus saada arvot

19 true ja false. Myös C-kielessä on standardista C99 lähtien määritelty looginen tietotyyppi (bool), joka voi saada arvot true ja false. Nämä ovat kuitenkin kokonaislukutyyppiä ja niiden arvot ovat 1 ja 0. Merkkitieto esitetään tietokoneen sisäisesti numeerisina koodeina. Vanhastaan yleisin koodauskäytäntö on ollut ASCII (American Standard Code for Information Interchange), jossa yleisimmin esiintyvät merkit esitetään luvuilla Tämä tapa on muistinkäytön suhteen tehokas, sillä merkit saadaan mahtuvaan yhteen tavuun, ja vielä ylin bitti jää vapaaksi. Tätä bittiä on käytetty muodostamaan erilaisia laajennuksia standardimerkistöön, jolloin käytettävä laajennus riippuu ympäristöstä. Esimerkiksi se, sisältääkö käytettävä lisämerkistö skandinaavisia kirjaimia, on tällainen seikka. ASCII - merkinnän peruja on se seikka, että useimmissa varhemmissa kielissä merkkityypin muuttuja (esimerkiksi C:ssä char) on ollut yleisimmin, mutta ei välttämättä, yhden tavun eli kahdeksan bitin mittainen. Nykyään tilansäästö ei kuitenkaan ole niin tarpeellista ja lisäksi tarve käyttää yhä laajempaa merkistöä kasvaa koko ajan. Näin ollen uudemmat kielet, kuten Java ja C#, käyttävät merkkitietotyypin esittämiseen 16 - bittistä Unicode-merkistöä. Merkkijonotyyppi (character string type) ei useimmiten ole primitiivinen, koska se määritellään merkkitietotyypin avulla. Se on kuitenkin monessa kielessä valmiiksi määriteltyjen perustietotyyppien joukossa, joten käsitellään se tässä yhteydessä. Periaatteessa olisi mahdollista määritellä merkkijonotyyppi omana primitiivisenä tyyppinään; näin ei useimmissa kielissä tehdä vaan käytetään yksiulotteista, merkkien muodostamaa taulukkoa. Poikkeuksia ovat FORTRAN (version 77 jälkeiset versiot) ja BASIC, joissa merkkijonot ovat primitiivisiä. Merkkijonoille toteutetaan yleensä joitakin perusoperaatioita, joita ovat mm. osajonoon viittaaminen, merkkijonojen katenointi, viittaaminen tietyssä kohdassa esiintyvään merkkiin jne. C-kielessä merkkijono on merkkiin '\0' päättyvä yksiulotteinen merkkitaulukko. Tätä muotoa voidaan käyttää myös C++:ssa, vaikka tässä kielessä onkin suositeltavampaa käyttää standardikirjaston string -luokkaa. Merkkijono-operaatiot hoidetaan C-kielessä käyttämällä kirjastofunktioita, esimerkiksi merkkijonojen vertailu funktioilla strcmp() ja strncmp(), merkkijonojen katenointi funktioilla strcat() ja strncat() sekä tietyn merkin

20 (strchr()) tai merkkijonon(strstr()) etsiminen merkkijonosta. Pascal -kielessäkin merkkijonot ovat merkkien muodostamia taulukoita (ns. pakattuja taulukoita); Pascalissa merkkijonot ovat staattisia pituudeltaan ja ainoastaan samanpituisten merkkijonojen järjestystä voidaan vertailla relaatio-operaattoreilla. Standardi-Pascalista puuttuvat lisäksi merkkijonojen yhdistely ja pilkkomismahdollisuudet, mitä voidaan pitää melkoisena puutteena. Pascalista onkin useita toteutuksia, joissa merkkijonojen esitysmuotoa ja käsittelyä on parannettu. Adassa (kuten myös FORTRANissa) on vastaavan kaltainen määrämittaisuuden vaatimus merkkijonoille. Ada tarjoaa mahdollisuuden katenoida merkkijonoja käyttämällä & -operaattoria: JONO1 := JONO1 & JONO2; FORTRANissa merkkijonojen katenaatio-operaattori on //. Lisäksi FORTRANin merkkijonojen vertailu sallii eripituiset merkkijonot. Tällöin lyhempää merkkijonoa käsitellään kuin se olisi täytetty tyhjillä merkeillä samanmittaiseksi kuin pitempi jono. Staattisen pituuden merkkijonot ovat aina täynnä merkkejä: jos lyhempi merkkijono sijoitetaan pitempään, loppu täytetään tyhjillä merkeillä. C -tyyppiset merkkijonot ovat pituudeltaan dynaamisia, mutta rajoitettuja: merkkejä voi olla mielivaltainen määrä, mutta sitä rajoittaa taulukolle varattu tila. C -merkkijonon lopun osoittaa aina merkki '\0'. Muuten merkkijonon pituutta ei pidetä yllä. Monissa kielissä merkkijonot voivat olla vaihtelevan pituisia ilman ylärajaa; tällöin sanotaan että kielessä merkkijonot ovat pituudeltaan dynaamisia. Java -kielen toteutuksessa merkkijonot ovat suoraan Object -luokasta periytyvän String -luokan ilmentymiä, joten merkkijonotyyppi on (jossakin mielessä) primitiivinen tyyppi. Oikeastaan merkkijono ei Javassa ole lainkaan kieleen sisäänrakennettu tyyppi, vaan luokka määritellään java.lang -paketissa, joka sisältyy automaattisesti kaikkiin Javalla kirjoitettuihin ohjelmiin. Javan merkkijonot ovat vakioita, ts. merkkijonon merkkejä ei voi muuttaa muuten kuin luomalla uusi merkkijono. Muokattavat merkkijonot ovat Javassa StringBuffer -luokan ilmentymiä. Javassa, kuten C++ -kielessäkin sen string - luokalle, on varsin laaja kokoelma valmiita metodeja merkkijonojen käsittelyyn.

21 Ordinaalityyppi (ordinal type) on tietotyyppi, jonka arvot voidaan yhdistää positiivisiin kokonaislukuihin luonnollisella tavalla. Useat kielet sallivat käyttäjän määrittelemiä ordinaalityyppejä; nämä eivät täytä primitiivisen tyypin määritelmää, mutta ovat kuitenkin yksinkertaisia tietotyyppejä. Käyttäjän määrittelemiä ordinaalityyppejä ovat luetellut tyypit (enumeration types) ja rajoitetut tyypit (subrange type). Luetellun tyypin muuttujien arvot määritellään luettelemalla symbolisiksi vakioiksi. Lueteltuun tyyppiin liittyy järjestys, joten luetellun tyypin arvoja voidaan vertailla. Esimerkiksi viikonpäivät voitaisiin esittää lueteltuna tyyppinä Pascal -kielellä seuraavasti: TYPE paiva = (su, ma, ti, ke, tor, pe, la); Sama C-kielellä olisi: enum paiva {su, ma, ti, ke, tor, pe, la}; Vertailu tämän tyypin muuttujien välillä tehtäisiin Pascalissa var ps,pt:paiva; begin end. ps:=su; pt:=tor; if pt > ps then begin end; ja C -kielessä: writeln('torstai sunnuntain jälkeen!'); enum paiva x = su, y = tor; if(x < y) printf("sunnuntai ennen torstaita\n"); C++ -kielessä sama koodi toimisi, mutta muuttujien esittelystä voitaisiin myös jättää enum pois. Useimmiten ei ole mahdollista määritellä lueteltua tyyppiä, joka sisältäisi

22 arvona sellaisen merkkijonovakion, joka esiintyy jo toisessa luetellussa tyypissä. Näin ylläolevaan Pascal -esimerkkikoodiin ei voi lisätä uutta tyyppiä TYPE bile_paiva = (ke, pe, la); eikä C-koodiin enum bile_paiva {ke, pe, la}; Adassa puolestaan tämä on mahdollista; tällaisessa tapauksessa voidaan merkitä, minkä tyypin arvosta on kysymys (ks. [Kur], kappale 4.3). Näin ollen Adassa voitaisiin kirjoittaa type PAIVA is (su, ma, ti, ke, tor, pe, la); type BILE_PAIVA is (ke, pe, la); ja viitata PAIVA -tyypin keskiviikkoon seuraavasti: PS: PAIVA; PS := PAIVA'(ke); Varhaisemmissa kielissä lueteltuja tyyppejä ei ollut ja ohjelmoijat joutuivat yleisesti käyttämään kokonaislukuarvoja merkitsemään tällaisia tyyppejä. Voitaisiin sopia, että 1 tarkoittaa sunnuntaita, 2 maanantaita jne. Tällaisella tavalla on kuitenkin useita varjopuolia. Ensiksikin koodin luettavuus kärsii, koska koodin lukija joutuu koko ajan pitämään mielessään, mitä eri arvot tarkoittavat. Sen sijaan määritellyt tyypit ovat helposti tulkittavissa. Lisäksi koodin luotettavuus kärsii: Kahden eri tyypin muuttujat voivat erehdyksessä sotkeutua toisiinsa ja lisäksi muuttujilla voidaan tehdä aritmeettisia operaatioita, jotka johtavat rajojen ylitykseen. Esimerkiksi yllä lauantai saisi arvon 7, johon voidaan lisätä luku 1, mutta 8 ei tarkoita mitään päivää. Tällaiset virhemahdollisuudet poistuvat mikäli kielessä tarkistetaan lueteltujen tyyppien yhteensopivuus. Näin tehdään esimerkiksi Pascalissa, mutta C-kielessä luetellut tyypit ovat tavallisia kokonaislukuja, joihin voidaan soveltaa kokonaislukujen operaatioita. Siten ylläolevissa esimerkeissä var ps,pt:paiva; begin ps:=10;

23 on Pascal -koodissa virhe, mutta C -koodissa enum paiva x; x = 10; sallitaan. Silti C-kielessäkin lueteltujen tyyppien käyttö parantaa kodin luettavuutta ja jonkin verran myös luotettavuutta. C++-kielessä suoritetaan myös luetelluille tyypeille voimakkaampi tyypintarkistus, joten yllämainittu C-kielinen koodi on virheellistä C++ - koodia. Java-kielessä ei voinut alun perin määritellä lueteltua tyyppiä, minkä takia ohjelmissa käytettiin usein monia nimettyjä vakioita. Tämä puute korjattiin Javan myöhempiin versioihin: kieleen lisättiin tyyppi enum (käytössä kielen versiosta 1.5 lähtien). Tämän tietotyypin muuttuja voi olla joukko esimääriteltyjä vakioita, esimerkiksi seuraavasti: public enum Paiva { } SUNNUNTAI, MAANANTAI, TIISTAI, KESKIVIIKKO, TORSTAI, PERJANTAI, LAUANTAI Javan enum-tyyppi on monipuolisempi kuin aiemmin mainituissa kielissä. Javassa vakiot ovat olioita, joille voidaan määritellä mitä tahansa luokkaan liitettäviä ominaisuuksia. Javan luetellun tyypin vakioita ei voi vertailla suoraan operaattorilla <, vaan siihen on käytettävä metodia compareto esimerkiksi seuraavasti: if( (Paiva.KESKIVIIKKO).compareTo(Paiva.MAANANTAI) < 0) else System.out.println("Keskiviikko tulee ennen maanantaita."); System.out.println("Maanantai tulee ennen keskiviikkoa."); Rajoitettu tyyppi on jonkin ordinaalityypin peräkkäisten arvojen osajono. Rajoitetun tyypin muuttujat esiintyivät ensimmäistä kertaa Pascal -kielessä ja niitä voidaan käyttää myös Pascaliin pohjautuvassa Adassa. Pascalissa voidaan määritellä minkä tahansa ordinaalityypin, myös käyttäjän määrittelemän, rajoitettu tyyppi antamalla ala- ja yläraja seuraavasti

24 TYPE allesata = ; pienetkirjaimet = 'a'..'z'; arkipaivat = ma..la; Rajoitetun tyypin käyttäminen lisää luotettavuutta ainakin siinä tapauksessa, että kääntäjä tarkistaa virheelliset operaatiot. Muissa yleisissä kielissä Pascalin ja Adan lisäksi ei rajoitettua tyyppiä käytetä. Seuraavaksi siirrytään käsittelemään ohjelmointikieliin toteutettuja rakenteellisia tietotyyppejä, joita ovat taulukot, tietueet ja unionit. Lisäksi Pascal -kieleen on toteutettu joukkotyyppi. Rakenteellinen tietotyyppi koostuu yhdestä tai useammasta yksinkertaista tai rakenteista tyyppiä olevasta komponentista. Taulukot ovat epäilemättä yleisimmin käytettyjä tietorakenteita ohjelmoinnissa. Taulukko muodostuu kiinteästä määrästä samaa tyyppiä olevia tietoalkioita, jotka sijaitsevat peräkkäin yhtenäisessä muistialueessa. Taulukon käyttö on tästä syystä tehokasta, koska minkä tahansa sen alkion muistiosoite voidaan suoraan laskea, kunhan vain tunnetaan taulukon alkuosoite. Taulukon alkiot voivat olla mitä tahansa tietotyyppiä, joko primitiivistä, kielessä määriteltyä tai ohjelmassa määriteltyä. Taulukon alkioihin viitataan taulukon nimellä ja alkion indeksillä taulukossa. Indeksi on useimmiten positiivinen kokonaisluku, mutta joissakin kielissä se voi mikä tahansa ordinaalityypin arvo. Esimerkiksi C-kielessä, jossa taulukon indeksit alkavat nollasta, koodi int lukutaulu[50]; lukutaulu[10] = 34; esittelee 50 -paikkaisen kokonaislukutaulukon ja sijoittaa sen yhdenteentoista paikkaan luvun 34. Samoin Javassa ja C++:ssa taulukon indeksit alkavat nollasta. Vastaava tehtäisiin Pascal -kielessä seuraavasti

25 VAR lukutaulu: ARRAY [0..49] OF INTEGER; begin lukutaulu[10] := 34; ja FORTRANissa INTEGER LTAULU(0:49) LTAULU(10) = 34; Näissä kielissä (tosin FORTRANissa vasta versiosta 77 alkaen, sitä varhemmissa versioissa taulukon indeksit alkavat aina luvusta 1) voidaan taulukon ylä- ja alarajat antaa esittelyn yhteydessä. Pascalissa voidaan myös käyttää indeksointiin muitakin ordinaalityypin arvoja ([Kor], kappale 7.2), esimerkiksi TYPE paiva = (su,ma,ti,ke,tor,pe,la); VAR tokataulu: ARRAY [ti..pe] OF INTEGER; begin tokataulu[ke] := 22; Taulukot voidaan jakaa neljään tyyppiin taulukon indeksien rajojen sidonnan ja taulukon muistin allokoinnin tapahtuma-ajan perusteella. Staattisten taulukoiden (static arrays) rajat sidotaan staattisesti, samoin taulukon vaatima muisti varataan staattisesti. Tämän tyypin taulukot ovat suoritusajan suhteen tehokkaimpia käyttää, koska ne eivät vaadi sidontaa eivätkä muistinvarausta ohjelman suorituksen aikana. Kiinteiden pinodynaamisten taulukoiden (fixed stack-dynamic arrays) rajat sidotaan staattisesti, mutta muisti varataan ajonaikaisesti pinomuistista. Tässä tapauksessa muistin käyttö on tehokkaampaa kuin staattisten taulukoiden tapauksessa. Pinodynaamisten taulukoiden (stack-dynamic arrays) rajat sidotaan dynaamisesti ja muisti varataan pinomuistista. Molemmat pysyvät vakioina taulukon elinajan. Tällaisten käyttö lisää joustavuutta, koska taulukon kokoa ei tarvitse tietää etukäteen. Kekodynaamisten taulukoiden (heap-dynamic array ) rajat sidotaan dynaamisesti ja taulukon muisti varataan dynaamisesti kekomuistista. Taulukon rajat ja varattu muisti voivat muuttua sen elinaikana. Näin ollen tämä on kaikkein joustavin tyyppi. FORTRANissa (ennen versiota 90) kaikki muuttujat varataan staattisesti. Tämä koskee myös taulukoita, jotka siten ovat FORTRANissa aina staattisia. C-kielessä taulukko, samoin kuin muuttujakin, voidaan esitellä static-määreellä staattiseksi. Yleensä C:n ja

26 C++:n funktioissa määritellyt taulukot ovat kiinteitä pinodynaamisia taulukoita, koska niiden rajat sidotaan käännösaikana, mutta niille varataan muisti pinomuistista suorituksen aikana. Pinodynaamiset taulukot olivat ennen harvinaisia yleisimmissä imperatiivisissa ohjelmointikielissä: Ada-kielessä on alusta lähtien voinut määritellä pinodynaamisen taulukon declare-lohkoa. AR_LEN := 25; declare AR: array(1..ar_len) of INTEGER; begin end; Tällöin muuttujaan AR_LEN voidaan syöttää jokin arvo ja taulukko varataan dynaamisesti declare-lohkoon tultaessa. Muisti vapautetaan jälleen poistuttaessa lohkosta. Yleensä rajojen dynaamisen sidonnan yhteydessä on käytetty kekodynaamisia taulukoita. C- ja C++-kielten uusimmissa standardeissa sallitaan kuitenkin pinodynaamiset taulukot. Siten seuraavan kaltainen C-ohjelmakoodi on korrekti: int koko = 0; scanf("%d",&koko); int taulukko[koko]; taulukko[koko-1] = 123; int i; for(i = 0; i < koko; i++){ printf("taulukko[%d] = %d\n",i,taulukko[i]); } Javassa, samoin kuin C#:ssa taulukot ovat olioita ja siten kaikki taulukot ovat kekodynaamisia. Uuden taulukon luominen tapahtuu joko käyttämällä new - operaattoria tai luettelemalla taulukon alkiot; tässäkin tapauksessa luodaan kekodynaaminen taulukko. Esimerkiksi Javassa int[] lukutaulu = new int[50]; C-kielessä kekodynaaminen taulukko varataan, samoin kuin muukin dynaamisesti varattava muisti, käyttämällä malloc-funktiota: int *lukutaulu; lukutaulu = malloc(50*sizeof(int));

27 lukutaulu[10] = 34; free(lukutaulu); Huomaa, että C-kielessä taulukko muuttujana on osoitin taulukon alkiotyyppiin; siksi lukutaulu esitellään osoittimena, mutta taulukon alkioihin voidaan viitata hakasulkeita käyttämällä. Huomaa myös, että C:ssä (samoin kuin C++ -kielessä) dynaamisesti varattava muisti on ohjelmoijan vapautettava itse. Pascal-kielessä oli alkujaan se hankala ominaisuus, että taulukon indeksirajat olivat osa taulukon tyyppiä: näin ollen oli esimerkiksi mahdotonta kirjoittaa aliohjelmaa, joka olisi parametrinaan ottanut erikokoisia taulukoita. Tämä kierrettiin ottamalla käyttöön ns. taulukkomallit (conformant arrays) ks esimerkiksi [Kor, s. 135]. Tällä mallilla voitiin antaa aliohjelmalle parametrina taulukko, jonka indeksit ovat jonkin ordinaalityypin rajoitettuja tyyppejä. Esimerkiksi PROCEDURE laskesumma(var summa: INTEGER; taulu: ARRAY [alaraja..ylaraja:integer] OF INTEGER); VAR ind:integer; BEGIN END; summa := 0; FOR ind:= alaraja TO ylaraja DO summa := summa + taulu[ind]; jolloin pääohjelmassa voidaan kutsua aliohjelmaa seuraavasti: VAR luvut: ARRAY[1..50] OF INTEGER; kokosumma: INTEGER; laskesumma(kokosumma,luvut); Tätä toteutusta eivät kaikki kääntäjät tue. Yleisemmin tämä voidaan nykyään toteuttaa ns. avoimien taulukoiden avulla (esimerkiksi Delphissä); tässä aliohjelmalle annetaan parametriksi vain taulukon tyyppi ja sen indeksien oletetaan alkavan nollasta. Korkein indeksi saadaan kutsumalla funktiota HIGH(). Tällöin ylläolevan aliohjelman koodi tulisi muotoon

28 PROCEDURE laskesumma(var summa:integer; taulu: ARRAY OF INTEGER); VAR ind:integer; BEGIN END; summa := 0; FOR ind:= 0 TO HIGH(taulu) DO summa := summa + taulu[ind]; Taulukot voivat olla myös moniulotteisia, ts. tarvitaan useampia indeksejä viittaamaan taulukon alkioihin. Yleensä tämä tarkoittaa sitä että taulukon ensimmäisen indeksin (dimension) alkiot ovat (n-1) -ulotteisia taulukoita jne. Esimerkiksi Pascal -kielen määrittely ARRAY[1..6,3..21,0..3] OF INTEGER on täsmälleen sama kuin ARRAY[1..6] OF ARRAY[3..21] OF ARRAY[0..3] OF INTEGER Yleisesti ohjelmointikielissä ei aseteta ylärajaa taulukon dimensioille; FORTRAN on poikkeus tästä. Alunperin FORTRANissa sai käyttää korkeintaan kolmiulotteisia taulukoita ja FORTRAN 77 salli seitsenulotteiset taulukot. Sittemmin ulottuvuuksien lukumäärää on vielä nostettu. Pascalissa ei ole mahdollista alustaa taulukkoa sen esittelyn yhteydessä. Monissa kielissä tämä on kuitenkin mahdollista. Esimerkiksi FORTRANissa voidaan DATA - lauseella antaa taulukoille (sekä muuttujille ja merkkijonoille) alkuarvoja, esimerkiksi REAL REAALILUVUT(4) DATA REAALILUVUT/1.1,2.5,99.3, / alustaa taulukon luetelluilla arvoilla. Sekä C, C++, C# että Java -kielessä on mahdollista esitellä ja alustaa taulukko luettelemalla sen alkiot ilman sen dimensioiden määrittelemistä, esimerkiksi int vektori[] = {2,4,6,8};

29 luo samalla nelipaikkaisen taulukon. Tämä lisää luonnollisesti ohjelmoijan mukavuutta, mutta heikentää koodin luotettavuutta, koska taulukon koko määräytyy automaattisesti eikä välttämättä huomata onko esimerkiksi jokin alkio jäänyt vahingossa pois tai kirjoitettu kahdesti. Sama esittely voitaisiin luonnollisesti tehdä myös int vektori[4] = {2,4,6,8}; Tämä tapa on sikäli turvallisempi, että kääntäjä huomaa, mikäli alustuslukuja on liikaa. Kaksi- ja useampiulotteinen taulukko voidaan C/C++ -kielessä alustaa luettelemalla ainoastaan niin, että ainoastaan yksi dimensio jätetään vapaaksi: int matriisi[][4] = {{1,2,3,4},{2,3,4,5}}; Javassa sen sijaan esittelyt int matriisi[][] = {{1,2,3,4},{2,3,4,5}}; int[][] matriisi2 = {{3,2,1,4},{5,3,4,2}}; on sallittu. C# -kielessä voidaan myös esitellä ja alustaa useampiulotteiset taulukot täysin luettelemalla, mutta tällöin on kirjoitettava int[,] matriisi = {{1,2,3,4},{2,3,4,5}}; Lisäksi Javassa taataan se, että taulukko on alustettu oletusarvoilla, esimerkiksi numeeriset taulukot arvoilla 0 ja oliotaulukot arvoilla null, vaikka ohjelmoija ei kirjoittaisi alustuskoodia taulukolle. Tätä ei taata esimerkiksi C-kielessä, jossa alustamaton taulukko sisältää satunnaista dataa. Yleensä ohjelmointikieleen sinänsä ei ole sisällytetty juuri taulukko-operaatioita, ts. sellaisia operaatioita, jotka käsittelisivät taulukkoa itsenäisenä yksikkönä. Tavallisesti nämä on toteutettu kirjastofunktioina tai sisällytetty luokkakirjastoihin. FORTRAN 90 sisältää kuitenkin taulukko-operaatioita, esimerkiksi taulukkojen summan (alkioittain). Adassa on mahdollista viitata taulukon osiin indeksirajoilla ja näin käsitellä esimerkiksi matriisin rivejä tai sarakkeita vektoreina. Laajin kokoelma kieleen rakennettuja vektorija matriisioperaatioita on eittämättä APL-kielessä, joka onkin pääasiassa suunniteltu

30 tällaisten tehtävien ohjelmoimiseen. APL-kielessä on operaattorit mm. matriisin transponointiin, sen käänteismatriisin etsimiseen sekä vektoreiden piste- ja ristituloille. Ohjelmoinnissa tarvitaan usein loogisia kokonaisuuksia, jotka koostuvat erilaisista tietoalkioista. Tätä tarvetta varten on luotu tietue (record). Tietue on erityyppisten tietoalkioiden kooste, jossa tiettyyn alkioon eli kenttään (field) viitataan sen nimellä. FORTRANia lukuunottamatta tietue on sisältynyt kaikkiin yleisiin ohjelmointikieliin. Oliokielissä ei kuitenkaan ole tarvetta tietueille, koska olioilla voidaan toteuttaa myös tietueet. C++ -kielessä voi vielä käyttää C:n jäänteenä tietueita, mutta tällöin nekin itse asiassa määrittelevät tietynlaisen luokan. Sama koskee C# -kieltä. Java ei sisällä tietuetietotyyppiä. Tietueen tarvitsema muisti varataan peräkkäisistä muistipaikoista kuten taulukonkin. Tietueen kenttiin viittaaminen ei voi tapahtua kuitenkaan niin suoraviivaisesti, kuin taulukon alkioihin, koska tietueen kentät ovat yleensä eripituisia. Tietueiden muisti voidaan allokoida staattisesti tai dynaamisesti kuten muidenkin muuttujien. Yleensä Esimerkiksi C-kielessä (ks. [Ker], luku 6) voitaisiin määritellä struct Asiakas { }; char nimi[25]; int tilinro; jolloin tietue voitaisiin esitellä ja sen kenttiin voitaisiin viitata tyypillisellä pistenotaatiolla: struct Asiakas a; strcpy(a.nimi,"huijari"); a.tilinro = 21; Mikäli tietue varattaisiin dynaamisesti ja käytettäisiin osoitintyyppistä muuttujaa viittaamaan tietueeseen, C-kielessä käytetään erityistä operaattoria -> viittaamaan kenttiin seuraavasti:

31 struct Asiakas* pa; pa = malloc(sizeof(struct Asiakas)); strcpy(pa->nimi,"huijari"); pa->tilinro = 21; Pascalissa (ks. [Kor], kappale 7.3) vastaava tietue toteutettaisiin seuraavasti: TYPE asiakas = RECORD nimi: PACKED ARRAY[0..24] OF CHAR; tilinro: INTEGER; END; VAR a:asiakas; BEGIN a.nimi := 'Huijari'; a.tilinro := 21; Pascal -kielessä on toinenkin tapa viitata yllämääritellyn tietueen a kenttiin käyttämällä WITH -lausetta: WITH a DO BEGIN WRITELN(nimi); WRITELN(tilinro); END; Tällöin lauseen sisällä oletetaan että annetut muuttujan nimet viittaavat tietueen kenttiin. Tietueet ovat ohjelmoinnissa käyttökelpoisia tietotyyppejä; lisäksi niiden toteutus on varsin suoraviivainen eikä sisällä ongelmia yleensä missään ohjelmointikielessä. Tietue vastaa yhden tai useamman tietotyypin karteesista tuloa ja sisältää siten kentät jokaisen tietotyypin muuttujalle. Unioni (union) vastaa puolestaan tietotyyppien unionia, joten unionityypin muuttuja sisältää vain yhden kentän, mutta tämän kentän muuttuja voi olla tyypiltään jokin annetuista tietotyypeistä. Näin ollen unionityypin muuttujan sisältämä tieto voi vaihdella tyypiltään ohjelman suorituksen aikana. Unionityyppisten muuttujien käyttö voi olla hyödyllistä esimerkiksi kirjoitettaessa koodia, jonka on tarkoitus toimia eri ympäristöissä. Joissakin koneissa esimerkiksi int - tyyppinen kokonaisluku voi olla 16 -bittinen, toisissa 32 tai 64 -bittinen. Unionityypin avulla voidaan kirjoittaa koodia, jossa tehdään ei-standardimaisia tyypinmuunnoksia.

32 Tässä piilee myös unionityypin käytön vaara: se voi aiheuttaa monia ongelmatilanteita koodissa juuri tästä syystä. C ja C++ -kielissä union -lauseella voidaan määritellä niin sanottu vapaa unioni (free union) (ks. [Ker], kappale 6.8 ja [Strou] Appendix C 8.2). Nimitys johtuu siitä, että unionissa ei ole minkäänlaista valitsinkenttää kertomassa minkä tyyppinen tieto on tällä hetkellä talletettu muuttujaan. Muuttujalle varataan tila suurimman mahdollisen tietotyypin mukaan ja mitään tyypintarkistusta ei tehdä, joten ohjelmoija on täysin vapaa muuntamaan tietotyypin miksi tahansa vaihtoehdoista. Esimerkiksi C-ohjelmassa union IntMerkki { int myint; char mychar; }; int arvo; union IntMerkki imer; imer.mychar = 'A'; voidaan sijoittaa kokonaislukumuuttujaan arvo = imer.myint; jolloin muutttujan arvo on satunnainen, koska ainoastaan yhtä tavua on käytetty sijoitettaessa merkki 'A'. Samoin voidaan tehdä imer.myint = 5432; jolloin imer.mychar == '8'; Unioneja käyttämällä on näin ollen mahdollista kiertää C-kielen tyypintarkistus ja turvallisuus jää ohjelmoijan vastuulle. Näin ollen unionien käyttäminen ohjelmassa pitäisi aina tehdä suurta harkintaa noudattaen. Jotta unioni- tyypissä voitaisiin tehdä tyypintarkistus, on tietotyyppiin liitettävä jokin tietokenttä, jonka perusteella päätellään, mikä on kulloinkin talletettu tyyppi. Tällaista

33 kenttää kutsutaan valitsinkentäksi (tag field, discriminant). Pascal -kielen unionityyppiä kutsutaan vaihtelevaksi tietueeksi (variant record) ([Kor], kappale 7.3.3). Tällaisessa tietueessa voi olla kiinteä ja vaihteleva osa. Kiinteä osa säilyy aina samanlaisena, mutta vaihteleva osa voi sisältää eri tietotyypin arvoja. Tällöin TYPE muoto = (ympyra,suorakaide); kuvio = RECORD x_coord:real; y_coord:real; case tyyppi:muoto OF ympyra:(sade:real); suorakaide:(leveys:real;korkeus:real); END; Määrittelee tietueen, jossa vaihtelevassa osassa on kentän tyyppi perusteella joko reaalikenttä sade tai kaksi reaalikenttää leveys ja korkeus. Tällaista tietuetta voi käyttää ohjelmassa kuten tavallistakin, ts. viittaamalla pistenotaatiolla tietueen kenttiin tai käyttämällä WITH -lausetta: VAR hahmo:kuvio; VAR ala:real; BEGIN hahmo.x_coord:=1.1; hahmo.y_coord:=2.1; hahmo.tyyppi := ympyra; hahmo.sade:=1.2; WITH hahmo DO CASE tyyppi OF suorakaide: ala := leveys*korkeus; ympyra: ala := 3.14 * sade * sade; END; Pascalin unionityyppi on hieman turvallisempi kuin C-kielen, mutta silti turvaton, koska se rikkoo Pascalin muuten vahvan tyypityksen, yleensä ei voida havaita vaihtelevien tietueiden väärinkäyttöä. Esimerkiksi ylläolevassa koodissa voitaisiin muuttaa rivi hahmo.tyyppi := ympyra; riviksi hahmo.tyyppi := suorakaide;

34 muuttamatta muuta koodia. Tällöin ohjelmassa viitattaisiin suorakaide -tyyppisen muuttujan sade -kenttään, jota ei pitäisi olla olemassakaan. Mutta tätä virhettä ei kääntäjä havaitse. Samoin suorakaiteeksi määritellyn muuttujan voisi muuttaa myöhemmin ympyräksi kajoamatta tietueen kenttiin, jotka suorakaiteen tapauksessa olivat leveys ja korkeus. Näin ollen unionitietotyypin toteutuksessa on ongelmansa. Ada -kielessä on samankaltainen vaihtuvan tietueen tyyppi kuin Pascalissa, mutta sitä on parannettu niin, että valitsinkenttää ei voi muuttaa muuttamatta koko tietuetta ja lisäksi Adassa on tarkistettava väärät kenttäviittaukset. Näin ollen Adan unionityypin toteutuksen tulisi olla turvallinen. Monissa kielissä, kuten Javassa ja C#:ssa ei unionityyppiä ole toteutettu. Joukkotyypin (set type) muuttujat voivat sisältää järjestämättömän kokoelman jonkin ordinaalityypin muuttujan erillisiä arvoja. Näin ollen joukkotyypillä mallinnetaan matematiikasta tutun joukon käsitettä. Yleisistä (imperatiivisista) ohjelmointikielistä ainoastaan Pascalissa on toteutettu joukkotyyppi ([Kor], kappale 7.4). Esimerkiksi TYPE paiva = (su,ma,ti,ke,tor,pe,la); paivaset = SET OF paiva; VAR joukko:paivaset; BEGIN joukko := [ma,pe,ke]; IF pe IN joukko THEN WRITELN('PAIVA OLI JOUKOSSA') ELSE WRITELN('PAIVA EI OLLUT JOUKOSSA'); määrittelee joukkotyypin, jonka alkiot voivat olla päiviä, luettelee erään joukkomuuttujan alkiota ja tarkistaa, onko annettu alkio joukossa. Pascalissa on lisäksi määritelty joukoille tavallisimmat joukko-opin operaatiot leikkaus, unioni ja joukkojen vertailu (onko toinen joukko toisen osajoukko, ovatko joukot samat vai eri joukot). Lopuksi tarkastellaan osoitintyyppiä (pointer type). Osoitintyypin muuttujien arvot ovat muistiosoitteiden arvoja ja lisäksi erityinen arvo null (tai nil). Osoitintyypin muuttujia kutsutaan yleensä osoittimiksi (pointers). Osoitintyypin muuttujia tarvitaan käsittelemään dynaamisia muuttujia ja erityisesti dynaamisia tietorakenteita. Lähes kaikissa imperatiivisissa ohjelmointikielissä on mahdollista käyttää osoittimia.

35 Poikkeuksena tästä on FORTRAN (77 ja varhaisemmat), jossa dynaamisten tietorakenteiden käyttö onkin hankalaa. Osoitintyypin muuttuja siis sisältää muistiosoitteen, joten muuttujana se on aina saman tyyppinen, mutta ohjelmoinnin kannalta on tiedettävä minkälaiseen muuttujaan osoitin osoittaa; tätä tyyppiä sanotaan osoitinmuuttujan tarkoitetyypiksi (reference type). Osoitin esitelläänkin aina kirjoittamalla tarkoitetyyppi ja sen jälkeen tyyppioperaattori ennen muuttujan nimeä. Tyyppioperaattori on C/C++ -kielessä *, Pascalissa ^ ja Adassa access. Periaatteessa osoitinmuuttuja voi viitata mihin tahansa tietotyyppiin, myös toisen osoittimeen. Se muuttuja, johon osoitinmuuttujan arvo kulloinkin viittaa, on sen tarkoitemuuttuja. Osoitintyypin muuttujaan liittyy oleellisesti kaksi operaatiota: sijoitus (assignment) ja muistipaikan sisältöön viittaaminen (viittauksen purkaminen, dereferencing). Ensimmäinen operaatio sijoittaa osoitinmuuttujan arvoksi jonkin (järkevän) muistipaikan. Jälkimmäinen toteutetaan yleensä jollakin sisältö-operaattorilla. Esimerkiksi C-kielisessä ohjelmassa voisi kokonaislukumuuttuja luku olla muistipaikassa 9876 ja sen arvo olla Olkoon toinen kokonaislukumuuttuja toinenluku esitelty ohjelmassa. Jos nyt kokonaislukuosoitinmuuttujan ptr arvo on 9876, käsky toinenluku = *ptr; kopioi muistipaikasta 9876 arvon 1000 muuttujan toinenluku arvoksi, ts. tekee täsmälleen saman operaation kuin toinenluku = luku; Muita tyypillisiä osoitinmuuttujille tehtäviä operaatioita on muuttujien vertailu, ts. sen vertaaminen osoittavatko ne samaan muistipaikkaan. Pascalissa muita operaatioita osoittimille ei (ehkä viisaasti) sallitakaan. Pascalissa muuttuja varataan dynaamisesti ja sitä käytetään sijoituslauseessa seuraavasti: VAR r:real; VAR pr:^real; BEGIN NEW(pr); pr^ := 21.1; r := pr^;

36 Tämän jälkeen muuttujalla r on arvo C ja C++ -kielissä osoittimia voi käyttää hyvin monipuolisesti, mikä antaa ohjelmoijalle monenlaisia mahdollisuuksia, mutta tekee niiden virheellisen käytön myös helpoksi. Minkä tahansa muuttujan muistiosoite voidaan selvittää ja sijoittaa osoitinmuuttujaan, esimerkiksi int muuttuja = 20; int *pm; pm = &muuttuja; *pm = 55; sijoittaa muuttujan arvoksi 55. Lisäksi C-kielessä osoitintyyppien tyypintarkistus on varsin väljää; C:ssä float f = ; int *pif; float *pf; pif = &f; pf = pif; on sallittu, mutta C++ ei anna tehdä kumpaakaan osoitinsijoitusta. Tällainen ohjelmointitapa on luonnollisesti arveluttava. Lisäksi C/C++-kielessä voidaan soveltaa osoitinaritmetiikkaa (ks. esim.[ker], luku 5). Jos ptr on osoitintyypin muuttuja, ptr+1 osoittaa seuraavan tarkoitetietotyypin muuttujan osoitteeseen. Toisin sanoen, jos ptr on tyyppiä char*, ptr+1 osoittaa seuraavaan tavuun, mutta jos se on tyyppiä int*, ptr+1 osoittaa neljän tavun päähän ptr:stä. (Olettaen, että char on yhden tavun mittainen ja int neljän tavun mittainen.) Esimerkiksi taulukko voidaan käydä läpi osoittimia käyttämällä:

37 char c; int ki; double rl; int index; char merkit[4] = {'a','b','c','d'}; int kokoluvut[4] = {1,2,3,4}; double rluvut[4] = {1.1,2.2,3.3,4.4}; char* pc = merkit; int* pi = kokoluvut; double* pd = rluvut; for(index=0;index < 4; index++) { c = *(pc + index); ki = *(pi + index); rl = *(pd + index); printf("merkki on %c, kokonaisluku on %d, reaaliluku on %e\n", c,ki,rl); } Huomaa, että kaikkien taulukoiden alkioihin viitataan samalla tavalla, vaikka taulukoiden sisältämät tietotyypit ovatkin erikokoisia. C ja C++ -kielessä on lisäksi olemassa geneerinen osoitintyyppi void*, joka voi osoittaa minkä tyyppiseen muuttujaan tahansa. Tällainen osoitin on aina tyypitettävä jonkin tyyppiseksi osoittimeksi ennen muistiosoitteeseen viittaamista. Yleisimmin void* -osoittimia käytetään muistia käsittelevien funktioiden parametreina. Osoitintyyppi on dynaamisten muuttujien ja tietorakenteiden käsittelyssä hyödyllinen, mutta osoitintyyppisten muuttujien käyttö johtaa myös moniin ongelmiin. Tyypillisiä ongelmia ovat roikkuvat osoittimet, muistivuoto ja moninimisyys. Mahdollisuutta moninimisyyteen (aliasing) käyttämiseen ohjelmointikielessä ei pidetä kovin suotavana, koska tällöin voidaan kirjoittaa koodia, jossa muuttujan arvon vaihtumista ei ole helppo havaita. Tällöin koodin luettavuus kärsii. Osoitintyypin muuttujien salliminen johtaa väistämättä moninimisyyteen. Esimerkiksi Pascal -koodissa VAR r:real; VAR pr,pra:^real; BEGIN NEW(pra); NEW(pr); pr^ := 21.1; pra := pr; pra^:=33.2; r := pr^;

38 ei välttämättä huomaa sijoittavansa muuttujaan r arvoa C/C++-kielessä moninimisyys ilmenee vielä moninaisimmin tavoin, varsinkin koska myös staattisesti sidottujen muuttujien muistiosoitteita voi sijoittaa osoitintyypin muuttujiin. Roikkuva osoitin (dangling pointer) tarkoittaa osoitinta, joka osoittaa jo vapautettuun muistiin. Tyypillisesti tämä perustuu siihen, että dynaamisesti varatut muuttujat joudutaan myös erikseen vapauttamaan ja koska useampi osoitinmuuttuja voi osoittaa samaan muistiosoitteeseen näitä voi jäädä roikkumaan muistia vapautettaessa. Useimmiten ohjelmassa tämä tapahtuu seuraavasti: Osoitinmuuttuja p1 osoittaa dynaamisesti varattuun muuttujaan, toiseen osoitinmuuttujaan p2 sijoitetaan p1 ja p1:n tarkoitemuuttuja vapautetaan (ja yleensä sijoitetaan p1=null). Mutta p2 osoittaa edelleen muistiosoitteeseen, jossa dynaaminen muuttuja sijaitsi: p2 on muuttunut roikkuvaksi osoittimeksi ja sen muistialueeseen viittaaminen tuottaa satunnaisia arvoja. Mikäli aiemmin esiintynyttä Pascal-koodia muutetaan seuraavasti: NEW(pra); NEW(pr); pr^ := 21.1; pra^:=33.2; pra := pr; dispose(pra); pra := NIL; r := pr^; muuttujassa r on jokin satunnainen kokonaisluku (useimmiten luultavasti 0). Samoin C++ -kielisessä esimerkissä int *pv,*pu; pv = new int; *pv = 55; pu = pv; delete pu; pu = 0; int ki = *pv; muuttujassa ki on satunnainen arvo. Muistivuodoksi (memory leakage) sanotaan tilannetta, jossa ohjelmassa varattua dynaamista muistia ei vapauteta. Tämä voi syntyä hävittämällä viite dynaamiseen muuttujaan. Tyypillisesti tämä tapahtuu niin, että osoitin, joka osoittaa dynaamisesti varattuun muuttujaan, sijoitetaan osoittamaan

39 johonkin toiseen muuttujaan. Ellei ensimmäistä muuttujaa sitä ennen vapauteta, siihen ei osoita mikään muuttuja ja sen varaamaa muistia on mahdotonta enää vapauttaa. Esimerkiksi C++ -koodissa int *pv,*pu; pu = new int; pv = new int; pu = pv; ensimmäinen varattu kokonaisluku jää ohjelmassa vapauttamatta. Sama ongelma voi esiintyä kaikissa kielissä, joissa dynaamisesti varattu muisti on ohjelmallisesti vapautettava, esimerkiksi Pascalissa ja C:ssä. Osoitintyypin muuttujien ongelmallisuuden takia ainakin Javassa ja C#:ssa on luovuttu niistä ja korvattu ne viitteillä. Viitetyypin (reference type) muuttujat sisällytettiin aluksi C++ -kieleen lähinnä toteuttamaan viitetyypin parametrinvälitys funktioille. Viitemuuttujan avulla voidaan luoda muuttujalle alias. C++ -kielen viite on vakioosoitin, jolle tehdään implisiittinen muistiosoitteeseen viittaaminen (ks. [Strou] kappale 5.5). Koska viite on vakio, se on alustettava jollakin muistiosoitteen arvolla, ja se viittaa samaan muistiosoitteeseen koko elinaikansa. Esimerkiksi float f; float &ref_f = f; tekee muuttujista f ja ref_f aliaksia. Tällöin sijoituslause ref_f = 2.78; sijoittaa muuttujan f arvoksi Java on yleistänyt viitemuuttujan tyyppiä verrattuna C++-kieleen niin, että osoittimet on voitu täysin korvata viitteillä. Kaikki luodut oliot Javassa varataan dynaamisesti kekomuistista ja olion nimi on itse asiassa viite tähän olioon. Minkäänlainen osoitinaritmetiikka ei ole Javan viitteille sallittua; Javan viitteet eivät myöskään ole vakio-osoittimia vaan viite voidaan asettaa osoittamaan toiseenkin olioon. Muistivuotojen estämiseksi Javan dynaamisesti varattuja olioita ei tarvitse ohjelmoijan vapauttaa, vaan roskien keruu (garbage collection) huolehtii siitä, että oliot vapautetaan, kun niihin ei enää ole viittauksia.

40 Lähteet [Arc] Archer, Tom. Inside C#. Edita, IT Press, [Arn] Arnold, Ken Gosling, James. The Java Programming Language, Second Edition, Addison-Wesley [Har] Harsu, Maarit. Ohjelmointikielet. Periaatteet, käsitteet, valintaperusteet, Talentum [Ker] Kernighan, Brian Richie Dennis. The C Programming Language. Prentice Hall [KLS] Kortela, Larmela, Salmela. FORTRAN 77. OtaData [Kor] Kortela, Larmela, Planman. Pascal-ohjelmointikieli. OtaData [Kur] Kurki-Suonio Reino. Ada-kieli ja ohjelmointikielten yleiset perusteet. MODEEMI ry Tampere [Lou] Louden, Kenneth C. Programming Languages, Principles and Practice, PWS-KENT [Seb] Sebesta, Robert W. Concepts of Programming Languages 10th edition, Pearson [Strou] Stroustrup, Bjarne. The C++ Programming Language, 3rd edition, Murray Hill 1997.

815338A Ohjelmointikielten periaatteet

815338A Ohjelmointikielten periaatteet 815338A Ohjelmointikielten periaatteet 2015-2016 IV.1 Imperatiivinen ohjelmointi muuttujat ja tietotyypit Sisältö 1. Yleistä muuttujista 2. Sidonta 3. Tyypin tarkistus 4. Näkyvyysalue 5. Yleistä tietotyypeistä

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

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

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

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

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

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

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

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

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

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

Lisätiedot

Sisällys. 6. Muuttujat ja Java. Muuttujien nimeäminen. Muuttujien nimeäminen. salinovi tai syntymapaiva

Sisällys. 6. Muuttujat ja Java. Muuttujien nimeäminen. Muuttujien nimeäminen. salinovi tai syntymapaiva Sisällys 6. Muuttujat ja Java Muuttujien nimeäminen. Muuttujan tyypin määritys. Javan tietotyypit: Kokonais- ja liukuluvut. boolean- ja char-tyypit. Tyyppien yhteensopivuus. Viitetietotyypit ja merkkijonotietotyyppi

Lisätiedot

6. Muuttujat ja Java 6.1

6. Muuttujat ja Java 6.1 6. Muuttujat ja Java 6.1 Sisällys Muuttujien nimeäminen. Muuttujan tyypin määritys. Javan tietotyypit: Kokonais- ja liukuluvut. boolean- ja char-tyypit. Tyyppien yhteensopivuus. Viitetietotyypit ja merkkijonotietotyyppi

Lisätiedot

11/20: Konepelti auki

11/20: Konepelti auki Ohjelmointi 1 / syksy 2007 11/20: Konepelti auki Paavo Nieminen [email protected] Tietotekniikan laitos Informaatioteknologian tiedekunta Jyväskylän yliopisto Ohjelmointi 1 / syksy 2007 p.1/11 Tämän luennon

Lisätiedot

15. Ohjelmoinnin tekniikkaa 15.1

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

Lisätiedot

Sisällys. 6. Muuttujat ja Java. Muuttujien nimeäminen. Muuttujien nimeäminen. Muuttujien nimeäminen. Muuttujan tyypin määritys. Javan tietotyypit:

Sisällys. 6. Muuttujat ja Java. Muuttujien nimeäminen. Muuttujien nimeäminen. Muuttujien nimeäminen. Muuttujan tyypin määritys. Javan tietotyypit: Sisällys 6. Muuttujat ja Java Muuttujien nimeäminen. Muuttujan tyypin määritys. Javan tietotyypit: Kokonais- ja liukuluvut, merkit, totuusarvot. Tyyppien yhteensopivuus. Viitetietotyypit ja merkkijonotietotyyppi

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

7. Oliot ja viitteet 7.1

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

Lisätiedot

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 perusteet

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

Lisätiedot

Java-kielen perusteet

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

Lisätiedot

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

Taulukot. Jukka Harju, Jukka Juslin 2006 1

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

Lisätiedot

Ohjelmoinnin perusteet Y Python

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

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

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

7/20: Paketti kasassa ensimmäistä kertaa

7/20: Paketti kasassa ensimmäistä kertaa Ohjelmointi 1 / syksy 2007 7/20: Paketti kasassa ensimmäistä kertaa Paavo Nieminen [email protected] Tietotekniikan laitos Informaatioteknologian tiedekunta Jyväskylän yliopisto Ohjelmointi 1 / syksy 2007

Lisätiedot

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

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

Lisätiedot

Sisällys. 6. Muuttujat ja Java. Muuttujien nimeäminen. Muuttujien nimeäminen. salinovi tai syntymapaiva

Sisällys. 6. Muuttujat ja Java. Muuttujien nimeäminen. Muuttujien nimeäminen. salinovi tai syntymapaiva Sisällys 6. Muuttujat ja Java Muuttujien nimeäminen. Muuttujan tyypin määritys. Javan tietotyypit: Kokonais- ja liukuluvut, merkit, totuusarvot. Tyyppien yhteensopivuus. Viitetietotyypit ja merkkijonotietotyyppi

Lisätiedot

6. Muuttujat ja Java 6.1

6. Muuttujat ja Java 6.1 6. Muuttujat ja Java 6.1 Sisällys Muuttujien nimeäminen. Muuttujan tyypin määritys. Javan tietotyypit: Kokonais- ja liukuluvut, merkit, totuusarvot. Tyyppien yhteensopivuus. Viitetietotyypit ja merkkijonotietotyyppi

Lisätiedot

Tieto- ja tallennusrakenteet

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

Lisätiedot

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

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 [email protected] 1. Java-ohjelmoinnin alkeita Tietokoneohjelma Java-kieli ja Eclipse-ympäristö Java-ohjelma ja ohjelmaluokka

Lisätiedot

Tietorakenteet ja algoritmit

Tietorakenteet ja algoritmit Tietorakenteet ja algoritmit Muuttujat eri muisteissa Ohjelman muistialueen layout Paikallisen ja globaalin muuttujan ominaisuudet Dynaamisen muistinkäytön edut Paikallisten muuttujien dynaamisuus ADT

Lisätiedot

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen Metodit Metodien määrittely Metodin parametrit ja paluuarvo Metodien suorittaminen eli kutsuminen Metodien kuormittaminen 1 Mikä on metodi? Metodi on luokan sisällä oleva yhteenkuuluvien toimintojen kokonaisuus

Lisätiedot

Rakenteiset tietotyypit Moniulotteiset taulukot

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

Lisätiedot

Ohjelmointi 1 Taulukot ja merkkijonot

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

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

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

Lisätiedot

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti C! Perusteet 19.1.2017 Palautteesta (1. kierros toistaiseksi) Toistaiseksi helppoa Miksi vain puolet pisteistä? Vaikeinta oli ohjelmointiympäristön asennus ja käyttö Vaikeaa eroavuudet Pythonin ja C:n

Lisätiedot

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

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

Lisätiedot

Kielioppia: toisin kuin Javassa

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

Lisätiedot

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

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

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti

Perusteet. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät Pasi Sarolahti C! Perusteet 19.1.2017 Palautteesta (1. kierros toistaiseksi) (Erittäin) helppoa Miksi vain puolet pisteistä? Vaikeinta oli ohjelmointiympäristön asennus ja käyttö Ei selvää että main funktion pitikin

Lisätiedot

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

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

Lisätiedot

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 15.3

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 15.3 15. Lohkot 15.1 Sisällys Tutustutaan lohkoihin. Muuttujien ja vakioiden näkyvyys sekä elinikä erityisesti operaation lohkossa. Nimikonfliktit. Muuttujat operaation alussa vai myöhemmin? 15.2 Lohkot Aaltosulkeet

Lisätiedot

Tietotekniikan valintakoe

Tietotekniikan valintakoe Jyväskylän yliopisto Tietotekniikan laitos Tietotekniikan valintakoe 2..22 Vastaa kahteen seuraavista kolmesta tehtävästä. Kukin tehtävä arvostellaan kokonaislukuasteikolla - 25. Jos vastaat useampaan

Lisätiedot

Olio-ohjelmointi Javalla

Olio-ohjelmointi Javalla 1 Olio-ohjelmointi Javalla Olio-ohjelmointi Luokka Attribuutit Konstruktori Olion luominen Metodit Olion kopiointi Staattinen attribuutti ja metodi Yksinkertainen ohjelmaluokka Ohjelmaluokka 1 Olio-ohjelmointi

Lisätiedot

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++? JAVA-OHJELMOINTI 3op A274615 JAVAN PERUSTEET LYHYT KERTAUS Teemu Saarelainen [email protected] Lähteet: http://java.sun.com/docs/books/tutorial/index.html Vesterholm, Kyppö: Java-ohjelmointi,

Lisätiedot

Sisällys. 15. Lohkot. Lohkot. Lohkot

Sisällys. 15. Lohkot. Lohkot. Lohkot Sisällys 15. Lohkot Tutustutaan lohkoihin. Muuttujien ja vakioiden näkyvyys sekä elinikä erityisesti operaation lohkossa. Nimikonfliktit. Muuttujat operaation alussa vai myöhemmin? 15.1 15.2 Lohkot Aaltosulkeet

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

Dynaaminen muisti. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät 2017.

Dynaaminen muisti. Pasi Sarolahti Aalto University School of Electrical Engineering. C-ohjelmointi Kevät 2017. C! Dynaaminen muisti 9.2.2017 Agenda Kertausta merkkijonoista Dynaaminen muisti Valgrind-perusteet ja esimerkkejä Seuraava luento to 2.3. Ei harjoituksia arviointiviikolla 13.2. 17.2. 2 Palautetta merkkijonoihin

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

Ohjelmointikieli TIE Principles of Programming Languages Syksy 2017 Ryhmä 19

Ohjelmointikieli TIE Principles of Programming Languages Syksy 2017 Ryhmä 19 Ohjelmointikieli TIE-20306 Principles of Programming Languages Syksy 2017 Ryhmä 19 Juho Kärnä Ville Mäntysaari 1. Johdanto D on yleiskäyttöinen, strukturoitu, staattisesti tyypitetty, käännettävä ohjelmointikieli

Lisätiedot

Osoitin ja viittaus C++:ssa

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

Lisätiedot

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

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

Lisätiedot

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

811120P Diskreetit rakenteet

811120P Diskreetit rakenteet 811120P Diskreetit rakenteet 2016-2017 4. Joukot, relaatiot ja funktiot Osa 3: Funktiot 4.3 Funktiot Olkoot A ja B joukkoja. Funktio joukosta A joukkoon B on sääntö, joka liittää yksikäsitteisesti määrätyn

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

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 16.3

Lohkot. if (ehto1) { if (ehto2) { lause 1;... lause n; } } else { lause 1;... lause m; } 16.3 16. Lohkot 16.1 Sisällys Tutustutaan lohkoihin. Muuttujien ja vakioiden näkyvyys sekä elinikä erityisesti operaation lohkossa. Nimikonfliktit. Muuttujat operaation alussa vai myöhemmin? 16.2 Lohkot Kaarisulut

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

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

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2 4. Attribuutit 4.1 Sisällys Yleistä attribuuteista. Näkyvyys luokan sisällä ja ulkopuolelta. Attribuuttien arvojen käsittely aksessoreilla. 4.2 Yleistä Luokan lohkossa, mutta metodien ulkopuolella esiteltyjä

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

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

815338A Ohjelmointikielten periaatteet 2014-2015

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

Lisätiedot

Ohjelmoinnin perusteet Y Python

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

Lisätiedot

815338A Ohjelmointikielten periaatteet

815338A Ohjelmointikielten periaatteet 815338A Ohjelmointikielten periaatteet 2015-2016 IV.3 Imperatiivinen ohjelmointi aliohjelmat Sisältö 1. Yleistä aliohjelmista 2. Proseduurit ja funktiot 3. Parametrien välittäminen 4. Taulukon välittäminen

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 [email protected] 1. Java-ohjelmoinnin alkeita Tietokoneohjelma Java-kieli ja Eclipse-kehitysympäristö Java-ohjelma ja luokka

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

Moduli 4: Moniulotteiset taulukot & Bittioperaatiot

Moduli 4: Moniulotteiset taulukot & Bittioperaatiot C! : Moniulotteiset taulukot & Bittioperaatiot 15.3.2016 Agenda Pieni kertausharjoitus Moniulotteiset taulukot Esimerkki taulukoista Tauko (bittitehtävä) Binäärioperaatioista Esimerkki (vilkaistaan IP

Lisätiedot

18. Abstraktit tietotyypit 18.1

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

Lisätiedot

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

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2

Sisällys. Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2 4. Attribuutit 4.1 Sisällys Yleistä attribuuteista. Näkyvyys luokan sisällä. Tiedonkätkentä. Aksessorit. 4.2 Yleistä Luokan lohkossa, mutta metodien ulkopuolella esiteltyjä muuttujia ja vakioita. Esittely

Lisätiedot

811120P Diskreetit rakenteet

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

Lisätiedot

Tietorakenteet. JAVA-OHJELMOINTI Osa 5: Tietorakenteita. Sisällys. Merkkijonot (String) Luokka String. Metodeja (public)

Tietorakenteet. 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ätiedot

Algoritmit 1. Luento 3 Ti Timo Männikkö

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

Lisätiedot

12. Javan toistorakenteet 12.1

12. Javan toistorakenteet 12.1 12. Javan toistorakenteet 12.1 Sisällys Yleistä toistorakenteista. Laskurimuuttujat. While-, do-while- ja for-lauseet. Laskuri- ja lippumuuttujat. Tyypillisiä ohjelmointivirheitä. Silmukan rajat asetettu

Lisätiedot

Groovy. Niko Jäntti Jesper Haapalinna Group 31

Groovy. Niko Jäntti Jesper Haapalinna Group 31 Groovy Niko Jäntti Jesper Haapalinna Group 31 Johdanto Groovy on Apachen kehittämä Javaan perustuva dynaaminen oliopohjainen ohjelmointikieli. Kielen kehitys alkoi vuonna 2003, versio 1.0 julkaistiin 2007

Lisätiedot

Sisällys. 20. Javan omat luokat. Java API. Pakkaukset. java\lang

Sisällys. 20. Javan omat luokat. Java API. Pakkaukset. java\lang Sisällys 20. Javan omat luokat Application Programming Interface (API). Pakkaukset. Merkkijonoluokka String. Math-luokka. Kääreluokat. 20.1 20.2 Java API Java-kielen Application Programming Interface (API)

Lisätiedot

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista Sisällys 1. Omat operaatiot Yleistä operaatioista. Mihin operaatioita tarvitaan? Oman operaation määrittely. Yleisesti, nimeäminen ja hyvä ohjelmointitapa, määreet, parametrit ja näkyvyys. HelloWorld-ohjelma

Lisätiedot

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

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

Lisätiedot

1. luento. Ohjelmointi (C) T0004 Syksy 2003. 1. luento. 1. luento. 1. luento. 1. luento. kurssin sisältö ja tavoitteet työmuodot.

1. luento. Ohjelmointi (C) T0004 Syksy 2003. 1. luento. 1. luento. 1. luento. 1. luento. kurssin sisältö ja tavoitteet työmuodot. EVTEK Teknillinen ammattikorkeakoulu Ohjelmointi (C) T0004 Syksy 2003 Olli Hämäläinen kurssin sisältö ja tavoitteet työmuodot luennot 1-2/2003 laboratorioharjoitukset 1-2/2003 kotitehtävät, laboratoriokerrat

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

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes) Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes) Kääreluokista Javan alkeistietotyypit ja vastaavat kääreluokat Autoboxing Integer-luokka Double-luokka Kääreluokista Alkeistietotyyppiset muuttujat (esimerkiksi

Lisätiedot

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

1. Olio-ohjelmointi 1.1

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

Lisätiedot

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit IDL - proseduurit 25. huhtikuuta 2017 Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo

Concurrency - Rinnakkaisuus. Group: 9 Joni Laine Juho Vähätalo Concurrency - Rinnakkaisuus Group: 9 Joni Laine Juho Vähätalo Sisällysluettelo 1. Johdanto... 3 2. C++ thread... 4 3. Python multiprocessing... 6 4. Java ExecutorService... 8 5. Yhteenveto... 9 6. Lähteet...

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

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014 18. syyskuuta 2014 IDL - proseduurit Viimeksi käsiteltiin IDL:n interaktiivista käyttöä, mutta tämä on hyvin kömpelöä monimutkaisempia asioita tehtäessä. IDL:llä on mahdollista tehdä ns. proseduuri-tiedostoja,

Lisätiedot