- Ohj2, luennot 4-6, 18.2.-19.2.2005
- Algoritmeissa tarvittavia rakenteita
- Materiaali: moniste, luku 5
- Ohjausrakenteita:
- Ehto- ja valintalauseet
- Silmukat
- Suljettu silmukka (for)
- Avoin silmukka (while/do)
- Break- ja continue-lauseet
- Goto-lause
- Assembler-kielen ainoa ohjausrakenne (suora tai ehdollinen hyppy)
- goto-lauseen huolimaton käyttö on helpoin tapa saada koodista spagettia
- "mainettaan parempi", jos sitä käyttää oikein
- Tärkein käyttötapa: "pakeneminen" monta tasoa sisältävästä silmukasta (javassa break-lauseen laajennus)
- Muuttujat
- "nimettyjä muistipaikkoja"
- symbolinen esitys tallennettavasta alkiosta
- Muuttujien tietotyyppejä
- Perustyypit
- Looginen muuttuja (boolean)
- C:ssä toteutettu lukuna: 0 epätosi, muut tosia
- Muissa kielissä vie tilaa yleensä tavun verran, vaikka periaatteessa bittikin riittäisi!
- Merkit
- C/C++:ssa 8-bittinen
- Javassa 16-bittinen (Unicoden vanha vesio)
- Luvut
- Lukualueita 8,16,32, 64 bittiä
- Etumerkillinen tai etumerkitön (javassa aina etumerkillisiä)
- Merkkijonot
- Useimmissa kielissä ei ole perustyyppi!
- C:ssä merkkitaulukko, C++:ssa ja Javassa olio (Javassa lisäksi erityissyntaksia), Pascalissa perustyyppi
- Osoittimet ja viitteet
- Osoitin: tiettyyn muistipaikkaan (muuttujaan, lukuun, taulukkoon, tietueeseen, olioon...) viittaava muuttuja
- Osoittimen omalla muistipaikalla ei yleensä ole merkitystä (poikkeus: C:n taulukkokäsittely), vaan muistipaikalla, johon osoitin viittaa
- Erityistapaus: NULL (nil)-osoitin ei osoita mihinkään.
- C++:ssä erikseen osoittimet, viitteet ja konkreettiset muuttuja
- Viite on C++:ssa kuin osoitin, jonka osoittamaa paikkaa ei voi muuttaa
- Konkreettisilla (automaattisilla) muuttujilla konstruktoria ja destruktoria kutsutaan automaattisesti
- Dynaamista muistinvarausta käytettäessä virheitä sattuu erittäin helposti!
- Pascalissa olioita käsitellään viitteillä, vain perustyypit ja merkkijonot konkreettisia
- Varsinaisia osoittimia voi myös käyttää, mutta ei yleensä tarvita
- Vaatii totuttelua, jos on tottunut C++:n tapaan
- Osittainen "roskienkeruu" komponenttien viitelaskurin avulla
- Huom. _osittainen_. Vaatii tarkkuutta lähes yhtä paljon kuin C++ erityisesti koostetuilla komponenteiila
- Javassa "ei ole osoittimia", mutta olioita käsitellään viitteillä, joiden osoittamaa paikkaa voidaan muuttaa
- Viitesemantiikka vaatii Pascalin tapaan totuttelua C++:aan tottuneille
- perustyypit: merkit ja luvut (char, int jne) - ovat konkreettisia "pinomuuttujia". Kaikki muut (mukaanlukien merkkijonot, taulukot ja perustyyppien olioesitykset Int, Char ym) ovat olioita, joita käsitellään aina viitteillä
- Roskienkeruu - olioita ei tarvitse tuhota itse. Johtaa erilaiseen ohjelmointityyliin kuin C++:lla huolimatta samanlaisesta syntaksista
- Automatiikasta voi olla myös haittaa, koska ei ole standardia 'resurssien vapautinta', jota voisi kutsua turvallisesti itse.
- Vaikka virtuaalikone huolehtii muistista, on myös muita resursseja, joita pitää varata ja vapauttaa: esim. tietokanta- ja verkkoyhteydet, ikkunat.
- Osoittimia käyttämällä on mahdollista tehdä hankalia virheitä: tyypillisiä ovat NULL-osoittimen käyttäminen varattuna oliona tai (ei javassa) jo vapautetun muistialueen käyttö.
- Oliosta toiseen viittaavat osoittimet aiheuttavat olioihin keskinäisiä riippuvuuksia (ja a viittaa b:hen ja b viittaa a:han, kumpi "omistaa" kumman?)
- Javassa on alussa liian helppoa sekoittaa viite ja konkreettinen olio - esim. funktion parametrina saama olioviite ja pääohjelman vastaavat "argumenttiolioviite" viittaavat samaan olioon!
- Ks. myös "Osoitinkyselyn yhteenveto" (MN)
- [ http://www.mit.jyu.fi/~vesal/kurssit/cpp/materiaali/osoitin/index.html ]
- Esimerkkejä
- Rakenteisia tietotyyppejä
- [ http://appro.mit.jyu.fi/2002/kesa/johdatusohjelmointiin/luennot/luento21/index.html ]
- Taulukot /array, vector)
- On helppo päästä mihin tahansa alkioon
- On helppo muuttaa mitä tahansa alkiota
- On "vaikeaa" lisätä tai poistaa keskeltä
- Javassa olioita
- Tietueet, unionit (struct, record)
- Kootaan yhteenliittyviä tietoja yhteen, ei toiminnallisuutta
- Unionit vain C/C++:ssa, Javassa tietueet ovat olioita ilman metodeja
- Luetellut tyypit (enum)
- Nyt myös Javan viimeisimmässä versiossa
- Aiemmin toteutettu int-vakioilla
- Joukot (set)
- Löytyy Pascalista, Javassa toteutettu oliona
- Operaatioita: yhdisteet, leikkaukset, komplementit, joukkoon kuuluvuus...
- Yhdistelmiä: moniulotteiset taulukot, osoitintaulukot...
- Esimerkki: sanakirja moniulotteisena taulukkona (tuskin kannattaa toteuttaa näin)
- C(++):ssa mahdollista valita, käytetäänkö konkreettisten olioiden taulukkoa vai osoitintaulukkoa...
- Javassa lähes kaikki taulukota ovat "osoitintaulukoita" poislukien int (ei Int)-tyyppisistä perustyypeistä kootut taulukot
- Aliohjelmat (alialgoritmit)
- Voidaan jakaa proseduureihin ja funktioihin
- Esim: paistoaliohjelma
- C-kielessä tärkeä osoittimien käyttötarkoitus: parametrit, joiden arvoja aliohjelma muuttaa
- Tämän takia C:llä on mahdotonta tehdä juuri mitään hyödyllistä ilman osoittimia
- C++:ssa viitteet vähentävät hieman osoittimien käyttötarvetta
- Lyhyesti: tietotyypit ja ohjausrakenteet ovat peruskoneistoa, joita algoritmin rakentaminen vaatii. Ohjelmointikielen tasolla ne voivat olla konkreettisia tyyppejä, olioita tai kielen standardikirjastoon kuuluvia rakenteita
- Vaikka jokin kieli ei tiettyä rakenteista tyyppiä sisältäisikään, se voitaisiin pienellä lisätyöllä toteuttaa
- Algoritmin suunnitteluvaiheessa tietotyypit ja ohjausrakenteet helpottavat yksityiskohtaista suunnittelua ohjelmointikieliriippumattomalla tavalla
- Pöytätesti
- Esimerkki: alkuluvun tutkiminen
- Vihje: lähes jokaisessa Ohj2-kurssin tentissä on ollut yhtenä tehtävänä pöytätestin tekeminen
- Propositiologiikan alkeita
- loogiset muuttujat
- loogiset operaattorit: and, or, not, xor, implikaatio jne...
- laskusääntöjä
- de morganin kaavat (käytetään sievennyksessä)
- päättelysäännöt
- suora päättely (jos A ja A=B, niin B), ristiriidasta päättely (jos A:sta seuraa ristiriita, niin -A)...
- käytössä matematiikan todistuksissa
- totuustaulut
- totuustauluilla voidaan todistaa propositiologiikan väitteitä
- esimerkki: bal=kyllä-tehtävä
- predikaattilogiikka (kaikki, on olemassa -operaattorit) vaatisi järeämpää kalustoa
- lyhyesti: if-lauseiden rakentaminen ja algoritmin erilaisten vaihtoehtojen huomiointi vaatii loogisten lausekkeiden hahmotusta
- lisätietoa: Matemaattisen logiikan kurssi
- Esimerkkejä eri kielistä
- Lisätietoa:
- Ohjelmointiparadigmoja (vrt. edellinen luento)
- Imperatiivinen
- Proseduraalinen
- Olio-ohjelmointi
- Puhtaita oliokieliä: Smalltalk, Java. Moniparadigmakieliä: C++, Python
- Deklaratiivinen
- Funktio-ohjelmointi
- Esim. Haskell, Scheme, Lisp (moniparadigma), XSLT
- Logiikkaohjelmointi
- Muitakin jaotteluja on (esim. kone vs. lausekielet, käännetyt kielet vs. skriptikielet)...
- Skriptikieliä:
- JavaScript (web-selain)
- PHP (web-palvelin)
- UNIX/Linux-komentotulkkien kielet: BASH, CSH ym
- Käännettyjä kieliä:
- Käännetyn ja skriptikielen välimaastossa ovat mm. Java, Python ja C#, joiden koodi on virtuaalikoneelle käännettyä, mutta virtuaalikoneen suoritus on tulkattua
- Muita laskennan malleja
- Huom. HTML ei ole ohjelmointikieli, vaikka siinä onkin ohjelmointikieliä muistuttavia rakenteita
- Ohjelmointikielen täytyy olla "turing-täydellinen", eli sillä voidaan ratkaista mikä tahansa laskettavissa oleva ongelma kuten Turingin koneella
- HTML ei laske - sillä vain kuvataan dokumentin looginen rakenne
- Toisaalta XSLT on ohjelmointikieli, koska sillä voidaan teoriassa tehdä mielivaltaisen monipuolisia muunnoksia XML-dokumentilta toiselle (XML-syntaksi tosin heikentää kielen "kirjoitettavuutta")
- Ohjelman kirjoitusprosessi (huom. ei koko kehitysprosessi)
- Koodin kirjoitus
- (esikääntäminen)
- Kääntäminen
- Javalla tuloksena .class -luokkatiedosto
- Muilla kielillä (C/C++, Pascal, Fortran ym) tuloksena konekielikoodinen objektitiedosto
- (staattinen) linkittäminen
- Javassa käytössä dynaaminen linkitys (vrt. DLL), joten erillistä linkitysvaihetta ei tarvita
- Muilla kielillä tuloksena ohjelman omista objektitiedostoista ja yleisistä kirjastotiedostoista koottu ajettava ohjelma
- Javalla tätä sivuaa lähinnä pakettien (JAR) riippuvuuksien hallinta, joka varsinkin suuremmissa projekteissa voi käydä varsin hankalaksi ilman aputyökaluja
- ajaminen / testaus / debuggaus
- Huom. uudet IDEt (Integrated Development Environment) hämärtävät tehokkaasti kirjoitusprosessia, mutta siitä on hyvä olla tietoinen
- IDE = yhdistetty editori, kääntäjä, linkkeri, debuggeri (joissakin myös uml-editori, dokumentaatioselain, web-palvelin jne)
- Myös komentorivipohjaisia ratkaisuja edelleen käytössä (esim. Emacs-editori, make/ant-projektinhallinta, grep-haku ym ym)
- Pohjimmiltaan IDEtkin käyttävät joukkoa eri komentorivisovelluksia!
- Esimerkkejä eri kielistä
- Java
- Lisätietoa
- Kielestä ja kirjastoista
- Java vs. C++
- Java == "C++ done right"? - version 1.5 myötä java muistuttaa yhä enemmän C++:aa (Templatet, luetellut tyypit)
- vrt. Ohj-kurssin C++ -luentomoniste
- C++ -tyylinen syntaksi
- C++:sta puuttuvia Javan ominaisuuksia:
- AUTOMAATTINEN MUISTINSIIVOUS (roskienkeruu)
- Synkronointi (kriittisiä lohkoja koodin sisällä, helpottaa monisäikeisten sovellusten tekemistä)
- Serialisointi (tuki minkä tahansa olion lataamiselle ja tallennukselle)
- Äärimmäisen laaja standardikirjasto (kurssin puitteissa ehditään keskittyä lähinnä kielen perus- ja säiliöluokkiin, paketit java.lang ja java.util) - ks. alla
- Javasta puuttuu:
- operaattorien kuormitus (olennaisesti syntaktista sokeria c++:ssa)
- moniperintä (voidaan hyvin pitkälle korvata rajapinnoilla)
- suora muistinkäsittely (osoitinaritmetiikka) - tämä on lähinnä hyvä asia. Tarpeelliset asiat saa tehtyä viitteillä
- eksplisiittinen olion tuhoaminen c++:n deleten tapaan - aiheuttaa pieniä ongelmia resurssien hallinnassa (esim. tietokantayhteydet, tiedostokahvat...)
- Java kirjasto- ja komponenttikokoelmana
- Säiliöt
- Käyttöliittymäkirjastot (AWT; Swing, SWT)
- Tietokantaohjelmointi (JDBC)
- Verkko-ohjelmointi (Socketit, RPC, RMI, CORBA, EJB...)
- XML:n käsittely (DOM- ja SAX-rajapinnat)
- Rajapinnat muihin kieliin ja käyttöjärjestelmän palveluihin
- ... (ks. javan dokumentaatio)
- Java-työkaluja
- Komentorivi! java, javac, javadoc, jar
- Käytännössä kaikki java-kehittimet käyttävät näitä sisäisesti
- Kehittyneempään käyttöön: JUnit (yksikkötestit), Ant (projektit, "make" javalle)
- Borland JBuilder
- Kaupallinen (perusversiot ilmaisia)
- NetBeans
- Ilmainen, open source
- Sun:in sponsoroima, kaupallinen versio SunONE
- Eclipse
- Ilmainen, open source
- IBM:n sponsoroima, kaupallinen versio myös saatavilla?
- Erikoisuutena oma natiivikomponentteihin nojaava käyttöliittymäkirjasto SWT
- Suunniteltu yleiseksi ohjelmistonkehitysalustaksi (javan lisäksi esim. C++, Python..), runsaasti Plug-ineja
- Työkalun valinta on makuasia. Erityisesti uusimmat versiot ovat ominaisuuksien puolesta hyvin lähellä tosiaan.
- Jokaisen koodaajan ammattitaitoon kuuluu myös komentorivikääntäminen tarpeen tullen
- Esimerkkejä
- monisteen java-alkeet
- [ http://www.mit.jyu.fi/vesal/kurssit/ohj2/moniste/esim/java-alk/ ]
- Fibonaccin luvut
- printf javalla - toteutettu java 5:een PrintWriter-luokkaan, käsitellään myöhemmin
- Vanhemmissa java-versioissa ks. esim. Henrik Bengtssonin printf, muitakin löytyy
- [ http://www.braju.com/ ]
- Miksi vasta java 5:een? funktio vaatii vaihtelevan määrän parametreja, jota ei ollut kielessä aiemmin (aiemmissa toteutuksissa käytetty formataointiin oliotaulukkoa)