1.06k likes | 1.3k Views
Johdatus Informaatioteknologiaan I Turun yliopisto, Informaatioteknologian laitos, periodi 1 / 2011 Lasse Bergroth. Yleistä. Luennot: Tiistaisin kello 12 – 14, luentosalina Alpha Torstaisin kello 14 – 16, luentosalina Alpha Yhteensä 12 tuntia Luennoitsija:
E N D
Johdatus Informaatioteknologiaan ITurun yliopisto, Informaatioteknologian laitos, periodi 1 / 2011Lasse Bergroth
Yleistä • Luennot: • Tiistaisin kello 12 – 14, luentosalina Alpha • Torstaisin kello 14 – 16, luentosalina Alpha • Yhteensä 12 tuntia • Luennoitsija: • Lasse Bergroth, työpiste Turussa ICT-talo, 4. kerros, huone B4094 • Tavattavissa parhaiten torstaisin kello 12 – 14. • Yhteystiedot: sähköposti: bergroth@utu.fi, puhelin (02) 333 8670 / Turku, 333 8592 / Salo • Esitietovaatimukset: • Ei edeltäviä pakollisia kursseja: Kurssi JIT1 on tietojenkäsittelytieteen opintojen ensimmäinen peruskurssi • Tentit: – Kolme tenttiä: 2011-10-10, 2011-11-21, 2012-01-09 – Viimeinen tenttipäivistä ei ole vielä vahvistettu tiedekunnassa – Tentteihin pitää ilmoittautua viimeistään viikkoa etukäteen laitoksen verkkosivujen kautta • Kurssin kotisivu:http://staff.cs.utu.fi/opinnot/kurssit/Salo/syksy2011/JohdatusInformaatioteknologiaanI.htm
Yleistä • Kurssin suoritustavat • Luennot + koneellisesti, omalla ajalla suoritettavat VILLE-harjoitustehtävät + tentti ei siis erillisiä tauludemonstraatioita • VILLE-tehtäviä pystyy tekemään 2011-09-08 lähtien, ja niiden suorittamisen viimeinen hyväksytty päivämäärä on 2011-10-09 (päivää ennen ensimmäistä tenttiä) • VILLE-tehtävät jakautuvat aihepiirinsä mukaisesti kuuteen eri tehtäväkokonaisuuteen, joista jokaisesta pitää saada kerättyä vähintään 40 % tarjolla olevista pisteistä • Minimivaatimuksen ylittävät pisteet luetaan hyväksi tenttiä arvosteltaessa porrastetusti siten, että täydet 100 % VILLE-tehtävien pisteistä tuottavat noin tehtävän verran lisäpisteitä tenttiin sekä tentistä läpi pääsy että korkean arvosanan saavuttaminen helpottuvat! • Tentti muodostuu viidestä kysymyksestä, joista kukin on 8 pisteen arvoinen: maksimipistemäärä on 40. • Hyväksyttyyn tenttiin vaaditaan puolet pisteistä eli 20 pistettä.
Kurssin tavoitteet • Antaa perustiedot algoritmeista, niiden muodostamisesta ja ominaisuuksista mitä eri ominaisuuksia algoritmeilta vaaditaan? • Kurssilla esitellään pseudokieli, joka on tarpeeksi ilmaisuvoimainen algoritmien kirjoittamiseen. varsinaiset ohjelmointikielet eroavat siitä lähinnä vain syntaktisesti: kontrollirakenteet ja perustietotyypit ovat yhdenmukaiset pseudokielen omaksuminen madaltaa kynnystä varsinaisten ohjelmointikielten omaksumiselle • Selvittää, miten reaalimaailman ongelman ratkaisemiseksi käsiteltävät tiedot muunnetaan tietokoneella esitettävään muotoon katsaus muuttujiin, eri tietotyyppeihin ja yksinkertaisiin tietorakenteisiin • Kurssilla Johdatus informaatioteknologiaan II perehdytään tätä kurssia syvällisemmin algoritmien teoreettisiin ominaisuuksiin
Kurssin sisältö • Johdanto 1.1 Terminologiaa 1.2 Tietokone: rakenne ja toimintaperiaate 1.3 Ohjelmointikielet, ohjelmat ja ohjelmistot 1.4 Algoritminen ongelmanratkaisu • Algoritmien suunnittelu 2.1 Algoritmin perusvaatimukset 2.2 Ohjelmointikielet 2.2.1 Syntaksi, semantiikka ja pragmatiikka 2.3 Algoritmien asteittainen tarkentaminen 2.4 Imperatiivinen paradigma 2.4.1 Muuttuja, tyyppi, lause, lauseke ja asetuslause 2.4.2 Lauseiden suoritusjärjestys
Kurssin sisältö 2.5 Ohjausrakenteet 2.5.1 Peräkkäisyys 2.5.2 Valintalauseet ja totuusarvoiset lausekkeet 2.5.3 Toistolauseet 2.5.4 Lajitteluesimerkki 2.6 Modulaarisuus 2.6.1 Abstraktiot 2.6.2 Moduulit 2.6.3 Parametrit 2.6.4 Proseduurit ja funktiot 2.6.5 Yhteenveto 2.7 Rekursio ja iteraatio 2.7.1 Rekursio 2.7.2 Iteraatio 2.7.3 Rekursio vai iteraatio? 2.8 Tieto- ja tallennusrakenteet (?)
Kurssikirjallisuutta • Kurssin JIT1 sisältö, kuten myös tämä kalvopaketti, perustuvat lehtori Jorma Bobergin luentomonisteeseen Johdatus tietojenkäsittelytieteeseen, Turun yliopisto, täydennyskoulutuskeskus, kesäkuu 2010 • luentomonisteen voi tulostaa omaan käyttöönsä pdf-versiona verkko-osoitteestahttp://staff.cs.utu.fi/staff/jorma.boberg/Mat/JTKTMoniste_16_06_2010.pdf • kurssilla käytettävän pseudokielen syntaksi löytyy puolestaan täältä: http://staff.cs.utu.fi/staff/jorma.boberg/Mat/ImperatiivinenPseudoKieli.pdf
1 Johdanto1.1 Terminologiaa • Algoritmilla tarkoitetaan yksikäsitteistä ohjeistusta tietyn tehtävän suorittamiseksi (esimerkiksi kahvin keittäminen, laskujen maksaminen verkkopankissa, toisen asteen yhtälön ratkaiseminen jne.) • Algoritmin käsite liitetään usein tietokoneisiin, mutta sen suorittaja voi yhtäläisesti olla ihminen tai vaikkapa robotti. • Riippuen siitä, kuka/mikä algoritmin suorittaa, sen esitystapa voi vaihdella melkoisesti! • Ihmisen suorittama (prosessoima) algoritmi voidaan yleensä esittää luonnollista kieltä käyttämällä, mikäli tarkasteltava ongelma on luonteeltaan sellainen, ettei riskiä väärinkäsityksiin ole (esimerkiksi ruoan valmistaminen keittokirjan ohjeiden mukaan). • Mikäli ohjeistus sen sijaan vaatii täsmällistä ja/tai tiivistä määrittelyä, on turvallisempaa esittää toimintaohje jotain formaalista kieltä käyttämällä (vrt. matematiikan kaavat), vaikka ratkaisijana olisikin ihminen eikä kone. • Tietokoneelle tehtävä on kuvattava tarkoin tiettyjä kielioppisääntöjä noudattaen tarvitaan avuksi ohjelmointikieli, jotta konetta voidaan ohjeistaa halutulla tavalla koneen ymmärtämällä tavalla.
Tietojenkäsittelytieteet pitävät sisällään sekä tietojenkäsittelytieteen että tietojärjestelmätieteen (vrt. tietojenkäsittelytieteiden koulutusohjelma). • Perinteisen näkökulman mukaan tietojenkäsittelytiede tutkii algoritmeja ja niiden abstrakteja ominaisuuksia matemaattis-luonnontieteellisestä näkökulmasta. • Nykyisin tietojenkäsittelytieteeseen katsotaan kuuluvaksi myös teknillistieteellinen lähestymistapa, jossa algoritmit ovat osana tietokonejärjestelmää, jolloin myös itse tietokone ja sen toimintaperiaate ovat algoritmien ohella keskeisiä tietojenkäsittelytieteen tutkimusalueita. • Tietojärjestelmätiede tutkii sen sijaan sekä tietokonejärjestelmää että sitä käyttävää organisaatiota (esimerkiksi yritystä, sairaalaa, oppilaitosta jne.) yhtenä kokonaisuutena ei rajoitu pelkästään algoritmeihin ja laitteisiin, vaan se sisältää myös ihmisnäkökulman • Nimitystä tietotekniikka käytetään puolestaan yleensä laajennettaessa tietojenkäsittelytieteen käsitettä edelleen tietoliikennetekniikan ja digitaalielektroniikan suuntaan, toisinaan se esiintyy kuitenkin automaattisen tietojenkäsittelyn synonyyminä terminologia häilyvää!
Myös käsitys tietokoneen olemuksesta on muuttunut voimakkaasti vuosien aikana • Yleiskäsitys edelleen laite, jossa on keskusyksikkö, sekä oheislaitteina ainakin näyttö ja näppäimistö ihminen syöttää tietoja ja/tai käyttää hyväkseen tietokoneen prosessoimia tulosteita • Nykyisin kuitenkin tietokoneita käytetään usein myös upotettuina isompiin laitteisiin ja kokonaisuuksiin esimerkkejä: autot, matkapuhelimet, teollisuusrobotit yms. puhutaan ns. sulautetuista järjestelmistä, joissa ihminen ei suoraan ole tietokoneen kanssa vuorovaikutuksessa, vaan syöttö voi toimia vaikkapa mittalaitteelta, ja tulosteena on esimerkiksi auton alustan säätäminen ajo-olosuhteiden mukaan sulautettujen järjestelmien tietokoneiden suorittimet – prosessorit – voivat olla rajoittuneita ainoastaan tiettyyn erityiseen sovellustarkoitukseen
1.2 Tietokone: rakenne ja toimintaperiaate • Tietokoneiden yleistyminen on saanut aikaan yhteiskunnallisen muutoksen, jonka suuruus on rinnastettavissa viime vuosisatojen teolliseen vallankumoukseen. • Teollinen vallankumous siirsi suuria fyysisiä voimainponnistuksia vaativia töitä ihmisiltä koneiden suoritettavaksi. • Tietotekniikan käyttöönotto vapautti ihmiset puolestaan rutiininomaisista laskentaa ja suurta tiedon varastointia vaativista tehtävistä. • Sen kummemmin teollinen vallankumous kuin tietokoneiden käyttöönottokaan ei kuitenkaan tehnyt ihmisen fyysistä voimaa eikä vastaavasti ajatteluakaan tarpeettomaksi (Tieto)koneet pystyvät ainoastaan laajentamaan ihmisten fyysisiä / henkisiä voimavaroja Tietokone ei pysty ratkaisemaan ongelmia, joiden ratkaisua ihminen ei ainakaan riittävässä määrin tunne, mutta jos ratkaisu tunnetaan, tietokone voi löytää sen paljonkin nopeammin!
1.2 Tietokone: rakenne ja toimintaperiaate • Tietokone suorittaa suurella teholla hyvin yksinkertaisia perusoperaatioita, joihin palataan tarkemmin kurssilla Johdatus informaatioteknologiaan II. • Jotta reaalimaailman ongelma voidaan ratkaista tietokoneella, pitää sille täsmällisesti kertoa, mitä operaatioita koneen kulloinkin pitää suorittaa. • Tehtävän ratkaisemiseen johtavaa suoritusta kutsutaan prosessoinniksi tai laskuksi. • Prosessointia varten kone tarvitsee resursseja, joihin luetaan suorittamiseen kuluva aika, muisti sekä erilaiset oheislaitteet syöttöä ja tulostusta varten. • Tietokoneen tärkeimmät komponentit ovat siten: 1) suoritin eli prosessori, joka suorittaa varsinaisen laskennan 2) muisti, jonne varastoidaan algoritmin laskemia tuloksia 3) oheis- ja siirräntälaiteet, jotka mahdollistavat kommunikaation ulkomaailman kanssa tietokone ilman oheislaitteita olisi toimiva mutta varsin hyödytön • Tietokoneen muisti luokitellaan ns. keskusmuistiin ja oheismuistiin.
1.2 Tietokone: rakenne ja toimintaperiaate • Keskusmuistissa säilytetään itse suoritettavaa ohjelmaa sekä sen tarvitsemia / laskemia tietoja. toiminnaltaan nopea jakautuu vielä erilliseen pysyväismuistiin, jota voidaan vain lukea (ROM, Read-Only Memory) ja työmuistiin, jonne voidaan myös tallentaa tietoa (RAM, Random Access Memory). Ensin mainittu sisältää mm. mikro-ohjelmat, joiden mukaan koneen suorittamat alkeisoperaatiot (mm. peruslaskutoimitukset) suoritetaan. Nämä säilyvät muuttumattomina jatkuvasti. • Oheis- eli massamuistia käytetään tietojen pitkäaikaiseen varastointiin. massamuistista haku ja sinne tallentaminen vievät moninkertaisen ajan keskusmuistioperaatioihin verrattuna. • Prosessorin eli suorittimen tärkeimmät osat ovat: aritmeettis-looginen yksikkö, jossa suoritetaan mm. laskutoimitukset ja tietojen vertailuoperaatiot rekisterit tiedon varastoimiseksi nopeaa saatavuutta varten kontrolliyksikkö, joka säätelee ohjelman suorituksen etenemistä
1.2 Tietokone: rakenne ja toimintaperiaate • Termien data, informaatio ja tieto määrittely: • Datalla tarkoitetaan sovitun mukaisessa muodossa esitettyjä tietoja, jotka ovat valmiita prosessoitaviksi (esimerkiksi kyselytutkimuksen lomakkeelta koodatut tiedot yhdessä) • Informaatio tarkoittaa tietämystä, joka on merkityksellistä omistajansa kannalta: antaa toimintaohjeita, ohjaa päätöksentekoa jne. (esimerkiksi lämpömittarin arvo ohjaa ihmisen pukeutumista). • Tiedolla tarkoitetaan perillä olemista jostakin asiasta riippumatta siitä, tuottaako se omistajalleen mitään oleellista hyötyä tietyssä tilanteessa vai ei (vaikkapa suurten löytöretkien vuosilukujen ulkoa muistaminen) • Erilaisista tarkoitteistaan huolimatta kyseisiä termejä käytetään enemmän tai vähemmän toistensa synonyymeinä. • Tietokoneen toiminta perustuu pitkälti kaksi- eli binäärijärjestelmään, jossa ainoat käytettävät numerosymbolit ovat 0 ja 1. soveltuu hyvin tietokoneille, sillä nuo luvut voidaan tulkita helposti totuusarvoiksi ei ja kyllä: jokin ominaisuus joko vallitsee tai ei tarkasteluhetkellä (esimerkiksi kulkeeko sähkövirta vai ei)
1.2 Tietokone: rakenne ja toimintaperiaate • Tietokoneella on prosessorina monia etuja ihmiseen verrattuna … • Nopeus: kone pystyy suorittamaan rutiininomaisia laskutehtäviä huomattavasti ihmistä nopeammin runsasta suoraviivaista laskentaa vaativat tehtävät sopivat paremmin tietokoneiden kuin ihmisten suoritettaviksi • Luotettavuus: kone pystyy kerta toisensa jälkeen suorittamaan saman tehtävän aina samalla tavalla kuin aiemmin, eikä laskennan suuri määrä saa konetta väsymään, kun taas ihminen voisi suorituksen aikana tehdä virheitä • Muisti: toisin kuin ihmisellä, tietokoneella ei ole taipumuksena unohtaa mitään laskennan aikana saavutettuja tuloksia • Kustannukset: kolmen edellisen kohdan, tietokoneiden hinnan halpenemisen ja tehon kasvamisen yhteisvaikutuksesta sama työn tuotos voidaan saada aikaan huomattavasti vähemmin kuin ihmistyövoimaa käyttämällä, kunhan tehtävä soveltuu tietokoneen suoritettavaksi
1.2 Tietokone: rakenne ja toimintaperiaate • … mutta ei sittenkään aivan kaikessa! • Nopeus: kone suorittaa nopeasti vain rutiinilaskutoimituksia. sen sijaan suorituksen aikaista päättelyä tai strategian valintaa vaativissa tehtävissä kone häviää ihmiselle. Ihminen pystyy helpommin aavistamaan, mistä ratkaisua kannattaa lähteä etsimään. Myös motorisesti kone on huomattavasti ihmistä rajoittuneempi. • Luotettavuus: koneelta puuttuu ”maalaisjärki”. Se toistaa uskollisesti sille annettuja komentoja, vaikka niiden logiikassa olisi virhe, ja ne vain kasaantuvat ajan myötä. Ihminen pystyisi helpommin reagoimaan mielettömiin tuloksiin. • Muisti: vaikkakin tietokoneen muisti on normaaliolosuhteissa erinomainen, siltä puuttuu luovuus, joka on tyypillistä ihmiselle, joka pystyy muistissaan yhdistelemään asioita toisiinsa. • Kustannukset: tietokonejärjestelmät eivät ole ilmaisia, ja lisäksi ne vaativat ylläpitotyötä ja erityisosaamista yrityksissä. Ei kannata automatisoida ilman mittakaavaetuja.
1.3 Ohjelmointikielet, ohjelmat ja ohjelmistot • On olemassa useita formalismeja tietokoneiden ”käskemiseksi”. Näitä kutsutaan ohjelmointikieliksi. • Ohjelmointikieliä on olemassa useita kymmeniä, ja monet niistä on kehitetty tiettyjä, erikoistuneita sovellusalueita varten. • Ensimmäinen yleiskäyttöinen ohjelmointikieli, FORTRAN, on edelleen käytössä mm. raskaaseen tieteelliseen laskentaan liittyvissä sovelluksissa. • Ns. korkean tason ohjelmointikielet (mm. Java, C, C++, Python, Pascal jne.) ovat lähempänä ihmisen ajatusmaailmaa kuin matalan tason kielet (mm. symbolinen konekieli eli Assembly-kieli), joilla ohjelmointi tapahtuu vahvasti koneen ehdolla. • Varsinainen konekielen käskykanta on suoraan sidoksissa käytettävään prosessoriin. Tällaiseen ns. mikro-ohjelmointiin palataan kurssilla Johdatus informaatioteknologiaan II. Mikro-ohjelmointi tapahtuu täysin koneen ehdoilla. Se on varsin primitiivisen tuntuista ja hyvin kaukana ihmisen käsitemaailmasta. • Ohjelmointiprosessissa reaalimaailman ongelmalle kehitetty algoritminen ratkaisu muunnetaan tietokoneelle suoritettavaan muotoon ohjelmointikieltä, sen kääntäjää tai tulkkia ja linkittäjää käyttäen.
Algoritmin muuntaminen suorituskelpoiseksi ohjelmaksi Ohjelmointi Käytettävän kielen säännöt Lausekielinen ohjelma Algoritmi Kääntäjä Käännös Konekielinen ohjelma Muut tarvittavat konekieliset ohjelmat Linkittäjä Linkitys Suorituskelpoinen konekielinen ohjelma Syöttötiedot Suoritus Tulostiedot
1.3 Ohjelmointikielet, ohjelmat ja ohjelmistot • Mitä korkeamman tason kieli, sitä ”helpompaa” ohjelmointi on, mutta vastaavasti käännös- tai tulkkausprosessi tulee työläämmäksi. • Matalan tason kielten hankala ohjelmoitavuus ”palkitaan” tehokkaampana suorituskelpoisena ohjelmana. • Kääntäjä on systeemiohjelma, joka muuntaa ohjelmoijan kirjoittaman tietokoneohjelman konekieliseen muotoon. Mikäli ohjelma ei ole kirjoitettu kielen kielioppisääntöjen mukaisesti, se joudutaan korjaamaan ennen uutta käännösyritystä. • Myös linkittäjä (tai linkkaaja) on systeemiohjelma. Sen tarkoituksena on koota useassa palassa käännetyt saman ohjelman osat yhdeksi kokonaisuudeksi. • Kääntäjien ja linkittäjien lisäksi myös käyttöjärjestelmät lasketaan kuuluviksi systeemiohjelmiin. Käyttöjärjestelmä huolehtii mm. koneen oheislaitteiden tahdistuksesta ja tietojen pitkäaikaissäilytyksestä. Systeemiohjelmiin palataan kurssilla JIT2. • Systeemiohjelmien vastakohtina pidetään sovellusohjelmia, jotka ovat joko valmisohjelmia tai käyttäjän itsensä tekemiä ohjelmia johonkin tiettyyn käyttötarkoitukseen.
1.4 Algoritminen ongelmanratkaisu • Algoritmin suorittaminen tietokoneella on systemaattinen toimenpide, joka voidaan esittää algoritmisesti seuraavasti: • Esitä algoritmi sopivalla ohjelmointikielellä • Suorita ohjelma tietokoneella • MUTTA: algoritmin muodostaminen ei ole algoritmisesti ratkeava ongelma, vaan se vaatii aina älyllistä ponnistelua (esimerkiksi uuden ruokareseptin kehittämistä ei voida automatisoida). Ei ole mahdollista kirjoittaa algoritmia algoritmin muodostamiseksi! • Systeemiohjelmien vastakohtina pidetään sovellusohjelmia, jotka ovat joko valmisohjelmia tai käyttäjän itsensä tekemiä ohjelmia johonkin tiettyyn käyttötarkoitukseen. • Jotta ongelma voitaisiin ratkaista tietokoneella, sille pitää olla algoritminen ratkaisu, joka tunnetaan riittävän tarkoin kaikissa ongelman esiintymissä. Algoritmiin ei saa jäädä aukkoja tai tulkinnanvaraa. Siten tehtävän täsmällinen määrittely on oleellisen tärkeää. • Täsmällisyys on tarpeen myös silloin, kun suorittajana on ihminen koneen asemesta (esimerkiksi määrää kuvaavat ilmaukset ”ripaus”, ”hieman” jne. vaativat arvostelukykyä ruoan valmistajalta).
Algoritmisen ongelmanratkaisun vaiheet Tehtävän määrittely Formalisoitu ongelma Ongelmanratkaisu Reaalimaailman ongelma Algoritminen ratkaisu: Algoritmi + Tietorakenne Ohjelmointi Ohjelma Ohjelman suoritus Linkittäjä Formaalinen ratkaisu Ratkaisun tulkinta Ratkaisu reaalimaailmassa
1.4 Algoritminen ongelmanratkaisu • Tietokoneella suoritettavan algoritmisen ongelmanratkaisun vaiheet pääpiirteittäin: 1. Törmätään reaalimaailmassa ongelmaan, joka halutaan ratkaista algoritmisesti. 2. Formuloidaan asetettu ongelma eksaktiin muotoon. 3. Keksitään ongelmalle algoritminen ratkaisu, ja esitellään algoritmi ja sen tarvitsemat tietorakenteet. 4. Muodostetaan algoritmin pohjalta lausekielinen ohjelma, joka käännetään ja tarvittaessa linkitetään. 5. Tietokoneohjelmalle annetaan sen tarvitsemat syötetiedot, minkä jälkeen kone laskee ratkaisun ongelmalle. 6. Koska saavutettu ratkaisu noudattaa koneelle sopivaa esitysmuotoa, se on vielä tulkittava selkokielellä alkuperäisen ongelman ratkaisuksi. • Algoritmit ovat koneesta ja kielestä riippumattomia. Toisin sanoen, laitteiden ja ohjelmointikielten kehittyminen ei tee niitä hyödyttömiksi! • Ilman algoritmeja ei ole ohjelmia, ja ilman ohjelmia tietokoneet olisivat tarpeettomia!
2 Algoritmien suunnittelu2.1 Algoritmin perusvaatimukset • Algoritmilla perustuu tehtävän määritykseen ja on täsmällinen ja yksityiskohtainen ohje siitä, miten tehtävä suoritetaan. • Tehtävän pitää olla riittävän täsmällisesti määritelty, jotta sille voitaisiin muodostaa algoritmi. • Esimerkki: Tehtävänasettelu ”Etsi lukujen suurin yhteinen tekijä” on liian väljä, sillä siitä ei käy ilmi, montako lukua voidaan antaa syötteeksi ja millaisia luvut ovat. Pitää tosin paikkansa, että moni ymmärtäisi tehtävän siten, että lukuja on kaksi ja että ne ovat positiivisia kokonaislukuja. Tämä tarkennus on kuitenkin syytä tehdä, jotta tehtävänanto olisi yksikäsitteinen. Syöttötiedot ja odotetut tulokset määriteltävä tarkoin! • Algoritmin pitää täyttää kolme perusvaatimusta: 1) Yleisyys: algoritmin pitää ratkaista ongelma sen kaikille tapauksille 2) Deterministisyys: jokaisessa vaiheessa suoritusta on tiedettävä yksiselitteisesti, miten vaiheesta edetään
2.1 Algoritmin perusvaatimukset 3) Tuloksellisuus: algoritmin palauttama tulos on a) aina oikeellinen ja b) tulos löydetään äärellisessä ajassa (laskenta ei saa jatkua loputtomiin) • Esimerkki: Jos algoritmin pitää ratkaista kahden positiivisen kokonaisluvun x ja y suurin yhteinen tekijä syt(x, y), algoritmin pitää toimia oikein riippumatta siitä, miten suuria syötetyt luvut ovat, kunhan ne vain ovat vaaditun kaltaisia, eli x > 0 ja y > 0. Sen sijaan algoritmin ei tarvitse ratkaista ongelmaa määritellyn arvoalueen ulkopuolisille luvuille (esim. x = -3, y = 7 x laiton) • Esimerkki: ”Vastaus on kolme” ei ole selvästikään ole yleinen kahden kokonaisluvun x ja y yhteenlaskualgoritmi, vaikka se monille syötteiden arvokombinaatioille tuottaakin oikean ratkaisun (esim. x = 11, y = -8; x = 0, y = 3; x = -49, y = 52 jne.)! Sen sijaan se kelpaisi ratkaisualgoritmiksi vain silloin, kun syötteiksi annettavien kokonaislukujen vaadittaisiin toteuttavan yhtälö y = 3 – x.
2.1 Algoritmin perusvaatimukset • Äskeisen naiivin esimerkin perusteella on helppo ymmärtää, että yksi hyvän algoritmin kriteereistä on sen yleisyys mitä laajemmalle syötejoukolle algoritmi toimii, sen käyttökelpoisempi ja hyödyllisempi se tavallisesti on! määrittelyjoukon väkisin, itsetarkoituksella tapahtuva laajentaminen saattaa kuitenkin tarpeettomasti heikentää laskennan tehoa silloin, kun laajennettua osaa määrittelyjoukosta ei ilmeisesti tarvita (esimerkiksi varautuminen kompleksiluvuilla laskemiseen, kun niitä ei pitäisi esiintyä) • Deterministisyys on tiukka vaatimus, jota ei voida soveltaa ns. vapaajärjesteisiin algoritmeihin, joissa seuraavaksi valittava toiminto voidaan valita tietystä joukosta kiinnittämättä sitä yksikäsitteisesti. Eniten tarkasteltaviin eli ns. imperatiivista paradigmaa noudattaviin algoritmeihin deterministisyysvaatimus sen sijaan istuu hyvin.
2.1 Algoritmin perusvaatimukset • Tuntuisi ensi alkuun ilmeiseltä, ettei algoritmin tuloksellisuusvaatimuksesta ole syytä tinkiä, mutta tästäkin on poikkeuksia: 1) On olemassa algoritmeja, joiden suorituksen ei koskaan halutakaan päättyvän (esimerkiksi kulkuneuvojen paikanvarausjärjestelmät, sairaalan potilastietokantojen ylläpito jne.) 2) Tarkan ratkaisun löytyminen voi kestää kauan, eikä se ole välttämättä tarpeen, vaan nopeasti laskettavissa oleva likimääräinen ratkaisu on riittävä (esimerkiksi ns. kauppamatkustajan ongelma) tähän palataan kurssilla Algoritmien suunnittelu ja analysointi) 3) Tietyllä, hyvin suurella todennäköisyydellä saatava oikeellinen tulos voidaan laskea nopeasti, kun taas takuuvarmasti oikean ratkaisun löytäminen voi kestää kauan ollaan valmiita ottamaan riski, ettei vastaus olekaan oikea (mm. eräät graafi- ja satunnaisalgoritmit) • Ilman hyvin perusteltua syytä ei esitetyistä algoritmin perusvaatimuksista pidä tinkiä, mutta järkeä pitää käyttää ja kompromisseja tehdä, mikäli vaatimusten täyttäminen vaatii kohtuuttomasti resursseja (aikaa, muistia). • Lisäksi pitää muistaa, että jotkin ongelmat ovat niin hankalia, että niiden algoritminen suoritus vain kauan – sille ei vain voi mitään!
2.2 Ohjelmointikielet • Tietyt luonnollisten kielten ominaisuudet tekevät niistä hankalasti sovellettavia algoritmien esittämiseen: 1) Laaja sanasto sama asia voidaan ilmaista usealla eri tavalla 2) Monimutkaiset kielioppisäännöt vaikeuttavat algoritmien laatimista 3) Lauseiden kontekstisidonnaisuus merkitys muuttuu asiayhteyden mukaan 4) Perustuvat viime kädessä puhuttuun kieleen elekieltä voidaan upottaa tekstiin välimerkkejä käyttämällä (esim. !?) 5) Käyttö vaatii maailmankuvan ymmärtäminen saattaa vaatia asioiden taustan tuntemista • Ohjelmointikielissä nämä luonnollisen kielen hankaloittavat tekijät on pyritty minimoimaan, mutta … • … tästä huolimatta monimerkityksisyyttä esiintyy jonkin verran.
2.2 Ohjelmointikielet esimerkiksi Pascal-ohjelmointikielessä kaksoispistettä (:) seuraa var-lohkossa muuttujan esittely, case .. of –rakenteessa tietyn vaihtoehdon toteutumista seuraavat toiminnot, ja jos sitä seuraa yhtäsuuruusmerkki (:=), se aloittaakin asetuslauseen! • Ohjelmointikieliä on useita muun muassa siksi, että 1) Ei ole löydetty yleisesti hyväksyttyä parasta tapaa kirjoittaa ohjelmia 2) Sovellusalueet vaihtelevat laidasta laitaan, joten samalla myös tarvittavat algoritmit eroavat tyypiltään toisistaan oleellisesti 3) Ohjelmointikielen hyvyys saattaa riippua käytettävän tietokoneen arkkitehtuurista ja käskykannasta 4) Halutaan kehittää aina vain parempia kieliä 5) Halutaan luoda eri tyyppisille ohjelmoijille sopivia kieliä heidän toiveidensa ja osaamisensa mukaisesti mitä korkeamman tason kieli, sitä lähempänä se on ihmisen muodostamaa abstraktia käsitemaailmaa ja helpommin sovellettavissa työvälineeksi, kun taas matalan tason kielet vaativat ohjelmointia koneen ehdoilla, mutta vastaavasti niillä saadaan useasti tuotettua tehokkaampia ohjelmia
2.2 Ohjelmointikielet • Ohjelmointikielen suunnittelussa huomioitavia seikkoja 1) Kielen tulee helpottaa algoritmien ilmaisemista tietokoneen ymmärtämässä muodossa. 2) Kielen tulee olla helposti tietokoneen ymmärrettävissä. 3) Kielen tulee olla helposti ihmisen ymmärrettävissä, jotta ohjelmia voidaan tarvittaessa helposti muuttaa. 4) Kielen tulee minimoida virhemahdollisuudet ohjelmaa kirjoitettaessa. 5) Kielellä kirjoitettua ohjelmaa tutkimalla pitäisi olla helppo vakuuttua siitä, että ohjelma todella kuvaa juuri halutun prosessin. 2.2.1 Syntaksi ja semantiikka • Prosessorin on pystyttävä tulkitsemaan sille suoritettavaksi annettu algoritmi, joten seuraavien kahden ehdon pitää toteutua: 1) Prosessorin tulee ymmärtää ne symbolit, joilla algoritmi esitetään, eli käytetyn kielen aakkostoja kielioppi. 2) Prosessorin tulee ymmärtää jokaisen askeleen merkitys.
2.2.1 Syntaksi ja semantiikka • Ohjelmointikielen kielioppi eli syntaksi määrää, miten kieleen kuuluvia symboleja voidaan laillisesti käyttää. kielioppisäännöt määräävät, onko ohjelmoijan kirjoittama ”kirjoitelma” käytettävän ohjelmointikielen mukainen • Syntaksi vastaa kysymykseen: ”Miten (ohjelmia kuuluu kirjoittaa)?”. • Syntaksivirhe estää kirjoitetun ohjelman kääntämisen konekielelle ja siten myös sen suorittamisen aiheutuu käännösaikainen virhe • Ohjelmointikielen syntaksi on suppea luonnolliseen kieleen verrattuna. Sitaatti kirjasta Lauri Malmi: Ohjelmoinnin perusteet ja Pascal-kieli:”Ohjelmointikielen kääntäjä ei pysty lähellekään samaan kuin ihminen, joka kykenee ymmärtämään toisen puhuman tai kirjoittaman sanoman, vaikka siinä olisi paljonkin virheitä.” • Esimerkkejä syntaksivirheistä: 1) Te kuuntelee luentoa. (joko subjekti virheellinen tai predikaatti väärässä persoonamuodossa) 2) a += b; (jos kyseessä on Pascal-ohjelma, ilmaus on virheellinen, mutta C-kielellä se on mahdollinen (muuttujan a arvoon lisätään muuttujan tai vakion b arvo)
2.2.1 Syntaksi ja semantiikka • Oppi (ohjelmointi)kielen lauseiden merkityksestä eli semantiikka määrää, mitä kielen lauseet tarkoittavat. semantiikka antaa lauseelle tulkinnan • Semantiikka vastaa kysymykseen: ”Mitä (kielen lause merkitsee)?”. • Luonnollisen kielen mukaisessa ilmauksessa semanttinen virhe ilmenee järjettömänä asiasisältönä, mutta lause voi silti olla syntaktisesti täysin kelvollinen. • Ohjelmassa esiintyvät semanttiset virheet eivät estä ohjelman kääntämistä, mutta ne voivat aiheuttaa ajonaikaisen virheen ja siten pakottaa ohjelman suorituksen keskeytymään. Syntaksivirheet paljastuvat helpommin kuin semanttiset virheet! • Esimerkkejä semanttisista virheistä: 1) Banaani söi apinan. (ei vaikuta kovinkaan uskottavalta tarinalta …) 2) Kirjoita vuoden 13. kuukauden nimi. (yleisesti käytössä olevan kalenterin mukaan tällaista ei ole)3) asetuslause a := b/c silloin, kun c saa arvon nolla. (nollalla jakaminenei ole sallittu aritmeettinen operaatio)
2.2.1 Syntaksi ja semantiikka • Voidakseen tulkita algoritmin prosessorin tulee 1. tuntea algoritmin kuvauksessa käytetyt symbolit 2. osata liittää kuhunkin askeleeseen sen merkitys suoritettavien operaatioiden muodossa 3. kyetä suorittamaan operaatiot • Semanttisten virheiden paljastuminen on usein ehdollista: edellisen sivun esimerkin kohdassa 3 mahdollisesti tapahtuvaa nollalla jakoa ei välttämättä milloinkaan esiinny, kun c on muuttuja. • Syntaksin ja semantiikan ohella ohjelmointikieleen kuuluu myös ns. pragmatiikka, joka määrää, mitä tarkoitusta varten jokin lause on sijoitettuna juuri johonkin tiettyyn kohtaan ohjelmassa. Pragmatiikka vastaa kysymykseen ”Miksi?”. • Kontekstin kannalta virheellisesti sijoitettuihin eli pragmaattisilla virheillä tarkoitetaan algoritmin (tai ohjelman) logiikassa olevia virheitä. Loogiset virheet ilmenevät siten, ettei kirjoitettu algoritmi loppujen lopuksi suoritakaan sitä tehtävää, jonka sen olisi tarkoitus suorittaa. Loogisten virheiden löytäminen on yleensä huomattavasti työläämpää kuin ohjelman puhdistaminen syntaktisista ja semanttisista virheistä!
2.3 Algoritmien asteittainen tarkentaminen • Muutamia yksinkertaisia ongelmia lukuun ottamatta algoritmin suunnittelu on monimutkainen ja älyllistä ponnistusta vaativa prosessi. • Tärkeä syy tähän: tietokone ei pysty päättelemään, toisin kuin ihminen, vaan sitä pitää käskeä ”kädestä pitäen”. • Siten algoritmin onnistunut suunnittelu lähtee väistämättä liikkeelle aina täsmällisestä tehtävän määrittelystä: - Millainen ongelma halutaan ratkaista? - Mitä tietoja on käytettävissä: ts. mitkä ovat syöttötiedot? - Miten ratkaisu määräytyy ja missä muodossa se esitetään? • Voidaan lähteä liikkeelle tehtävän karkean tason kuvauksesta, jota jalostetaan tarkemmaksi asteittain aina niin pitkälle, että kaikki tarpeelliset vaiheet ja toiminnot on selvitetty riittävän yksityiskohtaisesti, jotta algoritmin suorittaja pystyy ne ymmärtämään yksikäsitteisesti. • Reduktiolla tarkoitetaan alkuperäisen osittamista alkuperäistä pienempiin osatehtäviin, joiden ratkaisuista kootaan lopulta koko alkuperäisongelman ratkaisu alkuperäinen ongelma redusoidaan. • Algoritmiikassa ongelman redusointia itsenäisiksi osa-algoritmeiksi kutsutaan modularisoinniksi, ja yksittäisiä aliongelmia moduuleiksi.
2.3 Algoritmien asteittainen tarkentaminen • Esimerkki asteittaisesta tarkentamisesta: pikakaakaon keittäminen • Muodostetaan aluksi karkean tason algoritmi:(1) Keitä vettä(2) Pane kaakaojauhoja kuppiin(3) Kaada vettä kuppiin • Useimmille ihmisille kyseinen algoritmi on jo riittävän informatiivinen, mutta tarkennetaanpa esitystä kaiken varalta yksityiskohtaisemmaksi:(1.1) Täytä vesipannu(1.2) Aseta pannu liedelle(1.3) Lämmitä, kunnes vesi kiehuu(1.4) Siirrä pannu lieden sivuun(2.1) Ota kaakaopurkki esiin(2.2) Pane purkista 3 lusikallista kaakaota kuppiin(2.3) Pane lusikka kuppiin(2.4) Pane kaakaopurkki pois
2.3 Algoritmien asteittainen tarkentaminen (3.1) Nosta vesipannu kupin yläpuolelle(3.2) Kallista pannua niin, että vesi valuu kuppiin(3.3) Odota, kunnes kuppi on täynnä(3.4) Suorista pannu vaakasuoraan(3.5) Laske vesipannu liedelle • Edelleenkin saatetaan joutua tarkentamaan lisää:(1.1.1) Aseta vesipannu vesihanan alle(1.1.2) Avaa vesihana(1.1.3) Odota, kunnes pannu on täynnä(1.1.4) Sulje vesihana … ja niin edelleen!
2.3 Algoritmien asteittainen tarkentaminen • Algoritmimme ensimmäinen vaihe – veden keittäminen – näyttäisi asteittaisen tarkentamisen jälkeen nyt seuraavanlaiselta: (1) Keitä vettä (1.1) Täytä vesipannu (1.1.1) Aseta vesipannu vesihanan alle (1.1.2) Avaa vesihana (1.1.3) Odota, kunnes pannu on täynnä (1.1.4) Sulje vesihana (1.2) Aseta pannu liedelle (1.3) Lämmitä, kunnes vesi kiehuu (1.3.1) Pane liesi päälle (1.3.2) Odota, kunnes vesi kiehuu (1.3.2.1) Odota, kunnes pannu viheltää (1.3.3) Pane liesi pois päältä (1.4) Siirrä pannu lieden sivuun • Numeroinnin tasojen kasvaessa abstraktiotaso madaltuu ja kuvaus tarkentuu yksityiskohtaisemmaksi.
2.4 Imperatiivinen paradigma • Perinteinen käsitys algoritmeista: • suorittajina toimivat koneet • algoritmin suoritus perustuu siihen, että konetta käsketään tekemään tietyt toimenpiteet tietyssä järjestyksessä antamalla sille komentoja • Edellä kuvattu käsitys yhdessä perinteisen tietokoneen mallinnuksen kanssa ovat johtaneet yleisimpään ohjelmoinnin lähestymistapaan eli paradigmaan: imperatiiviseen ohjelmointiin • Tälläkin kurssilla kaikki esitettävät algoritmit noudattavat imperatiivista paradigmaa käyttämällä ns. pseudokieltä, joka sisältää tavallisimpiin imperatiivisiin ohjelmointikieliin sisältyvät rakenteet vasta kurssin JIT2 loppupuolella tarkastellaan lyhyesti muita lähestymistapoja algoritmeihin ohjelmointiin • Imperatiivinen algoritmi koostuu peräkkäisistä lauseista eli käskyistä, joihin kuuluvat: 1) asetuslause 2) valintalauseet (IF – THEN, IF – THEN – ELSE ja CASE..OF) 3) toistolauseet (FOR, WHILE ja REPEAT..UNTIL) 4) syöttö- ja tulostustoiminnot mahdollistavat lauseet (Lue(x) ja Tulosta(x)), missä x kuvaa, mitä luetaan/tulostetaan.
2.4 Imperatiivinen paradigma • Imperatiivisessa ohjelmoinnissa tärkeitä käsitteitä ovat: 1) muuttuja 2) tyyppi 3) lauseke (aritmeettinen tai totuusarvoinen) 4) lause (asetus, valita tai toisto) 5) moduuli (≈ metodi, aliohjelma), sen määrittely sekä kutsu • Imperatiivinen algoritmi kuvaa prosessia, joka muuntaa syötteen tulosteeksi. • Prosessissa käytetään hyväksi muuttujia, joihin talletetut arvot voivat vaihtua (yleensä myös vaihtuvat!) prosessin suorituksen aikana. • Algoritmin muuttuja on rinnastettavissa tietokoneen muistipaikkaan. • Algoritmin käskyt muuttavat muistipaikkojen sisältöä ja siten myös suoraan laskennan tilaa, joka määräytyy muuttujien tietosisällön kombinaatioina. • Muuttujan asema imperatiivisessa algoritmissa on erittäin keskeinen: itse asiassa koko ohjelman toiminta perustuu muuttujien arvojen hyväksi käyttämiseen ja niiden muutoksiin. 2.4.1 Muuttuja, tyyppi, lause, lauseke ja asetuslause
2.4.1 Muuttuja, tyyppi, lause, lauseke ja asetuslause • Imperatiivinen ohjelmointiajattelu on tiiviissä yhteydessä abstraktiin konemalliin, jossa ohjelmoija joutuu ajattelemaan ratkaisua koneen ehdoin. aikaisemmin tietokone oli ohjelmoijaa huomattavasti määräävämmässä asemassa: kaikki toiminta tapahtui koneen ehdoilla nykyisin asetelma on jokseenkin päinvastainen • Nykyisistä imperatiivisista kielistä kuitenkin huomattava osa on varsin korkealla abstraktiotasolla kääntäjien kehittyessä ohjelmointityö on saatu huomattavasti lähemmäs ihmisen ajattelumallia itse kone toimii kuitenkin likimain entisiä periaatteita noudattaen, mutta sen näkyvyys ohjelmoijalle ei ole enää läheskään niin voimakasta kuin muutamaa vuosikymmentä aiemmin • Imperatiivisen algoritmin yksittäisiä käskyjä tai komentoja sanotaan lauseiksi. • Lauseke on puolestaan ilmaus, johon voi sisältyä erilaisia muuttujia, vakioita, funktion kutsuja tai laskutoimituksia. • Lauseen ja lausekkeen väliset tärkeimmät erot: 1) lausekkeella on arvo, lauseella (yleisesti tulkittuna) ei. 2) lause on itsenäinen komento, mutta lauseke ei voi esiintyä yksinään.
2.4.1 Muuttuja, tyyppi, lause, lauseke ja asetuslause • Asetus- eli sijoituslauseella asetetaan muuttujalle (uusi) arvo. • Oletus tällä kurssilla: algoritmin suorituksen alkaessa muuttujalla ei ole mitään arvoa, vaan se pitää tarvittaessa alustaa sopivalla alkuarvolla. • Asetuslauseen syntaksi pseudokielessä on:muuttuja := lausekemissä muuttuja on jokin kirjaimista ja numeroista koostuva merkkijono ja lauseke tälle muuttujalle kelvollisen arvon tuottava ilmaus.Esimerkkejä: 1) pituus := 180 (Muuttujan pituus arvoksi asetetaan 180.) 2) x := y (Muuttujan [tai vakion] y arvo sijoitetaan muuttujanx arvoksi.) 3) z := max(x, y) (Muuttujan z arvoksi asetetaan x:n ja y:n maksimi.) 4) x := 2*x + 3*y (Muuttujalle x asetetaan uusi arvo, joka saadaan kertomalla ensiksi sen vanha arvo kahdella ja lisäämällä siihen muuttujan [tai vakion] y arvo kolmella kerrottuna.)
2.4.1 Muuttuja, tyyppi, lause, lauseke ja asetuslause • Huomioitavaa edellisestä esimerkistä: • Asetuslauseen vasemmalla puolella tulee aina sijaita muuttuja, mutta oikealla puolella voi sijaita vakio (tapaus 1), muuttujan [tai vakion] tunnus (tapaus 2), funktion kutsu (tapaus 3)tai operaattoreiden avulla muodostettu millainen tahansa näiden yhdistelmä eli lauseke (tapaus 4). • Operaattori voi olla joko aritmeettinen eli lukuarvon tuottava (esimerkiksi +, -, *, /, DIV ja MOD) tai looginen (esimerkiksi AND, OR, NOT) eli totuusarvon tuottava. • Asetusoperaattori merkitään kurssimme pseudokielessä, samoin kuin Pascal-ohjelmointikielessä perättäisillä kaksoispisteellä ja yhtäsuuruusmerkillä (:=), mutta esimerkiksi C- ja Java-kielissä asetusoperaattorina on pelkkä yhtäsuuruusmerkki (=). • Operaattoreilla on tietyt laskentajärjestys- eli ns. presedenssisäännöt. Esimerkiksi kerto- ja jakolaskuoperaatiot suoritetaan ennen yhteen- ja vähennyslaskuja (esimerkiksi lausekkeesta 3 + 2*x – 6 lasketaan ensiksi tulo 2*x ennen yhteen- ja vähennyslaskujen suorittamista). • Laskentajärjestykseltään samanvahvuiset operaatiot lasketaan vasemmalta oikealle. Algoritmeja (ja ohjelmia) kirjoitettaessa on kuitenkin syytä käyttää sulkeita apuna, jos lausekkeeseen sisältyy sekä kerto- että jakolaskuja, jotta varmistetaan lausekkeen oikea tulkinta (oletusjärjestys vasemmalta oikealle ei päde välttämättä kaikille kääntäjille).
2.4.1 Muuttuja, tyyppi, lause, lauseke ja asetuslause Esimerkki: lauseke 2 / 8 * 3 lasketaan normaalisti (2/8) * 3 = 6/8 = 3/4, mutta jokin kääntäjä saattaisi jäsentää sen toisin, koska kerto- ja jakolaskuoperaatioiden presedenssit ovat samat: saataisiin 2 / (8*3) = 2/24 = 1/12. • Asetuslauseen semantiikka: ensiksi lasketaan asetusoperaattorin (:=) oikealla puolella olevan lausekkeen arvo, joka sijoitetaan sitten vasemmalla puolella esiintyvän muuttujan arvoksi. Muuttujan edellinen arvo häviää. • Tällä kurssilla muuttujilla ei ole mitään arvoa, ennen kuin sellainen ensimmäistä kertaa niille asetetaan. Muuttujat ovat tätä ennen alustamattomia. Alustamaton muuttuja ei saa esiintyä asetuslauseen oikealla puolella. (tyypillinen virhe algoritmissa/ohjelmassa) • Kannattaa huomioida, että esimerkiksi x := x + 1 on usein täysin järkevä asetuslause muuttujan x arvoa kasvatetaan ykkösellä nykyisestä arvostaan. HUOM! Tätä ei pidä sekoittaa matematiikassa mahdottomaan yhtälöön x = x + 1! • Lausekkeen, muuttujan tai vakion tyyppi kertoo, miten sen arvo pitää tulkita.
2.4.1 Muuttuja, tyyppi, lause, lauseke ja asetuslause • Perustyyppeihin kuuluvat kokonais- ja desimaaliluvut (liukuluvut), merkit, totuusarvot ja merkkijonot. • Lisäksi ohjelmoija pystyy useimmissa kielissä esittelemään muitakin tarvitsemiaan tyyppejä. • Tällä kurssilla ei tyyppejä ilmoiteta erikseen, vaan tyypitys määräytyy implisiittisesti muuttujalle asetettavan arvon tai vakion esitysmuodon perusteella. • Ns. vahvasti tyypitetyissä ohjelmointikielissä muuttujan tyyppi on aina kerrottava muuttujan esittelyn yhteydessä. Esimerkki: 1) x := 16 x on kokonaislukumuuttuja 2) y := 2.9 y on liukulukumuuttuja 3) z := ’U’ z on merkkimuuttuja 4) u := Tosi (True) u on totuusarvomuuttuja 5) v := ’Paavo’ v on merkkijonomuuttuja • Tiettyä tyyppiä olevalle muuttujalle voidaan asettaa arvoksi ainoastaan samaa tyyppiä olevien lausekkeiden arvoja. Poikkeaminen tästä vaatii tyyppimuunnoksen (esimerkiksi haluttaessa asettaa kokonaisluku liukulukumuuttujan arvoksi).
2.4.2 Lauseiden suoritusjärjestys • Imperatiivisessa paradigmassa oletuksena on, että algoritmin lauseet suoritetaan siinä järjestyksessä kuin ne on kirjoitettu ja yksi kerrallaan. • Yleisesti ottaen järjestyksen vaihtaminen muuttaa lähes aina myös algoritmin merkitystä. • Peräkkäinen käskyjen suorittaminen perustuu pitkälti perinteiseen ns. von Neumannin konemalliin, jossa käskyjä haetaan suoritettaviksi järjestyksessä yksi kerrallaan. • Koska peräkkäiskäsittely on oletuksen mukainen algoritmien ohjausrakenne, sitä ei erikseen merkitä mitenkään näkyviin. • Sen sijaan peräkkäisyydestä poikkeaminen vaihtoehtoisten toimintojen tai toistojen takia osoitetaan algoritmissa erityisin rakentein. • Muita lähestymistapoja: • Funktionaalisessa ja deklaratiivisessa ohjelmoinnissa lauseiden suoritusjärjestys ei ole samalla tavoin kriittinen kuin imperatiivisessa eli ns. proseduraalisessa ohjelmoinnissa. Näissä ei ole otettu lähtökohdaksi komentojen antamista koneelle, vaan ne perustuvat määrittelyihin, miten ratkaisua ongelmaan haetaan. • Rinnakkaisohjelmoinnissa sallitaan ohjelman osien suorittamista samanaikaisesti jakamalla suoritus useammalle kuin yhdelle prosessorille. • Näihin vaihtoehtoisiin menettelyihin palataan kurssin JIT2 lopussa.
2.5 Ohjausrakenteet • Algoritmin perusohjausrakenteet ovat peräkkäisyys, valinta ja toisto. • Ne kuvaavat järjestyksen, jossa algoritmin sisältämät toimenpiteet suoritetaan. • Algoritmit muodostetaan yhdistelemällä näitä ohjaus- eli kontrollirakenteita, jotka ovat yhdessä riittävät minkä tahansa algoritmin esittämiseen. • Ehto- ja toistorakenteissa esiintyvät, rakenteen tunnistamiseksi tarvittavat ns. varatut sanat merkitään lauseiden syntaksia esiteltäessä lihavoituina (esimerkiksi ehtolauseen aloittava IF), kun taas lauseiden osat (ehdot ja toiminnot) merkitään kursiivilla. 2.5.1 Peräkkäisyys • Kuten jo aikaisemmin todettiin, peräkkäisyys on algoritmien oletuksen mukainen ohjausrakenne, joten sitä ei erikseen merkitä mitenkään näkyviin. ellei toisin muita ohjausrakenteita käyttäen osoiteta, algoritmin lauseet suoritetaan niiden kirjoitusjärjestyksessä. • Algoritmin viimeisen lauseen suorittaminen päättää algoritmin suorituksen.
2.5.1 Peräkkäisyys • Esitetään seuraavassa esimerkki algoritmista, jossa on käytetty yksinomaan peräkkäisyyttä ohjausrakenteenaAlgoritmi: Matkustaminen Joensuusta Uppsalaan • Aja taksilla Joensuun rautatieasemalle • Nouse Turkuun menevään junaan • Jää junasta Turun satamassa • Astu Tukholmaan menevään laivaan • Nouse maihin Tukholman satamassa • Kävele metroasemalle • Aja metrolla rautatieasemalle (T-Centralen) • Nouse Uppsalaan menevään junaan • Jää junasta Uppsalassa • Myös viime luennolla esitetty algoritmi pikakaakaon keittämiseksi noudatti pelkästään peräkkäisyyttä. • MUTTA: useimmiten yksistään peräkkäisyydellä ei pystytä kuvaamaan algoritmia siten, että se toimisi kaikissa tapauksissa
2.5.1 Peräkkäisyys • Pulmatilanteita syntyy etenkin silloin, jos jokin algoritmissa kuvatuista toimenpiteistä ei suju ennakkosuunnitelmien mukaisesti. • Esimerkki: Kaakaonkeittoa kuvaavassa algoritmissa syntyy epäselvä tilanne, jos vaikkapa 1) Vesijohdosta ei tule vettä odotetaanko (ja jos niin kuinka pitkään) vai haetaanko vettä toisaalta? 2) Kaakaopurkki on tyhjä hankitaanko lisää kaakaojauhetta varastosta tai kaupasta vai ohitetaanko kaakaonlisäämisvaihe kenties kokonaan ja tarjoillaan pelkkää kuumaa vettä]?) 3) Entä, jos kaakaota halutaan useampi kuin yksi kupillinen aloitetaanko valmistus tosiaankin aina alusta veden keittämisestä, vaikka kuumaa vettä olisi valmiina 4) Entä, jos kaakaoon halutaan lisätä jotain (sokeria, maitoa, kermaa, rommia tms.? jätetäänkö asia muitta mutkitta juojan kontolle? • Selvästikään esittämämme yksinkertainen pikakaakaonkeittoalgoritmi ei ole aukoton, vaan jättää avoimia lisäkysymyksiä.
2.5.1 Peräkkäisyys • Tarkastellaan seuraavaksi vielä, miten hyvin toimii algoritmi Joensuusta Tukholmaan matkustamista varten. • Päällisin puolin kaikki voisi sujua hyvin, jos kaikki liput on valmiiksi ostettuina/varattuina, euroja ja kruunuja tuli otettua tarpeeksi mukaan eikä matkan aikana tapahdu mitään odottamatonta. • Mutkia voi kuitenkin tulla matkaan. Seuraavassa muutamia pulmia: 1) Joensuussa taksista puhkeaa rengas, minkä johdosta matkustaja myöhästyy Turun-junasta ehtiikö vielä seuraavallakin junalla laivaan, yritetäänkö ehkä lentää Turkuun, siirretäänkö matkaa vai perutaanko se kokonaan? 2) Junaliikenteessä on häiriöitä, ja juna ei ehdi ajoissa Turun satamaan jäädäänkö Turkuun odottamaan seuraavaa laivaa, yritetäänkö saada hotelliyö VR:n laskuun jne.? 3) Laiva ajaa karille pääsy Uppsalaan viivästyy varmasti: matkasuunnitelma saattaa muuttua melkoisesti 4) Terroristit tekevät iskun metroasemalle Tukholmassa matkan jatkaminen alkuperäisen suunnitelman mukaan ei välttämättä enää päällimmäisenä ajatuksena!
2.5.2 Valintalauseet ja totuusarvoiset lausekkeet • Kuten edellä havaittiin, peräkkäisyys ei ohjausrakenteena riitä kattamaan kaikkia mahdollisia algoritmeja, vaan havaittiin, että toiminta saattaa toisinaan olla ehdollista – esimerkiksi pulmatilanteen esiintyessä – ja hyvin usein muutoinkin. • Ehdollinen toiminta perustuu valintaan, joka suoritetaan deterministisesti eli yksiselitteisesti tiettyjen kriteerien avulla: tietyn esiehdon toteutuessa valitaan aina sitä vastaava toimintavaihtoehto. Epädeterministiset ongelmat sivuutetaan tässä, mutta niihin palataan lyhyesti kurssin JIT2 lopulla. • Yksinkertaisin valinnan muoto: jokin toiminto joko suoritetaan tai jätetään suorittamatta: vaihtoehtoista toimintoa ei ole. Tätä kuvaa rakenne IFehtoTHENtoimintoENDIF • Valintarakenteessa ehto on totuusarvoinen lauseke, eli se arvoltaan joko tosi tai epätosi. Siinä voi esiintyä mm. vertailuoperaattoreita. Jos ehto toteutuu, toiminto suoritetaan, minkä jälkeen jatketaan ehtolausetta seuraavasta lauseesta. Jos ehto ei toteudu, hypätään suoraan ehtolauseen jälkeiseen lauseeseen.
2.5.2 Valintalauseet ja totuusarvoiset lausekkeet Esimerkki:IFvesi kiehuu THEN pane liesi pois päältä ENDIF • Mikäli ehdon jäädessä toteutumatta halutaan suorittaa vaihtoehtoinen toiminto, pitää käyttää valintalauseesta laajennettua muotoa IFehtoTHENtoiminto1ELSE toiminto2 ENDIF Jos ehto on tosi, suoritetaan toiminto1, muutoin toiminto2. Toiminnot ovat IF-THEN-ELSE –rakenteessa toisensa poissulkevat: niistä suoritetaan tarkalleen jompikumpi – ei molempia!Esimerkki:IFx < 0 (* IF-sanaa seuraa valintaehto *)THEN Tulosta ”x on negatiivinen”ELSE Tulosta ”x on vähintään nollan suuruinen”ENDIF • Ehto voi olla yksinkertainen totuusarvon tuottava lauseke, kuten edellisessä esimerkissä, mutta se voi koostua myös usean lausekkeen yhdistelmästä.