Commit 9607f840fd62fd563e49a668975a1205457d6bda

  • avatar
  • Samuel Uusi-Mäkelä <kaiutindev @gm…l.com> (Committer)
  • Thu Jun 05 16:12:45 EEST 2014
  • avatar
  • Samuel Uusi-Mäkelä <kaiutindev @gm…l.com> (Author)
  • Thu Jun 05 16:12:45 EEST 2014
added data
timApp/static/data/images/luentomonistecsUusin_htm_13ded424.gif
(13 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_194ffc3.png
(47 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_1b70689e.png
(218 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_207ef69a.gif
(11 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_266e7b42.gif
(7 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_2e6e1c93.gif
(12 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_356ed562.png
(13 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_373fc74f.png
(43 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_453c7491.png
(9 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_45faf2c8.gif
(4 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_4ce95e8f.png
(5 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_51840fcf.png
(65 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_5219b95e.png
(449 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_54d2cbea.png
(39 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_6743054f.gif
(19 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_6974859.gif
(14 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_74f89f25.png
(101 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_75ff594f.png
(35 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_77f7f118.png
(9 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_7deb6236.png
(7 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_7fd89c6a.gif
(22 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_821ea7c.png
(145 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_e600629.gif
(22 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m12339dd1.png
(18 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m12b38605.png
(28 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m16b63f32.png
(94 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m19490db5.gif
(11 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m1a3c9cf7.gif
(14 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m1cf175a9.gif
(64 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m28552086.gif
(19 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m28cb3581.jpg
(48 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m2a659b.png
(44 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m2f07591b.gif
(11 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m373c2e01.png
(9 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m38354e6c.gif
(14 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m3838408a.png
(17 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m3c4cba2e.gif
(14 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m48da2e91.png
(53 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m490d411b.gif
(4 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m502edb07.gif
(4 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m5634df04.png
(117 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m5638d5c8.png
(184 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m58b94a29.png
(86 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m5dfaebb8.png
(25 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m601d313b.gif
(11 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m6406473.gif
(13 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m692570a4.png
(11 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m6dff106.gif
(7 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m6ff43568.gif
(64 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m71545d14.gif
(4 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m793342fb.png
(34 / 0)
Binary files differ
timApp/static/data/images/luentomonistecsUusin_htm_m7a47ee4d.gif
(9 / 0)
Binary files differ
timApp/static/data/ohjelmointi1/block_00001
(2 / 0)
  
1Esipuhe
2=======
timApp/static/data/ohjelmointi1/block_00002
(13 / 0)
  
1Tämä moniste on luentomoniste kurssille Ohjelmointi 1. Luentomoniste
2tarkoittaa sitä, että sen ei ole tarkoitus korvata kunnon kirjaa, vaan
3esittää asiat samassa järjestyksessä ja samassa valossa kuin ne
4esitetään luennolla. Jotta moniste ei paisuisi kohtuuttomasti, ei
5asioita käsitellä missään nimessä täydellisesti. Siksi opiskelun tueksi
6tarvitaan jokin hyvä aihetta käsittelevä kirja, sekä rutkasti
7ennakkoluulotonta asennetta ottaa asioista selvää. Tuorein tieto löytyy
8tietenkin netistä. On myös huomattava, että useimmat saatavilla olevat
9kirjat keskittyvät hyvin paljon tiettyyn ohjelmointikieleen—erityisesti
10aloittelijoille tarkoitetut. Osin tämä on luonnollista, koska ihmisetkin
11tarvitsevat jonkin yhteisen kielen kommunikoidakseen toisen kanssa.
12Siksi ohjelmoinnin aloittaminen ilman, että ensin opetellaan jonkun
13kielen perusteet, on aika haastavaa.
timApp/static/data/ohjelmointi1/block_00003
(10 / 0)
  
1Jäsentämisen selkeyden takia kirjoissa käsitellään yleensä yksi aihe
2perusteellisesti alusta loppuun. Aloittaessaan puhumaan lapsi ei
3kuitenkaan ole kykeneväinen omaksumaan kaikkea tietyn lauserakenteen
4kieliopista. Vastaavasti ohjelmoinnin alkeita kahlattaessa
5vastaanottokyky ei vielä riitä kaikkien kikkojen käsittämiseen. Tässä
6monisteessa ja luennolla asioiden käsittelyjärjestys on sellainen, että
7asioista annetaan ensin esimerkkejä tai johdatellaan niiden tarpeeseen,
8ja sitten jonkin verran selitetään mistä oli kyse. Tästä syystä tästä
9monisteesta saa yhden näkemyksen mukaisen pintaraapaisun asioille ja
10kirjoista ja nettilähteistä asiaa on syvennettävä.
timApp/static/data/ohjelmointi1/block_00004
(14 / 0)
  
1Tässä monisteessa käytetään esimerkkikielenä *C\#*-kieltä. Kuitenkin
2nimenomaan esimerkkinä, koska monisteen rakenne ja esimerkit voisivat
3olla aivan samanlaisia mille tahansa muullekin ohjelmointikielelle.
4Tärkeintä on nimenomaan ohjelmoinnin ajattelutavan oppiminen. Kielen
5vaihtaminen toiseen samansukuiseen kieleen on ennemmin verrattavissa
6Savon murteen vaihtamisen Turun murteeseen, kuin suomen kielen
7vaihtamisen ruotsin kieleen. Toisin sanoen, jos yhdellä kielellä on
8oppinut ohjelmoimaan, kykenee jo lukemaan toisella kielellä
9kirjoitettuja ohjelmia pienen harjoittelun jälkeen. Toisella kielellä
10kirjoittaminen on hieman haastavampaa, mutta samat rakenteet sielläkin
11toistuvat. Ohjelmointikielet tulevat ja menevät. Tätäkin vastaavaa
12kurssia on pidetty Jyväskylän yliopistossa seuraavilla kielillä:
13Fortran, Pascal, C, C++, Java ja nyt C\#. Joissakin yliopistoissa
14aloituskielenä on Python.
timApp/static/data/ohjelmointi1/block_00005
(6 / 0)
  
1Ohjelmointia on täysin mahdotonta oppia pelkästään kirjoja lukemalla.
2Siksi kurssi sisältää luentojen ohella myös viikoittaisten
3harjoitustehtävien (demojen) tekemistä, ohjattua pääteharjoittelua
4tietokoneluokassa sekä harjoitustyön tekemisen. Näistä lisätietoa,
5samoin kuin kurssilla käytettävien työkalujen hankkimisesta ja
6asentamisesta löytyy kurssin kotisivuilta:
timApp/static/data/ohjelmointi1/block_00006
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2https://trac.cc.jyu.fi/projects/ohj1
3```
timApp/static/data/ohjelmointi1/block_00007
(4 / 0)
  
1Tämä moniste perustuu Martti Hyvösen ja Vesa Lappalaisen syksyllä 2009
2kirjoittamaan *Ohjelmointi 1* -monisteeseen, joka osaltaan sai muotonsa
3monen eri kirjoittajan työn tuloksena aina 80-luvulta alkaen. Suurimman
4panoksen monisteeseen ovat antaneet Timo Männikkö ja Vesa Lappalainen.
timApp/static/data/ohjelmointi1/block_00008
(1 / 0)
  
1Jyväskylässä 2.1.2013
timApp/static/data/ohjelmointi1/block_00009
(1 / 0)
  
1Martti Hyvönen, Vesa Lappalainen, Antti-Jussi Lakanen
timApp/static/data/ohjelmointi1/block_00010
(2 / 0)
  
11. Mitä ohjelmointi on?
2=======================
timApp/static/data/ohjelmointi1/block_00011
(10 / 0)
  
1Ohjelmointi on yksinkertaisimmillaan toimintaohjeiden antamista ennalta
2määrätyn toimenpiteen suorittamista varten. Ohjelmoinnin kaltaista
3toimintaa esiintyy jokaisen ihmisen arkielämässä lähes päivittäin.
4Algoritmista esimerkkinä voisi olla se, että annamme jollekulle
5puhelimessa ajo-ohjeet, joiden avulla hänen tulee päästä perille
6ennestään vieraaseen paikkaan. Tällöin luomme sarjan ohjeita ja
7komentoja, jotka ohjaavat toimenpiteen suoritusta. Alkeellista
8ohjelmointia on tavallaan myös mikroaaltouunin käyttäminen, sillä
9tällöin uunille annetaan ohjeet siitä, kuinka kauan ja kuinka suurella
10teholla sen tulee toimia.
timApp/static/data/ohjelmointi1/block_00012
(11 / 0)
  
1Kaikissa edellisissä esimerkeissä oli siis kyse yksikäsitteisten
2ohjeiden antamisesta. Kuitenkin esimerkit käsittelivät hyvinkin
3erilaisia viestintätilanteita. Ihmisten välinen kommunikaatio,
4mikroaaltouunin kytkimien kiertäminen tai nappien painaminen, samoin
5kuin videon ajastimen säätö laserkynällä ovat ohjelmoinnin kannalta
6toisiinsa rinnastettavissa, mutta ne tapahtuvat eri työvälineitä
7käyttäen. Ohjelmoinnissa työvälineiden valinta riippuu asetetun tehtävän
8ratkaisuun käytettävissä olevista välineistä. Ihmisten välinen
9kommunikaatio voi tapahtua puhumalla, kirjoittamalla tai näiden
10yhdistelmänä. Samoin ohjelmoinnissa voidaan usein valita erilaisia
11toteutustapoja tehtävän luonteesta riippuen.
timApp/static/data/ohjelmointi1/block_00013
(7 / 0)
  
1Ohjelmoinnissa on olemassa eri tasoja riippuen siitä, minkälaista
2työvälinettä tehtävän ratkaisuun käytetään. Pitkälle kehitetyt korkean
3tason työvälineet mahdollistavat työskentelyn käsitteillä ja
4ilmaisuilla, jotka parhaimmillaan muistuttavat luonnollisen kielen
5käyttämiä käsitteitä ja ilmaisuja, kun taas matalan tason työvälineillä
6työskennellään hyvin yksinkertaisilla ja alkeellisilla käsitteillä ja
7ilmaisuilla.
timApp/static/data/ohjelmointi1/block_00014
(2 / 0)
  
1Eräänä esimerkkinä ohjelmoinnista voidaan pitää sokerikakun
2valmistukseen kirjoitettua ohjetta:
timApp/static/data/ohjelmointi1/block_00015
(13 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2Sokerikakku
3
46 munaa
51,5 dl sokeria
61,5 dl jauhoja
71,5 tl leivinjauhetta
8
91. Vatkaa sokeri ja munat vaahdoksi.
102. Sekoita jauhot ja leivinjauhe.
113. Sekoita muna-sokerivaahto ja jauhoseos.
124. Paista 45 min 175°C lämpötilassa.
13```
timApp/static/data/ohjelmointi1/block_00016
(6 / 0)
  
1Valmistusohje on ilmiselvästi kirjoitettu ihmistä varten, vieläpä
2sellaista ihmistä, joka tietää leipomisesta melko paljon. Jos sama ohje
3kirjoitettaisiin ihmiselle, joka ei eläessään ole leiponut mitään, ei
4edellä esitetty ohje olisi alkuunkaan riittävä, vaan siinä täytyisi
5huomioida useita leipomiseen liittyviä niksejä: uunin ennakkoon
6lämmittäminen, vaahdon vatkauksen salat, yms.
timApp/static/data/ohjelmointi1/block_00017
(10 / 0)
  
1Koneelle kirjoitettavat ohjeet poikkeavat merkittävästi ihmisille
2kirjoitetuista ohjeista. Kone ei osaa automaattisesti kysyä neuvoa
3törmätessään uuteen ja ennalta arvaamattomaan tilanteeseen. Se toimii
4täsmälleen niiden ohjeiden mukaan, jotka sille on annettu, olivatpa ne
5vallitsevassa tilanteessa mielekkäitä tai eivät. Kone toistaa saamiaan
6toimintaohjeita uskollisesti sortumatta ihmisille tyypilliseen
7luovuuteen. Näin ollen tämän päivän ohjelmointikielillä koneelle
8tarkoitetut ohjeet on esitettävä hyvin tarkoin määritellyssä muodossa ja
9niissä on pyrittävä ottamaan huomioon kaikki mahdollisesti esille
10tulevat tilanteet. [MÄN]
timApp/static/data/ohjelmointi1/block_00018
(2 / 0)
  
12. Ensimmäinen C\#-ohjelma
2==========================
timApp/static/data/ohjelmointi1/block_00019
(2 / 0)
  
12.1 Ohjelman kirjoittaminen
2---------------------------
timApp/static/data/ohjelmointi1/block_00020
(10 / 0)
  
1C\#-ohjelmia (lausutaan *c sharp*) voi kirjoittaa millä tahansa
2tekstieditorilla. Tekstieditoreja on kymmeniä, ellei satoja, joten yhden
3nimeäminen on vaikeaa. Osa on kuitenkin suunniteltu varta vasten
4ohjelmointia ajatellen. Tällaiset tekstieditorit osaavat muotoilla
5ohjelmoijan kirjoittamaa lähdekoodia (tai lyhyesti koodia)
6automaattisesti siten, että lukeminen on helpompaa ja siten ymmärtäminen
7ja muokkaaminen nopeampaa. Ohjelmoijien suosimia ovat mm. *Vim,* *Emacs,
8ConTEXT* *ja* *NotePad++*, mutta monet muutkin ovat varmasti hyviä.
9Monisteen alun esimerkkien kirjoittamiseen soveltuu hyvin mikä tahansa
10tekstieditori.
timApp/static/data/ohjelmointi1/block_00021
(2 / 0)
  
1*Koodi, lähdekoodi =* Ohjelmoijan tuottama tiedosto, josta varsinainen
2ohjelma muutetaan tietokoneen ymmärtämäksi konekieleksi.
timApp/static/data/ohjelmointi1/block_00022
(8 / 0)
  
1Kirjoitetaan tekstieditorilla alla olevan mukainen C\#-ohjelma ja
2tallennetaan se vaikka nimellä HelloWorld.cs. Tiedoston tarkenteeksi
3(eli niin sanottu tiedostopääte) on sovittu juuri tuo .cs, mikä tulee
4käytetyn ohjelmointikielen nimestä, joten tälläkin kurssilla käytämme
5sitä. Kannattaa olla tarkkana tiedostoa tallennettaessa, sillä jotkut
6tekstieditorit yrittävät oletuksena tallentaa kaikki tiedostot
7tarkenteella .txt ja tällöin tiedoston nimi voi helposti tulla muotoon
8HelloWorld.cs.txt.
timApp/static/data/ohjelmointi1/block_00023
(9 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2public class HelloWorld
3{
4 public static void Main()
5 {
6 System.Console.WriteLine("Hello World!");
7 }
8}
9```
timApp/static/data/ohjelmointi1/block_00024
(1 / 0)
  
1Tämän ohjelman pitäisi tulostaa näytölle teksti
timApp/static/data/ohjelmointi1/block_00025
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2Hello World!
3```
timApp/static/data/ohjelmointi1/block_00026
(2 / 0)
  
1Voidaksemme kokeilla ohjelmaa käytännössä, täytyy se ensiksi kääntää
2tietokoneen ymmärtämään muotoon.
timApp/static/data/ohjelmointi1/block_00027
(2 / 0)
  
1*Kääntäminen =* Kirjoitetun lähdekoodin muuntamista suoritettavaksi
2ohjelmaksi.
timApp/static/data/ohjelmointi1/block_00028
(2 / 0)
  
1Esimerkkejä muilla ohjelmointikielillä kirjoitetusta HelloWorld
2-ohjelmasta löydät vaikkapa:
timApp/static/data/ohjelmointi1/block_00029
(1 / 0)
  
1<http://www2.latech.edu/~acm/HelloWorld.html>.
timApp/static/data/ohjelmointi1/block_00030
(2 / 0)
  
12.2 Ohjelman kääntäminen ja ajaminen
2------------------------------------
timApp/static/data/ohjelmointi1/block_00031
(9 / 0)
  
1Jotta ohjelman kääntäminen ja suorittaminen onnistuu, täytyy koneelle
2olla asennettuna joku C\#-sovelluskehitin. Mikäli käytät Windowsia, niin
3aluksi riittää hyvin Microsoft .NET SDK (Software Development Kit, suom.
4kehitystyökalut). Muiden käyttöjärjestelmien tapauksessa
5sovelluskehittimeksi käy esimerkiksi *Novell Mono*. Hyvin monet tämän
6kurssin harjoituksista on tehtävissä Mono-sovelluskehittimellä, mutta
7tämän monisteen ohjeet ja esimerkit tullaan käsittelemään
8Windows-ympäristössä. Edelleen, Jypeli-kirjaston käyttäminen on
9mahdollista vain Windows-ympäristössä.
timApp/static/data/ohjelmointi1/block_00032
(6 / 0)
  
1Lisätietoa .NET-kehitystyökaluista ja asentamisesta löytyy kurssin
2kotisivuilta:
3<https://trac.cc.jyu.fi/projects/ohj1/wiki/dotnet-tyokalut>. Kun
4sovelluskehitin on asennettu, käynnistetään komentorivi (Command Prompt,
5lyhyemmin cmd) ja siirrytään siihen hakemistoon, johon HelloWorld.cs
6tiedosto on tallennettu. Ohjelma käännetään nyt komennolla:
timApp/static/data/ohjelmointi1/block_00033
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2csc HelloWorld.cs
3```
timApp/static/data/ohjelmointi1/block_00034
(4 / 0)
  
1Komento ”csc” tulee sanoista *C Sharp Compiler* (compiler = kääntäjä).
2Kääntämisen jälkeen hakemistoon ilmestyy HelloWorld.exe-niminen
3tiedosto, joka voidaan ajaa kuten minkä tahansa ohjelman syöttämällä
4ohjelman nimi:
timApp/static/data/ohjelmointi1/block_00035
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2HelloWorld
3```
timApp/static/data/ohjelmointi1/block_00036
(2 / 0)
  
1Ohjelman tulisi nyt tulostaa näyttöön teksti Hello World!, kuten alla
2olevassa kuvassa.
timApp/static/data/ohjelmointi1/block_00037
(3 / 0)
  
1![\
2 Kuva 1: Ohjelman kääntäminen ja ajaminen Windowsin
3komentorivillä.](../src/luentomonistecsUusin_htm_m16b63f32.png)
timApp/static/data/ohjelmointi1/block_00038
(3 / 0)
  
1\
2 Huomaa, että käännettäessä kirjoitetaan koko tiedoston nimi
3.cs-tarkentimen kanssa.
timApp/static/data/ohjelmointi1/block_00039
(1 / 0)
  
1Jos saat virheilmoituksen
timApp/static/data/ohjelmointi1/block_00040
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2'csc' is not recognized as an internal or external command, operable program or batch file.
3```
timApp/static/data/ohjelmointi1/block_00041
(2 / 0)
  
1niin kääntäjäohjelmaa csc.exe ei silloin löydy niin sanotusta
2*hakupolusta*. Ohjelman lisääminen hakupolkuun onnistuu komennolla:
timApp/static/data/ohjelmointi1/block_00042
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2set PATH=%WINDIR%\Microsoft.NET\Framework\v4.0.30319;%path%
3```
timApp/static/data/ohjelmointi1/block_00043
(3 / 0)
  
1Jotta kääntäjää ei tarvitsisi joka kerta lisätä hakupolkuun, voi sen
2lisätä siihen pysyvästi. Esimerkiksi Windows 7:ssä tämä tapahtuu
3seuraavasti.
timApp/static/data/ohjelmointi1/block_00044
(5 / 0)
  
1Klikkaa Oma tietokone -kuvaketta hiiren oikealla painikkeella ja valitse
2**Ominaisuudet** (Properties). Valitse sitten vasemmalta Advanced system
3settings ja Advanced-välilehdeltä Environment variables. Ylemmästä
4laatikosta valitse muuttuja PATH ja paina **Muokkaa**. Siirry rivin
5Variable value loppuun, kirjoita puolipiste (;) ja heti perään polku
timApp/static/data/ohjelmointi1/block_00045
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2%WINDIR%\Microsoft.NET\Framework\v4.0.30319
3```
timApp/static/data/ohjelmointi1/block_00046
(2 / 0)
  
1XP:ssä vastaavasti Oma tietokone → Ominaisuudet → Lisäasetukset →
2Ympäristömuuttujat.
timApp/static/data/ohjelmointi1/block_00047
(2 / 0)
  
12.3 Ohjelman rakenne
2--------------------
timApp/static/data/ohjelmointi1/block_00048
(3 / 0)
  
1Ensimmäinen kirjoittamamme ohjelma HelloWorld.cs on oikeastaan
2yksinkertaisin mahdollinen C\#-ohjelma. Alla yksinkertaisimman ohjelman
3kaksi ensimmäistä riviä.
timApp/static/data/ohjelmointi1/block_00049
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2public class HelloWorld
3{
4```
timApp/static/data/ohjelmointi1/block_00050
(9 / 0)
  
1Ensimmäisellä rivillä määritellään *luokka* (class) jonka nimi on
2HelloWorld. Tässä vaiheessa riittää ajatella luokkaa ”kotina”
3*aliohjelmille*. Aliohjelmista puhutaan lisää hieman myöhemmin.
4Toisaalta luokkaa voidaan verrata ”piparkakkumuottiin”-se on
5rakennusohje olioiden (eli ”piparkakkujen”) luomista varten. Ohjelman
6ajamisen aikana olioita syntyy luokkaan kirjoitetun koodin avulla.
7Olioita voidaan myös tuhota. Yhdellä luokalla voidaan siis tehdä monta
8samanlaista oliota, aivan kuten yhdellä piparkakkumuotilla voidaan tehdä
9monta samanlaista (samannäköistä) piparia.
timApp/static/data/ohjelmointi1/block_00051
(7 / 0)
  
1Jokaisessa C\#-ohjelmassa on vähintään yksi luokka, mutta luokkia voi
2olla enemmänkin. Luokan, jonka sisään ohjelma kirjoitetaan, on hyvä olla
3samanniminen kuin tiedoston nimi. Jos tiedoston nimi on HelloWorld.cs,
4on suositeltavaa, että luokan nimi on myös HelloWorld, kuten meidän
5esimerkissämme. Tässä vaiheessa ei kuitenkaan vielä kannata liikaa
6vaivata päätänsä sillä, mikä luokka oikeastaan on, se selviää tarkemmin
7myöhemmin.
timApp/static/data/ohjelmointi1/block_00052
(2 / 0)
  
1Huomaa! C\#:ssa *ei* samasteta isoja ja pieniä kirjaimia. Ole siis
2tarkkana kirjoittaessasi luokkien nimiä.
timApp/static/data/ohjelmointi1/block_00053
(2 / 0)
  
1Huomaa! Vahva suositus (ja tämän kurssin tapa) on, että luokka alkaa
2isolla alkukirjaimella, ja ettei skandeja käytetä luokan nimessä.
timApp/static/data/ohjelmointi1/block_00054
(6 / 0)
  
1Luokan edessä oleva public-sana on eräs *saantimääre* (eng. *access
2modifier*). Saantimääreen avulla luokka voidaan asettaa rajoituksetta
3tai osittain muiden (luokkien) saataville, tai piilottaa kokonaan. Sana
4public tarkoittaa, että luokka on muiden luokkien näkökulmasta
5*julkinen*, kuten luokat useimmiten ovat. Muita saantimääreitä ovat
6protected, internal ja private.
timApp/static/data/ohjelmointi1/block_00055
(6 / 0)
  
1Määreen voi myös jättää kirjoittamatta luokan eteen, jolloin luokan
2määreeksi tulee automaattisesti internal. Puhumme aliohjelmista
3myöhemmin, mutta mainittakoon, että vastaavasti, jos aliohjelmasta
4jättää määreen kirjoittamatta, tulee siitä private. Tällä kurssilla
5kuitenkin harjoitellaan kirjoittamaan julkisia luokkia (ja aliohjelmia),
6jolloin public-sana kirjoitetaan aina luokan ja aliohjelman eteen.
timApp/static/data/ohjelmointi1/block_00056
(9 / 0)
  
1Toisella rivillä on oikealle auki oleva *aaltosulku*. Useissa
2ohjelmointikielissä yhteen liittyvät asiat ryhmitellään tai kootaan
3aaltosulkeiden sisälle. Oikealle auki olevaa aaltosulkua sanotaan
4aloittavaksi aaltosuluksi ja tässä tapauksessa se kertoo kääntäjälle,
5että tästä alkaa HelloWorld-luokkaan liittyvät asiat. Jokaista
6aloittavaa aaltosulkua kohti täytyy olla vasemmalle auki oleva lopettava
7aaltosulku. HelloWorld-luokan lopettava aaltosulku on rivillä viisi,
8joka on samalla ohjelman viimeinen rivi. Aaltosulkeiden rajoittamaa
9aluetta kutsutaan *lohkoksi* (block).
timApp/static/data/ohjelmointi1/block_00057
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2public static void Main()
3{
4```
timApp/static/data/ohjelmointi1/block_00058
(7 / 0)
  
1Rivillä kolme määritellään (tai oikeammin *esitellään*) uusi aliohjelma
2nimeltä Main. Nimensä ansiosta se on tämän luokan pääohjelma. Sanat
3static ja void kuuluvat aina Main-aliohjelman esittelyyn. Paneudumme
4niihin tarkemmin hieman myöhemmin, mutta sanottakoon tässä kohtaa, että
5static tarkoittaa, että aliohjelma on *luokkakohtainen* (vastakohtana
6*oliokohtainen*, jolloin static-sanaa ei kirjoiteta). Vastaavasti void
7merkitsee, ettei aliohjelma palauta mitään tietoa.
timApp/static/data/ohjelmointi1/block_00059
(4 / 0)
  
1Samoin kuin luokan, niin myös pääohjelman sisältö kirjoitetaan
2aaltosulkeiden sisään. C\#:ssa ohjelmoijan kirjoittaman koodin
3suorittaminen alkaa aina käynnistettävän luokan pääohjelmasta. Toki
4sisäisesti ehtii tapahtua paljon asioita jo ennen tätä.
timApp/static/data/ohjelmointi1/block_00060
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2System.Console.WriteLine("Hello World!");
3```
timApp/static/data/ohjelmointi1/block_00061
(4 / 0)
  
1Rivillä neljä tulostetaan näytölle Hello World!. C\#:ssa tämä tapahtuu
2pyytämällä .NET-ympäristön mukana tulevan luokkakirjaston
3System-luokkakirjaston Console-luokkaa tulostamaan
4WriteLine()-*metodilla* (method).
timApp/static/data/ohjelmointi1/block_00062
(5 / 0)
  
1Huomaa! Viitattaessa aliohjelmiin on kirjallisuudessa usein tapana
2kirjoittaa aliohjelman nimen perään sulut. Kirjoitustyyli korostaa, että
3kyseessä on aliohjelma, mutta asiayhteydestä riippuen sulut voi myös
4jättää kirjoittamatta. Tässä monisteessa käytetään pääsääntöisesti
5jälkimmäistä tapaa, tilanteesta riippuen.
timApp/static/data/ohjelmointi1/block_00063
(11 / 0)
  
1Kirjastoista, olioista ja metodeista puhutaan lisää kohdassa 4.1 ja
2luvussa 8. Tulostettava merkkijono kirjoitetaan sulkeiden sisälle
3lainausmerkkeihin (Shift + 2). Tämä rivi on myös tämän ohjelman ainoa
4*lause* (statement). Lauseiden voidaan ajatella olevan yksittäisiä
5toimenpiteitä, joista ohjelma koostuu. Jokainen lause päättyy C\#:ssa
6puolipisteeseen. Koska lauseen loppuminen ilmoitetaan puolipisteellä, ei
7C\#:n syntaksissa (syntax) ”tyhjillä merkeillä” (white space), kuten
8rivinvaihdoilla ja välilyönneillä ole merkitystä ohjelman toiminnan
9kannalta. Ohjelmakoodin luettavuuden kannalta niillä on kuitenkin suuri
10merkitys. Huomaa, että puolipisteen unohtaminen on yksi yleisimmistä
11ohjelmointivirheistä ja tarkemmin sanottuna *syntaksivirheistä.*
timApp/static/data/ohjelmointi1/block_00064
(2 / 0)
  
1*Syntaksi* = Tietyn ohjelmointikielen (esimerkiksi C\#:n)
2kielioppisäännöstö.
timApp/static/data/ohjelmointi1/block_00065
(1 / 0)
  
1### 2.3.1 Virhetyypit
timApp/static/data/ohjelmointi1/block_00066
(2 / 0)
  
1Ohjelmointivirheet voidaan jakaa karkeasti *syntaksivirheisiin* ja
2*loogisiin virheisiin*.
timApp/static/data/ohjelmointi1/block_00067
(4 / 0)
  
1Syntaksivirhe estää ohjelman kääntymisen vaikka merkitys eli
2*semantiikka* olisikin oikein. Siksi ne huomataankin aina viimeistään
3ohjelmaa käännettäessä. Syntaksivirhe voi olla esimerkiksi joku
4kirjoitusvirhe tai puolipisteen unohtaminen lauseen lopusta.
timApp/static/data/ohjelmointi1/block_00068
(6 / 0)
  
1Loogisissa virheissä semantiikka, eli merkitys, on väärin. Ne on
2vaikeampi huomata, sillä ohjelma kääntyy semanttisista virheistä
3huolimatta. Ohjelma voi jopa näyttää toimivan täysin oikein. Jos
4looginen virhe ei löydy *testauksessakaan* (testing), voivat seuraukset
5ohjelmistosta riippuen olla tuhoisia. Tässä yksi tunnettu esimerkki
6loogisesta virheestä:
timApp/static/data/ohjelmointi1/block_00069
(1 / 0)
  
1<http://money.cnn.com/magazines/fortune/fortune_archive/2000/02/07/272831/index.htm>.
timApp/static/data/ohjelmointi1/block_00070
(1 / 0)
  
1### 2.3.2 Kääntäjän virheilmoitusten tulkinta
timApp/static/data/ohjelmointi1/block_00071
(1 / 0)
  
1Alla on esimerkki syntaksivirheestä HelloWorld-ohjelmassa.
timApp/static/data/ohjelmointi1/block_00072
(9 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2public class HelloWorld
3{
4 public static void Main()
5 {
6 System.Console.Writeline("Hello World!");
7 }
8}
9```
timApp/static/data/ohjelmointi1/block_00073
(2 / 0)
  
1Ohjelmassa on pieni kirjoitusvirhe, joka on (ilman apuvälineitä) melko
2hankala huomata. Tutkitaan csc-kääntäjän antamaa virheilmoitusta.
timApp/static/data/ohjelmointi1/block_00074
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2HelloWorld.cs(5,17): error CS0117: 'System.Console' does not contain a
3 definition for 'Writeline'
4```
timApp/static/data/ohjelmointi1/block_00075
(4 / 0)
  
1Kääntäjä kertoo, että tiedostossa HelloWorld.cs rivillä 5 ja sarakkeessa
217 on seuraava virhe: System.Console-luokka ei tunne Writeline-komentoa.
3Tämä onkin aivan totta, sillä WriteLine kirjoitetaan isolla L:llä.
4Korjattuamme tuon ohjelma toimii jälleen.
timApp/static/data/ohjelmointi1/block_00076
(3 / 0)
  
1Valitettavasti virheilmoituksen sisältö ei aina kuvaa ongelmaa kovinkaan
2hyvin. Alla olevassa esimerkissä on erehdytty laittamaan puolipisteen
3väärään paikkaan.
timApp/static/data/ohjelmointi1/block_00077
(9 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2public class HelloWorld
3{
4 public static void Main();
5 {
6 System.Console.Writeline("Hello World!");
7 }
8}
9```
timApp/static/data/ohjelmointi1/block_00078
(1 / 0)
  
1Virheilmoitus, tai oikeastaan virheilmoitukset, näyttävät seuraavalta.
timApp/static/data/ohjelmointi1/block_00079
(8 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2HelloWorld.cs(4,3): error CS1519: Invalid token '{' in class, struct, or
3 interface member declaration
4HelloWorld.cs(5,26): error CS1519: Invalid token '(' in class, struct, or
5 interface member declaration
6HelloWorld.cs(7,1): error CS1022: Type or namespace definition, or end-of-file
7 expected
8```
timApp/static/data/ohjelmointi1/block_00080
(4 / 0)
  
1Ensimmäinen virheilmoitus osoittaa riville 4, vaikka todellisuudessa
2ongelma on rivillä 3. Toisin sanoen, näistä virheilmoituksista ei ole
3meille tässä tilanteessa lainkaan apua, päinvastoin, ne kehottavat
4tekemään jotain, mitä emme halua.
timApp/static/data/ohjelmointi1/block_00081
(1 / 0)
  
1### 2.3.3 Tyhjät merkit (White spaces)
timApp/static/data/ohjelmointi1/block_00082
(3 / 0)
  
1Esimerkkinämme ollut HelloWorld-ohjelma voitaisiin, ilman että sen
2toiminta muuttuisi, vaihtoehtoisesti kirjoittaa myös seuraavassa
3muodossa.
timApp/static/data/ohjelmointi1/block_00083
(13 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2public class HelloWorld
3 {
4
5
6 public static void Main()
7 {
8System.Console.WriteLine("Hello World!");
9 }
10
11
12}
13```
timApp/static/data/ohjelmointi1/block_00084
(3 / 0)
  
1\
2\
3 Edelleen, koodi voitaisiin kirjoittaa myös seuraavasti.
timApp/static/data/ohjelmointi1/block_00085
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2public class HelloWorld { public static void Main() {
3 System.Console.WriteLine("Hello World!"); } }
4```
timApp/static/data/ohjelmointi1/block_00086
(9 / 0)
  
1Vaikka molemmat yllä olevista esimerkeistä ovat syntaksiltaan oikein,
2eli ne noudattavat C\#:n kielioppisääntöjä, on niiden luettavuus
3huomattavasti heikompi kuin alkuperäisen ohjelmamme. C\#:ssa on
4yhteisesti sovittuja koodauskäytänteet (code conventions), jotka
5määrittelevät, miten ohjelmakoodia tulisi kirjoittaa. Kun kaikki
6kirjoittavat samalla tavalla, on muiden koodin lukeminen helpompaa.
7Tämän monisteen esimerkit on pyritty kirjoittamaan näiden käytänteiden
8mukaisesti. Linkkejä koodauskäytänteisiin löytyy kurssin wiki-sivulta
9osoitteesta
timApp/static/data/ohjelmointi1/block_00087
(1 / 0)
  
1<https://trac.cc.jyu.fi/projects/ohj1/wiki/CsKoodausKaytanteet>[.](https://trac.cc.jyu.fi/projects/ohj1/wiki/CsKoodausKaytanteet)
timApp/static/data/ohjelmointi1/block_00088
(2 / 0)
  
1Merkkijonoja käsiteltäessä välilyönneillä, tabulaattoreilla ja
2rivinvaihdoilla on kuitenkin merkitystä. Vertaa alla olevia tulostuksia.
timApp/static/data/ohjelmointi1/block_00089
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2System.Console.WriteLine("Hello World!");
3```
timApp/static/data/ohjelmointi1/block_00090
(2 / 0)
  
1Yllä oleva rivi tulostaa: Hello World!, kun taas alla oleva rivi
2tulostaa: H e l l o W o r l d !
timApp/static/data/ohjelmointi1/block_00091
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2System.Console.WriteLine("H e l l o W o r l d !");
3```
timApp/static/data/ohjelmointi1/block_00092
(2 / 0)
  
12.4 Kommentointi
2----------------
timApp/static/data/ohjelmointi1/block_00093
(2 / 0)
  
1> “Good programmers use their brains, but good guidelines save us having
2> to think out every case.” -Francis Glassborow
timApp/static/data/ohjelmointi1/block_00094
(6 / 0)
  
1Lähdekoodia on usein vaikea ymmärtää pelkkää ohjelmointikieltä
2lukemalla. Tämän takia koodin sekaan voi ja pitää lisätä selosteita eli
3*kommentteja*. Kommentit ovat sekä koodin kirjoittajaa itseään varten
4että tulevia ohjelman lukijoita ja ylläpitäjiä varten. Monet asiat
5voivat kirjoitettaessa tuntua ilmeisiltä, mutta jo viikon päästä saakin
6pähkäillä, että miksihän tuonkin tuohon kirjoitin.
timApp/static/data/ohjelmointi1/block_00095
(2 / 0)
  
1Kääntäjä jättää kommentit huomioimatta, joten ne eivät vaikuta ohjelman
2toimintaan. C\#:ssa on kolmenlaisia kommentteja.
timApp/static/data/ohjelmointi1/block_00096
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2// Yhden rivin kommentti
3```
timApp/static/data/ohjelmointi1/block_00097
(2 / 0)
  
1Yhden rivin kommentti alkaa kahdella vinoviivalla (//). Sen vaikutus
2kestää koko rivin loppuun.
timApp/static/data/ohjelmointi1/block_00098
(6 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2/* Tämä kommentti
3 on usean
4 rivin
5 pituinen */
6```
timApp/static/data/ohjelmointi1/block_00099
(3 / 0)
  
1Vinoviivalla ja asteriskilla alkava (/\*) kommentti kestää niin kauan
2kunnes vastaan tulee asteriski ja vinoviiva ( \*/). Huomaa, ettei
3asteriskin ja vinoviivan väliin tule välilyöntiä.
timApp/static/data/ohjelmointi1/block_00100
(1 / 0)
  
1### 2.4.1 Dokumentointi
timApp/static/data/ohjelmointi1/block_00101
(5 / 0)
  
1Kolmas kommenttityyppi on *dokumentaatiokommentti*.
2Dokumentaatiokommenteissa on tietty syntaksi, ja tätä noudattamalla
3voidaan dokumentaatiokommentit muuttaa sellaiseen muotoon, että
4kommentteihin perustuvaa yhteenvetoa on mahdollista tarkastella
5nettiselaimen avulla.
timApp/static/data/ohjelmointi1/block_00102
(5 / 0)
  
1Dokumentaatiokommentti olisi syytä kirjoittaa ennen jokaista luokkaa,
2pääohjelmaa, aliohjelmaa ja metodia (aliohjelmista ja metodeista
3puhutaan myöhemmin). Lisäksi jokainen C\#-tiedosto alkaa aina
4dokumentaatiokommentilla, josta selviää tiedoston tarkoitus, tekijä ja
5versio.
timApp/static/data/ohjelmointi1/block_00103
(4 / 0)
  
1Dokumentaatiokommentit kirjoitetaan siten, että rivin alussa on aina
2aina kolme vinoviivaa (Shift + 7). Jokainen seuraava
3dokumentaatiokommenttirivi aloitetaan siis myöskin kolmella
4vinoviivalla.
timApp/static/data/ohjelmointi1/block_00104
(5 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2/// Tämä
3/// on
4/// dokumentaatiokommentti
5```
timApp/static/data/ohjelmointi1/block_00105
(6 / 0)
  
1Dokumentoiminen tapahtuu *tagien* avulla. Jos olet joskus kirjoittanut
2HTML-sivuja, on merkintätapa sinulle tuttu. Dokumentaatiokommentit
3alkavat aloitustagilla, muotoa \<esimerkki\>, jonka perään tulee
4kommentin asiasisältö. Kommentti loppuu lopetustagiin, muotoa
5\</esimerkki\>, siis muuten sama kuin aloitustagi, mutta ensimmäisen
6kulmasulun jälkeen on yksi vinoviiva.
timApp/static/data/ohjelmointi1/block_00106
(3 / 0)
  
1C\#-tageja ovat esimerkiksi \<summary\>, jolla ilmoitetaan pieni
2yhteenveto kommenttia seuraavasta koodilohkosta (esimerkiksi pääohjelma
3tai metodi). Yhteenveto päättyy \</summary\> -lopetustagiin.
timApp/static/data/ohjelmointi1/block_00107
(5 / 0)
  
1Ohjelman kääntämisen yhteydessä dokumentaatiotagit voidaan kirjoittaa
2erilliseen *XML*-tiedostoon, josta ne voidaan edelleen muuntaa helposti
3selattaviksi HTML-sivuiksi. Tageja voi keksiä itsekin lisää, mutta tämän
4kurssin tarpeisiin riittää hyvin suositeltujen tagien luettelo. Tiedot
5suositelluista tageista löytyvät C\#:n dokumentaatiosta:
timApp/static/data/ohjelmointi1/block_00108
(1 / 0)
  
1<http://msdn.microsoft.com/en-us/library/5ast78ax.aspx>[.](http://msdn.microsoft.com/en-us/library/5ast78ax.aspx)
timApp/static/data/ohjelmointi1/block_00109
(2 / 0)
  
1Voisimme kirjoittaa nyt C\#-kommentit HelloWorld-ohjelman alkuun
2seuraavasti:
timApp/static/data/ohjelmointi1/block_00110
(20 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2/// @author Antti-Jussi Lakanen
3/// @version 28.8.2012
4///
5/// <summary>
6/// Esimerkkiohjelma, joka tulostaa tekstin "Hello World!"
7/// </summary>
8
9public class HelloWorld
10{
11 /// <summary>
12 /// Pääohjelma, joka hoitaa varsinaisen tulostamisen.
13 /// </summary>
14 /// <param name="args">Ei käytössä</param>
15 public static void Main(string[] args)
16 { // Suoritus alkaa siis tästä, ohjelman "entry point"
17 System.Console.WriteLine("Hello World!"); // Tämä lause tulostaa ruudulle
18 } // Ohjelman suoritus päättyy tähän
19}
20```
timApp/static/data/ohjelmointi1/block_00111
(5 / 0)
  
1Ohjelman alussa kerrotaan kohteen tekijän nimi. Tämän jälkeen tulee
2ensimmäinen dokumentaatiokommentti (huomaa kolme vinoviivaa), joka on
3lyhyt ja ytimekäs kuvaus tästä luokasta. Huomaa, että jossain
4dokumentaation tiivistelmissä näytetään vain tuo ensimmäinen virke.
5[DOC] [HYV]
timApp/static/data/ohjelmointi1/block_00112
(6 / 0)
  
1*Dokumentointi on erittäin keskeinen osa ohjelmistotyötä*. Luokkien ja
2koodirivien määrän kasvaessa dokumentointi helpottaa niin omaa
3työskentelyä kuin tulevien käyttäjien ja ylläpitäjien tehtävää.
4Dokumentoinnin tärkeys näkyy muun muassa siinä, että jopa 40-60%
5ylläpitäjien ajasta kuluu muokattavan ohjelman ymmärtämiseen.
6[KOSK][KOS]
timApp/static/data/ohjelmointi1/block_00113
(2 / 0)
  
13. Algoritmit
2=============
timApp/static/data/ohjelmointi1/block_00114
(1 / 0)
  
1> “First, solve the problem. Then, write the code.” - John Johnson
timApp/static/data/ohjelmointi1/block_00115
(2 / 0)
  
13.1 Mikä on algoritmi?
2----------------------
timApp/static/data/ohjelmointi1/block_00116
(6 / 0)
  
1Pyrittäessä kirjoittamaan koneelle kelpaavia ohjeita joudutaan
2suoritettavana oleva toimenpide kirjaamaan sarjana yksinkertaisia
3toimenpiteitä. Toimenpidesarjan tulee olla yksikäsitteinen, eli sen
4tulee joka tilanteessa tarjota yksi ja vain yksi tapa toimia, eikä siinä
5saa esiintyä ristiriitaisuuksia. Yksikäsitteistä kuvausta tehtävän
6ratkaisuun tarvittavista toimenpiteistä kutsutaan algoritmiksi.
timApp/static/data/ohjelmointi1/block_00117
(3 / 0)
  
1Ohjelman kirjoittaminen voidaan aloittaa hahmottelemalla tarvittavat
2algoritmit eli kirjaamalla lista niistä toimenpiteistä, joita tehtävän
3suoritukseen tarvitaan:
timApp/static/data/ohjelmointi1/block_00118
(9 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2Kahvin keittäminen:
3
41. Täytä pannu vedellä.
52. Keitä vesi.
63. Lisää kahvijauhot.
74. Anna tasaantua.
85. Tarjoile kahvi.
9```
timApp/static/data/ohjelmointi1/block_00119
(3 / 0)
  
1Algoritmi on yleisesti ottaen mahdollisimman pitkälle tarkennettu
2toimenpidesarja, jossa askel askeleelta esitetään yksikäsitteisessä
3muodossa ne toimenpiteet, joita asetetun ongelman ratkaisuun tarvitaan.
timApp/static/data/ohjelmointi1/block_00120
(2 / 0)
  
13.2 Tarkentaminen
2-----------------
timApp/static/data/ohjelmointi1/block_00121
(6 / 0)
  
1Kun tarkastellaan lähes mitä tahansa tehtävänantoa, huomataan, että
2tehtävän suoritus koostuu selkeästi toisistaan eroavista osatehtävistä.
3Se, miten yksittäinen osatehtävä ratkaistaan, ei vaikuta muiden
4osatehtävien suorittamiseen. Vain sillä, että kukin osasuoritus tehdään,
5on merkitystä. Esimerkiksi pannukahvinkeitossa jokainen osatehtävä
6voidaan jakaa edelleen osasiin:
timApp/static/data/ohjelmointi1/block_00122
(20 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2Kahvinkeitto:
3
41. Täytä pannu vedellä:
5 1.1. Pistä pannu hanan alle.
6 1.2. Avaa hana.
7 1.3. Anna veden valua, kunnes vettä on riittävästi.
82. Keitä vesi:
9 2.1. Aseta pannu hellalle.
10 2.2. Kytke virta keittolevyyn.
11 2.3. Anna lämmetä, kunnes vesi kiehuu.
123. Lisää kahvinporot:
13 3.1. Mittaa kahvinporot.
14 3.2. Sekoita kahvinporot kiehuvaan veteen.
154. Anna tasaantua:
16 4.1. Odota, kunnes suurin osa valmiista kahvista on vajonnut
17 pannun pohjalle.
185. Tarjoile kahvi:
19 5.1. Tämä sitten onkin jo oma tarinansa...
20```
timApp/static/data/ohjelmointi1/block_00123
(7 / 0)
  
1Edellä esitetyn kahvinkeitto-ongelman ratkaisu esitettiin jakamalla
2ratkaisu viiteen osavaiheeseen. Ratkaisun algoritmi sisältää viisi
3toteutettavaa lausetta. Kun näitä viittä lausetta tarkastellaan
4lähemmin, osoittautuu, että niistä kukin on edelleen jaettavissa
5osavaiheisiin, eli ratkaisun pääalgoritmi voidaan jakaa edelleen
6alialgoritmeiksi, joissa askel askeleelta esitetään, kuinka kukin
7osatehtävä ratkaistaan.
timApp/static/data/ohjelmointi1/block_00124
(4 / 0)
  
1Algoritmien kirjoittaminen osoittautuu hierarkkiseksi prosessiksi, jossa
2aluksi tehtävä jaetaan osatehtäviin, joita edelleen tarkennetaan, kunnes
3kukin osatehtävä on niin yksinkertainen, ettei sen suorittamisessa enää
4ole mitään moniselitteistä.
timApp/static/data/ohjelmointi1/block_00125
(2 / 0)
  
13.3 Yleistäminen
2----------------
timApp/static/data/ohjelmointi1/block_00126
(4 / 0)
  
1Eräs tärkeä algoritmien kirjoittamisen vaihe on yleistäminen. Tällöin
2valmiiksi tehdystä algoritmista pyritään paikantamaan kaikki alunperin
3annetusta tehtävästä riippuvat tekijät, ja pohditaan voitaisiinko ne
4kenties kokonaan poistaa tai korvata joillakin yleisemmillä tekijöillä.
timApp/static/data/ohjelmointi1/block_00127
(2 / 0)
  
13.4 Harjoitus
2-------------
timApp/static/data/ohjelmointi1/block_00128
(6 / 0)
  
1Tarkastele edellä esitettyä algoritmia kahvin keittämiseksi ja luo
2vastaava algoritmi teen keittämiseksi. Vertaile algoritmeja: mitä samaa
3ja mitä eroa niissä on? Onko mahdollista luoda algoritmi, joka
4yksiselitteisesti selviäisi sekä kahvin että teen keitosta? Onko
5mahdollista luoda algoritmi, joka saman tien selviytyisi maitokaakosta
6ja rommitotista?
timApp/static/data/ohjelmointi1/block_00129
(2 / 0)
  
13.5 Peräkkäisyys
2----------------
timApp/static/data/ohjelmointi1/block_00130
(4 / 0)
  
1Kuten luvussa 1 olevassa reseptissä ja muissakin ihmisille
2kirjoitetuissa ohjeissa, niin myös tietokoneelle esitetyt ohjeet luetaan
3ylhäältä alaspäin, ellei muuta ilmoiteta. Esimerkiksi ohjeen lumiukon
4piirtämisestä voisi esittää yksinkertaistettuna alla olevalla tavalla.
timApp/static/data/ohjelmointi1/block_00131
(5 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2Piirrä säteeltään 20cm kokoinen ympyrä koordinaatiston pisteeseen (20, 80)
3Piirrä säteeltään 15cm kokoinen ympyrä edellisen ympyrän päälle
4Piirrä säteeltään 10cm kokoinen ympyrä edellisen ympyrän päälle
5```
timApp/static/data/ohjelmointi1/block_00132
(3 / 0)
  
1Yllä oleva koodi ei ole vielä mitään ohjelmointikieltä, mutta se
2sisältää jo ajatuksen siitä kuinka lumiukko voitaisiin tietokoneella
3piirtää. Piirrämme lumiukon C\#-ohjelmointikielellä seuraavassa luvussa.
timApp/static/data/ohjelmointi1/block_00133
(2 / 0)
  
14. Yksinkertainen graafinen C\#-ohjelma
2=======================================
timApp/static/data/ohjelmointi1/block_00134
(3 / 0)
  
1Seuraavissa esimerkeissä käytetään Jyväskylän yliopistossa
2kehitettyä*Jypeli-ohjelmointikirjastoa.* Kirjaston voit ladata koneelle
3osoitteesta
timApp/static/data/ohjelmointi1/block_00135
(1 / 0)
  
1<https://trac.cc.jyu.fi/projects/npo/wiki/LataaJypeli>,
timApp/static/data/ohjelmointi1/block_00136
(4 / 0)
  
1josta löytyy myös ohjeet kirjaston asennukseen ja käyttöön. Huomaa, että
2tietokoneellasi tulee olla asennettuna .NET Framework 4 sekä XNA Game
3Studio 4, jotta graafinen ohjelma voidaan kääntää. .NET-frameworkin
4asennusohjeet löytyvät osoitteesta
timApp/static/data/ohjelmointi1/block_00137
(1 / 0)
  
1<https://trac.cc.jyu.fi/projects/ohj1/wiki/dotnet-tyokalut>.
timApp/static/data/ohjelmointi1/block_00138
(4 / 0)
  
1Vaikka tässä kohtaa emme vielä Visual Studio 2010 -kehitysympäristöä
2tarvitsekaan, on sen asentaminen tässä kohtaa myös viisasta, sillä
3Visual Studio tulisi olla asennettuna ennen XNA:n ja Jypelin
4asentamista.
timApp/static/data/ohjelmointi1/block_00139
(2 / 0)
  
14.1 Mikä on kirjasto?
2---------------------
timApp/static/data/ohjelmointi1/block_00140
(8 / 0)
  
1C\#-ohjelmat koostuvat luokista. Luokat taas sisältävät metodeja (ja
2aliohjelmia), jotka suorittavat tehtäviä ja mahdollisesti palauttavat
3arvoja suoritettuaan näitä tehtäviä. Metodi voisi esimerkiksi laskea
4kahden luvun summan ja palauttaa tuloksen tai piirtää ohjelmoijan
5haluaman kokoisen ympyrän. Samaan asiaan liittyviä metodeja kootaan
6luokkaan ja luokkia kootaan edelleen kirjastoiksi. Idea kirjastoissa on,
7ettei kannata tehdä uudelleen sitä minkä joku on jo tehnyt. Toisin
8sanoen, pyörää ei kannata keksiä uudelleen.
timApp/static/data/ohjelmointi1/block_00141
(4 / 0)
  
1C\#-ohjelmoijan kannalta oleellisin kirjasto on .NET Framework
2luokkakirjasto. Luokkakirjaston dokumentaatioon (documentation)
3kannattaa tutustua, sillä sieltä löytyy monia todella hyödyllisiä
4metodeja. Dokumentaatio löytyy Microsoftin sivuilta osoitteesta
timApp/static/data/ohjelmointi1/block_00142
(1 / 0)
  
1<http://msdn.microsoft.com/en-us/library/ms229335.aspx>.
timApp/static/data/ohjelmointi1/block_00143
(2 / 0)
  
1*Dokumentaatio =* Sisältää tiedot kaikista kirjaston luokista ja niiden
2metodeista (ja aliohjelmista). Löytyy useimmiten ainakin WWW-muodossa.
timApp/static/data/ohjelmointi1/block_00144
(2 / 0)
  
14.2 Jypeli-kirjasto
2-------------------
timApp/static/data/ohjelmointi1/block_00145
(5 / 0)
  
1Jypeli-kirjaston kehittäminen aloitettiin Jyväskylän yliopistossa
2keväällä 2009. Tämän monisteen esimerkeissä käytetään versiota 4.
3Jypeli-kirjastoon on kirjoitettu valmiita luokkia ja metodeja siten,
4että esimerkiksi fysiikan ja matematiikan ilmiöiden, sekä pelihahmojen
5ja liikkeiden ohjelmointi lopulliseen ohjelmaan on helpompaa.
timApp/static/data/ohjelmointi1/block_00146
(2 / 0)
  
14.3 Esimerkki: Lumiukko
2-----------------------
timApp/static/data/ohjelmointi1/block_00147
(3 / 0)
  
1Piirretään lumiukko käyttämällä Jypeli-kirjastoa. Mallikoodin vasemmassa
2reunassa juoksee myös rivinumerointi, joka ei kuulu koodiin, mutta
3helpottaa lukemista.
timApp/static/data/ohjelmointi1/block_00148
(47 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
201 // Otetaan käyttöön Jyväskylän yliopiston Jypeli-kirjasto
302 using Jypeli;
403
504 /// @author Vesa Lappalainen, Antti-Jussi Lakanen
605 /// @version 22.12.2011
706 ///
807 ///
908 /// <summary>
1009 /// Luokka, jossa harjoitellaan piirtämistä lisäämällä ympyröitä ruudulle
1110 /// </summary>
1211 public class Lumiukko : PhysicsGame
1312 {
1413 /// <summary>
1514 /// Pääohjelmassa laitetaan "peli" käyntiin Jypelille tyypilliseen tapaan
1615 /// </summary>
1716 /// <param name="args">Ei käytössä</param>
1817 public static void Main(string[] args)
1918 {
2019 using (Lumiukko peli = new Lumiukko())
2120 {
2221 peli.Run();
2322 }
2423 }
2524
2625 /// <summary>
2726 /// Piirretään oliot ja zoomataan kamera niin että kenttä näkyy kokonaan.
2827 /// </summary>
2928 public override void Begin()
3029 {
3130 Camera.ZoomToLevel();
3231 Level.Background.Color = Color.Black;
3332
3433 PhysicsObject p1 = new PhysicsObject(2*100.0, 2*100.0, Shape.Circle);
3534 p1.Y = Level.Bottom + 200.0;
3635 Add(p1);
3736
3837 PhysicsObject p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
3938 p2.Y = p1.Y + 100 + 50;
4039 Add(p2);
4140
4241 PhysicsObject p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
4342 p3.Y = p2.Y + 50 + 30;
4443 Add(p3);
4544 }
4645 }
47```
timApp/static/data/ohjelmointi1/block_00149
(2 / 0)
  
1Ajettaessa ohjelman tulisi piirtää yksinkertainen lumiukko keskelle
2ruutua, kuten alla olevassa kuvassa. 4.3.1 Ohjelman suoritus
timApp/static/data/ohjelmointi1/block_00150
(3 / 0)
  
1![\
2 Kuva 2: Lumiukko Jypeli-kirjaston avulla
3piirrettynä](../src/luentomonistecsUusin_htm_m793342fb.png)
timApp/static/data/ohjelmointi1/block_00151
(2 / 0)
  
1\
2 \#\#\# 4.3.1 Ohjelman suoritus
timApp/static/data/ohjelmointi1/block_00152
(7 / 0)
  
1Ohjelman suoritus aloitetaan aina pääohjelmasta ja sitten edetään rivi
2riviltä ylhäältä alaspäin ohjelman loppuun niin kauan kuin lauseita
3riittää. Ohjelmassa voi olla myös rakenteita, joissa toistetaan tiettyjä
4rivejä useampaan kertaan vain muuttamalla jotain arvoa tai arvoja.
5Pääohjelmassa voi olla myös aliohjelmakutsuja jolloin hypätään
6pääohjelmasta suorittamaan aliohjelmaa ja palataan sitten takaisin
7pääohjelman suoritukseen. Aliohjelmista puhutaan enemmän luvussa 6.
timApp/static/data/ohjelmointi1/block_00153
(1 / 0)
  
1### 4.3.2 Ohjelman oleellisemmat kohdat
timApp/static/data/ohjelmointi1/block_00154
(1 / 0)
  
1Tarkastellaan ohjelman oleellisempia kohtia.
timApp/static/data/ohjelmointi1/block_00155
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
202 using Jypeli;
3```
timApp/static/data/ohjelmointi1/block_00156
(3 / 0)
  
1Aluksi meidän täytyy kertoa kääntäjälle, että haluamme ottaa käyttöön
2koko Jypeli-kirjaston. Nyt Jypeli-kirjaston kaikki luokat (ja niiden
3metodit) ovat käytettävissämme.
timApp/static/data/ohjelmointi1/block_00157
(7 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
208 /// <summary>
309 /// Luokka, jossa harjoitellaan piirtämistä lisäämällä ympyröitä ruudulle
410 /// </summary>
511 public class Lumiukko : PhysicsGame
612 {
7```
timApp/static/data/ohjelmointi1/block_00158
(8 / 0)
  
1Rivit 8-10 ovat dokumentaatiokommentteja. Rivillä 11 luodaan
2Lumiukko-luokka, joka hieman poikkeaa HelloWorld-esimerkin tavasta luoda
3uusi luokka. Tässä kohtaa käytämme ensimmäisen kerran Jypeli-kirjastoa,
4ja koodissa kerrommekin, että Lumiukko-luokka, jota juuri olemme
5tekemässä, ”perustuu” Jypeli-kirjastossa olevaan PhysicsGame-luokkaan.
6Täsmällisemmin sanottuna Lumiukko-luokka peritään PhysicsGame-luokasta.
7Tuon PhysicsGame-luokan avulla objektien piirtäminen, myöhemmin
8liikuttelu ruudulla ja fysiikan lakien hyödyntäminen on vaivatonta.
timApp/static/data/ohjelmointi1/block_00159
(13 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
213 /// <summary>
314 /// Pääohjelmassa laitetaan "peli" käyntiin Jypelille tyypilliseen tapaan.
415 /// </summary>
516 /// <param name="args">Ei käytössä</param>
617 public static void Main(String[] args)
718 {
819 using (Lumiukko peli = new Lumiukko())
920 {
1021 peli.Run();
1122 }
1223 }
13```
timApp/static/data/ohjelmointi1/block_00160
(8 / 0)
  
1Myös Main-metodi, eli pääohjelma, on Jypeli-peleissä käytännössä aina
2tällainen vakiomuotoinen, joten jatkossa siihen ei tarvitse juurikaan
3koskea. Ohitamme tässä vaiheessa pääohjelman sisällön mainitsemalla
4vain, että pääohjelmassa Lumiukko-luokasta tehdään uusi olio (eli uusi
5”peli”), joka sitten laitetaan käyntiin peli.Run()-kohdassa.
6Jypeli-kirjaston rakenteesta johtuen kaikki varsinainen peliin liittyvä
7koodi kirjoitetaan omaan aliohjelmaansa, Begin-aliohjelmaan, jota
8käsittelemme seuraavaksi.
timApp/static/data/ohjelmointi1/block_00161
(2 / 0)
  
1Tarkasti ottaen Begin alkaa riviltä 29. Ensimmäinen lause on kirjoitettu
2riville 30.
timApp/static/data/ohjelmointi1/block_00162
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
230 Camera.ZoomToLevel();
331 Level.Background.Color = Color.Black;
4```
timApp/static/data/ohjelmointi1/block_00163
(5 / 0)
  
1Näistä kahdesta rivistä ensimmäisellä kutsutaan Camera-luokan
2ZoomToLevel-aliohjelmaa, joka pitää huolen siitä, että ”kamera” on
3kohdistettuna ja zoomattuna oikeaan kohtaan. Aliohjelma ei ota vastaan
4parametreja, joten sulkujen sisältö jää tyhjäksi. Toisella rivillä
5muutetaan taustan väri.
timApp/static/data/ohjelmointi1/block_00164
(5 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
233 PhysicsObject p1 = new PhysicsObject(2*100.0, 2*100.0, Shape.Circle);
334 p1.Y = Level.Bottom + 200.0;
435 Add(p1);
5```
timApp/static/data/ohjelmointi1/block_00165
(3 / 0)
  
1Näiden kolmen rivin aikana luomme uuden fysiikkaolio-ympyrän, annamme
2sille säteen, y-koordinaatin, sekä lisäämme sen ”pelikentälle”, eli
3näkyvälle alueelle valmiissa ohjelmassa.
timApp/static/data/ohjelmointi1/block_00166
(9 / 0)
  
1Tarkemmin sanottuna luomme uuden PhysicsObject-*olion* eli
2PhysicsObject-luokan *ilmentymän*, jonka nimeksi annamme p1.
3PhysicsObject-oliot ovat pelialueella liikkuvia olioita, jotka
4noudattavat fysiikan lakeja. Sulkujen sisään laitamme tiedon siitä,
5millaisen objektin haluamme luoda - tässä tapauksessa leveys ja korkeus
6(Jypeli-mitoissa, ei pikseleissä), sekä olion muoto. Teemme siis
7ympyrän, jonka säde on 100 (leveys 2 \* 100 ja korkeus 2 \* 100). Muita
8Shape-kokoelmasta löytyviä muotoja ovat muiden muassa kolmio, neliö,
9sydän jne. Olioista puhutaan lisää luvussa 8.
timApp/static/data/ohjelmointi1/block_00167
(1 / 0)
  
1Kokeile itse muuttaa olion muotoa!
timApp/static/data/ohjelmointi1/block_00168
(8 / 0)
  
1Seuraavalla rivillä asetetaan olion paikka Y-arvon avulla. Huomaa että Y
2kirjoitetaan isolla kirjaimella. Tämä on p1-olion ominaisuus,
3attribuutti. X-koordinaattia meidän ei tarvitse tässä erikseen asettaa,
4se on oletusarvoisesti 0 ja se kelpaa meille. Saadaksemme ympyrät
5piirrettyä oikeille paikoilleen, täytyy meidän laskea koordinaattien
6paikat. Oletuksena ikkunan keskipiste on koordinaatiston origo eli piste
7(0, 0). x-koordinaatin arvot kasvavat oikealle ja y:n arvot ylöspäin,
8samoin kuin ”normaalissa” koulusta tutussa koordinaatistossa.
timApp/static/data/ohjelmointi1/block_00169
(3 / 0)
  
1Peliolio täytyy aina lisätä kentälle, ennen kuin se saadaan näkyviin.
2Tämä tapahtuu Add-metodin avulla, joka ottaa parametrina kentälle
3lisättävän olion nimen (tässä p1).
timApp/static/data/ohjelmointi1/block_00170
(9 / 0)
  
1Metodeille annettavia tietoja sanotaan *parametreiksi* (parameter).
2ZoomToLevel-metodi ei ota vastaan yhtään parametria, mutta Add-metodi
3sen sijaan ottaa yhden parametrin: PhysicsObject-tyyppisen olion.
4Add-metodille voidaan antaa toinenkin parametri: *taso*, jolle olio
5lisätään. Tasojen avulla voidaan hallita, mitkä oliot lisätään
6päällimmäiseksi. Tasoparametri voidaan kuitenkin jättää antamatta,
7jolloin ohjelma itse päättää tasojen parhaan järjestyksen. Parametrit
8kirjoitetaan metodin nimen perään sulkeisiin ja ne erotetaan toisistaan
9pilkuilla.
timApp/static/data/ohjelmointi1/block_00171
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2MetodinNimi(parametri1, parametri2,..., parametriX);
3```
timApp/static/data/ohjelmointi1/block_00172
(2 / 0)
  
1Seuraavien rivien aikana luomme vielä kaksi ympyrää vastaavalla tavalla,
2mutta vaihtaen sädettä ja ympyrän koordinaatteja.
timApp/static/data/ohjelmointi1/block_00173
(6 / 0)
  
1Esimerkissä koordinaattien laskemiseen on käytetty C\#:n *aritmeettisia
2operaatioita*. Voisimme tietenkin laskea koordinaattien pisteet myös
3itse, mutta miksi tehdä niin jos tietokone voi laskea pisteet
4puolestamme? C\#:n aritmeettiset perusoperaatiot ovat summa (+),
5vähennys (-), kerto (\*), jako (/) ja jakojäännös (%). Aritmeettisista
6operaatioista puhutaan lisää muuttujien yhteydessä kohdassa 7.7.1.
timApp/static/data/ohjelmointi1/block_00174
(7 / 0)
  
1Keskimmäinen ympyrä tulee alimman ympyrän yläpuolelle niin, että ympyrät
2sivuavat toisiaan. Keskimmäisen ympyrän keskipiste sijoittuu siis siten,
3että sen x-koordinaatti on 0 ja y-koordinaatti on *alimman ympyrän
4paikka* +*alimman ympyrän säde + keskimmäisen ympyrän säde*. Kun
5haluamme, että keskimmäisen ympyrän säde on 50, niin silloin
6keskimmäisen ympyrän keskipiste tulee kohtaan (0, p1.Y + 100 + 50) ja se
7piirretään lauseella:
timApp/static/data/ohjelmointi1/block_00175
(5 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2PhysicsObject p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
3p2.Y = p1.Y + 100 + 50;
4Add(p2);
5```
timApp/static/data/ohjelmointi1/block_00176
(4 / 0)
  
1Huomaa, että fysiikkaolion Y-ominaisuuden asettamisen (*set*) lisäksi
2voimme myös lukea tai pyytää (*get*) kyseisen ominaisuuden arvon. Yllä
3teemme sen kirjoittamalla yksinkertaisesti sijoitusoperaattorin oikealle
4puolelle p1.Y.
timApp/static/data/ohjelmointi1/block_00177
(1 / 0)
  
1Seuraava kuva havainnollistaa ensimmäisen ja toisen pallon asettelua.
timApp/static/data/ohjelmointi1/block_00178
(3 / 0)
  
1![\
2 Kuva 3: Lumiukon kaksi ensimmäistä palloa asemoituina
3paikoilleen.](../src/luentomonistecsUusin_htm_m58b94a29.png)
timApp/static/data/ohjelmointi1/block_00179
(6 / 0)
  
1\
2\
3\
4 Ylin ympyrä sivuaa sitten taas keskimmäistä ympyrää.
5Harjoitustehtäväksi jätetään laskea ylimmän ympyrän koordinaatit, kun
6ympyrän säde on 30.
timApp/static/data/ohjelmointi1/block_00180
(4 / 0)
  
1Kaikki tiedot luokista, luokkien metodeista sekä siitä mitä parametreja
2metodeille tulee antaa löydät käyttämäsi kirjaston dokumentaatiosta.
3Jypelin luokkadokumentaatio löytyy osoitteesta:
4<http://kurssit.it.jyu.fi/npo/material/latest/documentation/html/>.
timApp/static/data/ohjelmointi1/block_00181
(2 / 0)
  
14.4 Harjoitus {#harjoitus-1}
2-------------
timApp/static/data/ohjelmointi1/block_00182
(3 / 0)
  
1Etsi Jypeli-kirjaston dokumentaatiosta RandomGen-luokka. Mitä tietoa
2löydät NextInt(int min, int max)-metodista? Mitä muita metodeja luokassa
3on?
timApp/static/data/ohjelmointi1/block_00183
(2 / 0)
  
14.5 Kääntäminen ja luokkakirjastoihin viittaaminen
2--------------------------------------------------
timApp/static/data/ohjelmointi1/block_00184
(5 / 0)
  
1Jotta Lumiukko-esimerkkiohjelma voitaisiin nyt kääntää C\#-kääntäjällä,
2tulee Jypeli-kirjasto olla tallennettuna tietokoneelle. Jypeli käyttää
3XNA-kirjaston lisäksi vapaan lähdekoodin fysiikka- ja
4matematiikkakirjastoja. Fysiikka- ja matematiikkakirjastot on
5sisäänrakennettuina Jypeli-kirjastoon.
timApp/static/data/ohjelmointi1/block_00185
(3 / 0)
  
1Ennen kääntämistä kopioi seuraavat tiedostot kurssin kotisivuilta
2(<https://trac.cc.jyu.fi/projects/ohj1/wiki/csharpCommandLine>) samaan
3kansioon Lumiukko.cs-tiedoston kanssa.
timApp/static/data/ohjelmointi1/block_00186
(1 / 0)
  
1- Jypeli.dll
timApp/static/data/ohjelmointi1/block_00187
(8 / 0)
  
1Meidän täytyy vielä välittää kääntäjälle tieto siitä, että
2Jypeli-kirjastoa tarvitaan Lumiukko-koodin kääntämiseen. Lisäksi
3annetaan kääntäjälle tieto siitä, että ohjelma tehdään *32-bittisille*
4järjestelmille (x86). Tämä tehdään csc-ohjelman
5`/reference`{.terminaali-western}-parametrin avulla. Lisäksi tarvitaan
6referenssi Jypelin käyttämään XNA-kirjastoon. Kirjoita nyt
7komentoriville(kaikki rivit samalle riville niin, että /-viivan edessä
8on yksi välilyönti)
timApp/static/data/ohjelmointi1/block_00188
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2csc Lumiukko.cs /reference:Jypeli.dll;"%XNAGSv4%\References\Windows\x86\Microsoft.Xna.Framework.Game.dll" /platform:x86
3```
timApp/static/data/ohjelmointi1/block_00189
(3 / 0)
  
1Jos käyttöjärjestelmäsi ei tunnista csc-komentoa, niin kertaa luvussa 2
2olevat ohjeet komennon asettamisesta
3`PATH`{.terminaali-western}-ympäristömuuttujan poluksi.
timApp/static/data/ohjelmointi1/block_00190
(11 / 0)
  
1Vinkki! Yllä esitelty kääntämiskomento on varsin pitkä. Asioiden
2helpottamiseksi voit kirjoittaa tiedoston csk.bat, joka sisältää
3seuraavan tekstin (komento on yksi pitkä rivi):\
4\
5@"%WINDIR%\\Microsoft.NET\\Framework\\v4.0.30319\\csc" %\*
6/reference:Jypeli.dll;"%XNAGSv4%References\\Windows\\x86\\Microsoft.Xna.Framework.Game.dll";"%XNAGSv4%References\\Windows\\x86\\Microsoft.Xna.Framework.dll"
7/platform:x86 /define:WINDOWS\
8\
9Tämä asettaa puolestasi reference ja platform -parametrit. Varmista,
10että tekemäsi csk.bat-tiedosto on ”polussa”. Tämän jälkeen kääntäminen
11onnistuu yksinkertaisemmin: csk OhjelmanNimi.cs
timApp/static/data/ohjelmointi1/block_00191
(2 / 0)
  
15. Lähdekoodista prosessorille
2==============================
timApp/static/data/ohjelmointi1/block_00192
(2 / 0)
  
15.1 Kääntäminen
2---------------
timApp/static/data/ohjelmointi1/block_00193
(12 / 0)
  
1Tarkastellaan nyt tarkemmin sitä kuinka C\#-lähdekoodi muuttuu lopulta
2prosessorin ymmärtämään muotoon. Kun ohjelmoija luo ohjelman
3lähdekoodin, joka käyttää *.NET Framework* -ympäristöä, tapahtuu
4kääntäminen sisäisesti kahdessa vaiheessa. Ohjelma käännetään ensin
5eräänlaiselle välikielelle, *MSIL*:lle (Microsoft Intermediate
6Language), joka ei ole vielä suoritettavissa millään
7käyttöjärjestelmällä. Tästä välivaiheen koodista käännetään ajon aikana
8valmis ohjelma halutulle käyttöjärjestelmälle, kuten Mac Os X:lle tai
9Linuxille, niin sanotulla *JIT-kääntäjällä* (Just-In-Time). JIT-kääntäjä
10muuntaa välivaiheen koodin juuri halutulle käyttöjärjestelmälle
11sopivaksi koodiksi nimenomaan ohjelmaa ajettaessa - tästä tulee nimi
12”just-in-time”.
timApp/static/data/ohjelmointi1/block_00194
(2 / 0)
  
1Ennen ensimmäistä kääntämistä kääntäjä tarkastaa, että koodi on
2syntaksiltaan oikein. [VES][KOS]
timApp/static/data/ohjelmointi1/block_00195
(2 / 0)
  
1Kääntäminen tehtiin Windowsissa komentorivillä (Command Prompt)
2käyttämällä komentoa
timApp/static/data/ohjelmointi1/block_00196
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2csc Tiedostonnimi.cs
3```
timApp/static/data/ohjelmointi1/block_00197
(1 / 0)
  
1tai hyödyntämällä edellisessä luvussa esiteltyä komentojonoa
timApp/static/data/ohjelmointi1/block_00198
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2csk Tiedostonnimi.cs
3```
timApp/static/data/ohjelmointi1/block_00199
(2 / 0)
  
15.2 Suorittaminen
2-----------------
timApp/static/data/ohjelmointi1/block_00200
(5 / 0)
  
1C\#:n tuottaa siis lähdekoodista suoritettavan (tai ”ajettavan”)
2tiedoston. Tämä tiedosto on käyttöjärjestelmäriippuvainen, ja
3suoritettavissa vain sillä alustalla, johon käännös on tehty. Toisin
4sanoen, Windows-ympäristössä käännetyt ohjelmat eivät ole ajettavissa OS
5X -käyttöjärjestelmässä, ja toisin päin.
timApp/static/data/ohjelmointi1/block_00201
(9 / 0)
  
1Toisin kuin C\#, eräät toiset ohjelmointikielet tuottavat
2käyttöjärjestelmäriippumatonta koodia. Esimerkiksi *Java*-kielessä
3kääntäjän tuottama tiedosto on niin sanottua *tavukoodia*, joka on
4käyttöjärjestelmäriippumatonta koodia. Tavukoodin suorittamiseen
5tarvitaan Java-virtuaalikone (Java Virtual Machine). Java-virtuaalikone
6on oikeaa tietokonetta matkiva ohjelma, joka tulkkaa tavukoodia ja
7suorittaa sitä sitten kohdekoneen prosessorilla. Tässä on merkittävä ero
8perinteisiin käännettäviin kieliin (esimerkiksi C ja C++), joissa
9käännös on tehtävä erikseen jokaiselle eri laitealustalle. [VES][KOS]
timApp/static/data/ohjelmointi1/block_00202
(3 / 0)
  
1\
2\
3 6. Aliohjelmat ==============
timApp/static/data/ohjelmointi1/block_00203
(1 / 0)
  
1> “Copy and paste is a design error.” - David Parnas
timApp/static/data/ohjelmointi1/block_00204
(5 / 0)
  
1Pääohjelman lisäksi ohjelma voi sisältää muitakin aliohjelmia.
2Aliohjelmaa *kutsutaan* pääohjelmasta, metodista tai toisesta
3aliohjelmasta suorittamaan tiettyä tehtävää. Aliohjelmat voivat saada
4parametreja ja palauttaa arvon, kuten metoditkin. Pohditaan seuraavaksi
5mihin aliohjelmia tarvitaan.
timApp/static/data/ohjelmointi1/block_00205
(3 / 0)
  
1Jos tehtävänämme olisi piirtää useampi lumiukko, niin tämänhetkisellä
2tietämyksellämme tekisimme todennäköisesti jonkin alla olevan kaltaisen
3ratkaisun.
timApp/static/data/ohjelmointi1/block_00206
(62 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
201 using Jypeli;
302
403 /// <summary>
504 /// Piirretään lumiukko.
605 /// </summary>
706 public class Lumiukko : PhysicsGame
807 {
908 /// <summary>
1009 /// Pääohjelmassa peli käyntiin.
1110 /// </summary>
1211 /// <param name="args">Ei käytössä.</param>
1312 public static void Main(String[] args)
1413 {
1514 using (Lumiukko game = new Lumiukko())
1615 {
1716 game.Run();
1817 }
1918 }
2019
2120 /// <summary>
2221 /// Aliohjelma, jossa
2322 /// piirretään ympyrät.
2423 /// </summary>
2524 public override void Begin()
2625 {
2726 Camera.ZoomToLevel();
2827 Level.Background.Color = Color.Black;
2928
3029 PhysicsObject p1, p2, p3;
3130
3231 // Eka ukko
3332 p1 = new PhysicsObject(2 * 100.0, 2 * 100.0, Shape.Circle);
3433 p1.Y = Level.Bottom + 200.0;
3534 Add(p1);
3635
3736 p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
3837 p2.Y = p1.Y + 100 + 50;
3938 Add(p2);
4039
4140 p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
4241 p3.Y = p2.Y + 50 + 30;
4342 Add(p3);
4443
4544 // Toinen ukko
4645 p1 = new PhysicsObject(2 * 100.0, 2 * 100.0, Shape.Circle);
4746 p1.X = 200;
4847 p1.Y = Level.Bottom + 300.0;
4948 Add(p1);
5049
5150 p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
5251 p2.X = 200;
5352 p2.Y = p1.Y + 100 + 50;
5453 Add(p2);
5554
5655 p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
5756 p3.X = 200;
5857 p3.Y = p2.Y + 50 + 30;
5958 Add(p3);
6059 }
6160 }
62```
timApp/static/data/ohjelmointi1/block_00207
(9 / 0)
  
1Huomataan, että ensimmäisen ja toisen lumiukon piirtäminen tapahtuu
2lähes samanlaisilla koodinpätkillä. Itse asiassa ainoa ero on, että
3jälkimmäisen lumiukon pallot saavat ensimmäisestä lumiukosta eroavat
4koordinaatit. Toisaalta voisimme kirjoittaa koodin myös niin, että
5lumiukon alimman pallon keskipiste tallennetaan *muuttujiin* x ja y.
6Näiden pisteiden avulla voimme sitten laskea muiden pallojen paikat.
7Määritellään heti alussa myös p1, p2 ja p3 PhysicsObject-olioiksi.
8Rivinumerointi on tässä jätetty pois selvyyden vuoksi. Luvun lopussa
9korjattu ohjelma esitellään kokonaisuudessaan rivinumeroinnin kanssa.
timApp/static/data/ohjelmointi1/block_00208
(21 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2double x, y;
3PhysicsObject p1, p2, p3;
4
5// Tehdään ensimmäinen lumiukko
6x = 0; y = Level.Bottom + 200.0;
7p1 = new PhysicsObject(2*100.0, 2*100.0, Shape.Circle);
8p1.X = x;
9p1.Y = y;
10Add(p1);
11
12p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
13p2.X = x;
14p2.Y = y + 100 + 50; // y + 1. pallon säde + 2. pallon säde
15Add(p2);
16
17p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
18p3.X = x;
19p3.Y = y + 100 + 2 * 50 + 30; // y + 1. pallon säde + 2. halk. + 3. säde
20Add(p3);
21```
timApp/static/data/ohjelmointi1/block_00209
(2 / 0)
  
1Vastaavasti toiselle lumiukolle: asetetaan vain x:n ja y:n arvot
2oikeiksi.
timApp/static/data/ohjelmointi1/block_00210
(18 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2// Tehdään toinen lumiukko
3x = 200; y = Level.Bottom + 300.0;
4p1 = new PhysicsObject(2 * 100.0, 2 * 100.0, Shape.Circle);
5p1.X = x;
6p1.Y = y;
7Add(p1);
8
9p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
10p2.X = x;
11p2.Y = y + 100 + 50;
12Add(p2);
13
14p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
15p3.X = x;
16p3.Y = y + 100 + 2*50 + 30;
17Add(p3);
18```
timApp/static/data/ohjelmointi1/block_00211
(1 / 0)
  
1Tarkastellaan nyt muutoksia hieman tarkemmin.
timApp/static/data/ohjelmointi1/block_00212
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2double x, y;
3```
timApp/static/data/ohjelmointi1/block_00213
(4 / 0)
  
1Yllä olevalla rivillä esitellään kaksi liukuluku*tyyppistä* *muuttujaa*.
2Liukuluku on eräs tapa esittää *reaalilukuja* tietokoneissa. C\#:ssa
3jokaisella muuttujalla on oltava tyyppi ja eräs liukulukutyyppi C\#:ssa
4on double. Muuttujista ja niiden tyypeistä puhutaan lisää luvussa 7.
timApp/static/data/ohjelmointi1/block_00214
(2 / 0)
  
1*Liukuluku* (floating point) = Tietokoneissa käytettävä esitysmuoto
2reaaliluvuille. Tarkempaa tietoa liukuluvuista löytyy luvusta 26.
timApp/static/data/ohjelmointi1/block_00215
(1 / 0)
  
1\
timApp/static/data/ohjelmointi1/block_00216
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2x = 0; y = Level.Bottom + 200.0;
3```
timApp/static/data/ohjelmointi1/block_00217
(4 / 0)
  
1Yllä olevalla rivillä on kaksi lausetta. Ensimmäisellä asetetaan
2muuttujaan x arvo 0 ja toisella muuttujaan y arvo 50 (jos Level.Bottom
3sattuu olemaan vaikka -150). Nyt voimme käyttää lumiukon pallojen
4laskentaan näitä muuttujia.
timApp/static/data/ohjelmointi1/block_00218
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2x = 300; y = Level.Bottom + 300.0;
3```
timApp/static/data/ohjelmointi1/block_00219
(4 / 0)
  
1Vastaavasti yllä olevalla rivillä asetetaan nyt muuttujiin uudet arvot,
2joita käytetään seuraavan lumiukon pallojen paikkojen laskemiseen.
3Huomaa, että y-koordinaatti saa negatiivisen arvon, jolloin lumiukon
4alimman pallon keskipiste painuu kuvaruudun keskitason alapuolelle.
timApp/static/data/ohjelmointi1/block_00220
(4 / 0)
  
1Nyt alimman pallon x-koordinaatiksi sijoitetaankin *muuttuja* x, ja
2vastaavasti y-koordinaatin arvoksi asetetaan *muuttuja* y, ja muiden
3pallojen sijainnit lasketaan ensimmäisen pallon koordinaattien
4perusteella.
timApp/static/data/ohjelmointi1/block_00221
(3 / 0)
  
1![\
2 Kuva 4: Kaksi
3lumiukkoa.](../src/luentomonistecsUusin_htm_m12339dd1.png)
timApp/static/data/ohjelmointi1/block_00222
(3 / 0)
  
1\
2 Näiden muutosten jälkeen molempien lumiukkojen varsinainen piirtäminen
3tapahtuu nyt **täysin samalla koodilla**.
timApp/static/data/ohjelmointi1/block_00223
(6 / 0)
  
1Uusien lumiukkojen piirtäminen olisi nyt jonkin verran helpompaa, sillä
2meidän ei tarvitse kuin ilmoittaa ennen piirtämistä uuden lumiukon
3paikka ja varsinaisen lumiukkojen piirtäminen onnistuisi kopioimilla ja
4liittämällä koodia (copy-paste). Kuitenkin, jos koodia kirjoittaessa
5joutuu tekemään suoraa kopiointia, pitäisi pysähtyä miettimään, että
6onko tässä mitään järkeä.
timApp/static/data/ohjelmointi1/block_00224
(7 / 0)
  
1Kahden lumiukon tapauksessa tämä vielä onnistuu ilman, että koodin määrä
2kasvaa kohtuuttomasti, mutta entä jos meidän pitäisi piirtää 10 tai 100
3lumiukkoa? Kuinka monta riviä ohjelmaan tulisi silloin? Kun lähes
4samanlainen koodinpätkä tulee useampaan kuin yhteen paikkaan, on
5useimmiten syytä muodostaa siitä oma *aliohjelma*. Koodin monistaminen
6moneen paikkaan lisäisi vain koodirivien määrää, tekisi ohjelman
7ymmärtämisestä vaikeampaa ja vaikeuttaisi testaamista.
timApp/static/data/ohjelmointi1/block_00225
(7 / 0)
  
1\
2\
3 Lisäksi jos monistetussa koodissa olisi vikaa, jouduttaisiin korjaukset
4tekemään myös useampaan paikkaan. Hyvän ohjelman yksi mitta (kriteeri)
5onkin, että jos jotain pitää muuttaa, niin kohdistuvatko muutokset
6kohdistuvat vain yhteen paikkaan (hyvä) vai joudutaanko muutoksia
7tekemään useaan paikkaan (huono).
timApp/static/data/ohjelmointi1/block_00226
(2 / 0)
  
16.1 Aliohjelman kutsuminen
2--------------------------
timApp/static/data/ohjelmointi1/block_00227
(4 / 0)
  
1Haluamme siis aliohjelman, joka piirtää meille lumiukon tiettyyn
2pisteeseen. Kuten metodeille, myös aliohjelmalle viedään parametrien
3avulla sen tarvitsemaa tietoa. Parametreina tulisi viedä vain
4minimaaliset tiedot, joilla aliohjelman tehtävä saadaan suoritettua.
timApp/static/data/ohjelmointi1/block_00228
(3 / 0)
  
1Sovitaan, että aliohjelmamme piirtää aina samankokoisen lumiukon
2haluamaamme pisteeseen. Mitkä ovat ne välttämättömät tiedot, jotka
3aliohjelma tarvitsee piirtääkseen lumiukon?
timApp/static/data/ohjelmointi1/block_00229
(5 / 0)
  
1Aliohjelma tarvitsee tiedon *mihin* pisteeseen lumiukko piirretään.
2Viedään siis parametrina lumiukon alimman pallon keskipiste. Muiden
3pallojen paikat voidaan laskea tämän pisteen avulla. Lisäksi tarvitaan
4yksi Game-tyyppinen parametri, jotta aliohjelmaamme voisi kutsua myös
5toisesta ohjelmasta. Nämä parametrit riittävät lumiukon piirtämiseen.
timApp/static/data/ohjelmointi1/block_00230
(6 / 0)
  
1Kun aliohjelmaa käytetään ohjelmassa, sanotaan, että aliohjelmaa
2*kutsutaan*. Kutsu tapahtuu kirjoittamalla aliohjelman nimi ja antamalla
3sille parametrit. Aliohjelmakutsun erottaa metodikutsusta vain se, että
4metodi liittyy aina tiettyyn olioon. Esimerkiksi pallo-olio p1
5voitaisiin poistaa pelikentällä kutsumalla metodia Destroy(), eli
6kirjoittaisimme:
timApp/static/data/ohjelmointi1/block_00231
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2p1.Destroy();
3```
timApp/static/data/ohjelmointi1/block_00232
(5 / 0)
  
1Toisin sanoen metodeja kutsuttaessa täytyy ensin kirjoittaa sen olion
2nimi, jonka metodia kutsutaan, ja sen jälkeen pisteellä erotettuna
3kirjoittaa haluttu metodin nimi. Sulkujen sisään tulee luonnollisesti
4tarvittavat parametrit. Yllä olevan esimerkin Destroy-metodi ei ota
5vastaan yhtään parametria.
timApp/static/data/ohjelmointi1/block_00233
(7 / 0)
  
1Päätetään, että aliohjelman nimi on PiirraLumiukko. Sovitaan myös, että
2aliohjelman ensimmäinen parametri on tämä peli, johon lumiukko ilmestyy
3(kirjoitetaan this). Toinen parametri on lumiukon alimman pallon
4keskipisteen x-koordinaatti ja kolmas parametri lumiukon alimman pallon
5keskipisteen y-koordinaatti. Tällöin kentälle voitaisiin piirtää
6lumiukko, jonka alimman pallon keskipiste on (0, Level.Bottom + 200.0),
7seuraavalla kutsulla:
timApp/static/data/ohjelmointi1/block_00234
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2PiirraLumiukko(this, 0, Level.Bottom + 200.0);
3```
timApp/static/data/ohjelmointi1/block_00235
(3 / 0)
  
1Kutsussa voisi myös ensiksi mainita sen luokan nimen mistä aliohjelma
2löytyy. Tällä kutsulla aliohjelmaa voisi kutsua myös muista luokista,
3koska määrittelimme Lumiukot-luokan julkiseksi (public).
timApp/static/data/ohjelmointi1/block_00236
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2Lumiukot.PiirraLumiukko(this, 0, Level.Bottom + 200.0);
3```
timApp/static/data/ohjelmointi1/block_00237
(6 / 0)
  
1Vaikka tämä muoto muistuttaa jo melko paljon metodin kutsua on ero
2kuitenkin selvä. Metodia kutsuttaessa toimenpide tehdään aina *tietylle
3oliolle*, kuten p1.Destroy() tuhoaa juuri sen pallon, johon p1-olio
4viittaa. Pallojahan voi tietenkin olla myös muita erinimisiä (kuten
5esimerkissämme onkin). Alla olevassa aliohjelmakutsussa kuitenkin
6käytetään vain luokasta Lumiukot löytyvää PiirraLumiukko-aliohjelmaa.
timApp/static/data/ohjelmointi1/block_00238
(2 / 0)
  
1Jos olisimme toteuttaneet jo varsinaisen aliohjelman, piirtäisi Begin
2meille nyt kaksi lumiukkoa.
timApp/static/data/ohjelmointi1/block_00239
(14 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2/// <summary>
3/// Kutsutaan PiirraLumiukko-aliohjelmaa
4/// sopivilla parametreilla.
5/// </summary>
6public override void Begin()
7{
8 Camera.ZoomToLevel();
9 Level.Background.Color = Color.Black;
10
11 PiirraLumiukko(this, 0, Level.Bottom + 200.0);
12 PiirraLumiukko(this, 200.0, Level.Bottom + 300.0);
13}
14```
timApp/static/data/ohjelmointi1/block_00240
(3 / 0)
  
1Koska PiirraLumiukko-aliohjelmaa ei luonnollisesti vielä ole olemassa,
2ei ohjelmamme vielä toimi. Seuraavaksi meidän täytyy toteuttaa itse
3aliohjelma, jotta kutsut alkavat toimimaan.
timApp/static/data/ohjelmointi1/block_00241
(4 / 0)
  
1Usein ohjelman toteutuksessa on viisasta edetä juuri tässä
2järjestyksessä: suunnitellaan aliohjelmakutsu ensiksi, kirjoitetaan
3kutsu sille kuuluvalle paikalle, ja vasta sitten toteutetaan varsinainen
4aliohjelman kirjoittaminen.
timApp/static/data/ohjelmointi1/block_00242
(2 / 0)
  
1Lisätietoja aliohjelmien kutsumisesta löydät kurssin wiki-sivulta:
2<https://trac.cc.jyu.fi/projects/ohj1/wiki/aliohjelmienKutsuminen>.
timApp/static/data/ohjelmointi1/block_00243
(2 / 0)
  
16.2 Aliohjelman kirjoittaminen
2------------------------------
timApp/static/data/ohjelmointi1/block_00244
(4 / 0)
  
1Ennen varsinaista aliohjelman toiminnallisuuden kirjoittamista täytyy
2aliohjelmalle tehdä määrittely (kutsutaan myös esittelyksi,
3declaration). Kirjoitetaan määrittely aliohjelmalle, jonka kutsun jo
4teimme edellisessä alaluvussa.
timApp/static/data/ohjelmointi1/block_00245
(2 / 0)
  
1Lisätään ohjelmaamme aliohjelman runko. Dokumentoidaan aliohjelma myös
2saman tien.
timApp/static/data/ohjelmointi1/block_00246
(25 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2/// <summary>
3/// Kutsutaan PiirraLumiukko-aliohjelmaa
4/// sopivilla parametreilla.
5/// </summary>
6public override void Begin()
7{
8 Camera.ZoomToLevel();
9 Level.Background.Color = Color.Black;
10
11 PiirraLumiukko(this, 0, Level.Bottom + 200.0);
12 PiirraLumiukko(this, 200.0, Level.Bottom + 300.0);
13}
14
15/// <summary>
16/// Aliohjelma piirtää lumiukon
17/// annettuun paikkaan.
18/// </summary>
19/// <param name="peli">Peli, johon lumiukko tehdään.</param>
20/// <param name="x">Lumiukon alimman pallon x-koordinaatti.</param>
21/// <param name="y">Lumiukon alimman pallon y-koordinaatti.</param>
22public static void PiirraLumiukko(Game peli, double x, double y)
23{
24}
25```
timApp/static/data/ohjelmointi1/block_00247
(2 / 0)
  
1Alla oleva kuva selvittää aliohjelmakutsun ja aliohjelman määrittelyn
2sekä vastinparametrien yhteyttä.
timApp/static/data/ohjelmointi1/block_00248
(3 / 0)
  
1![\
2 Kuva 5: Aliohjelmakutsu ja aliohjelman
3vastinparametrit.](../src/luentomonistecsUusin_htm_m48da2e91.png)
timApp/static/data/ohjelmointi1/block_00249
(2 / 0)
  
1\
2 Aliohjelman toteutuksen ensimmäistä riviä
timApp/static/data/ohjelmointi1/block_00250
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2public static void PiirraLumiukko(Game peli, double x, double y)
3```
timApp/static/data/ohjelmointi1/block_00251
(8 / 0)
  
1sanotaan aliohjelman *otsikoksi* (header) tai *esittelyriviksi*. Otsikon
2alussa määritellään aliohjelman *näkyvyys* julkiseksi (public). Kun
3näkyvyys on julkinen, niin aliohjelmaa voidaan kutsua eli käyttää myös
4muissa luokissa. Aliohjelma määritellään myös staattiseksi (static),
5sillä jos emme määrittelisi aliohjelmaa staattiseksi, olisi se
6oikeastaan metodi, eli olion toiminto (ks. luku 8.5). Statttinen
7aliohjelma pystyy tekemään kaikki toimensa parametreinä tuodun tiedon
8perusteella.
timApp/static/data/ohjelmointi1/block_00252
(6 / 0)
  
1Aliohjelmalle on annettu myös palautusarvoksi void, joka tarkoittaa
2sitä, että aliohjelma ei palauta mitään arvoa. Aliohjelma voisi
3nimittäin myös lopettaessaan palauttaa jonkun arvon, jota tarvitsisimme
4ohjelmassamme. Tällaisista aliohjelmista puhutaan luvussa 9.
5void-määrityksen jälkeen aliohjelmalle on annettu nimeksi
6PiirraLumiukko.
timApp/static/data/ohjelmointi1/block_00253
(2 / 0)
  
1Huomaa! C\#:ssa aliohjelmat kirjoitetaan tyypillisesti isolla
2alkukirjaimella.
timApp/static/data/ohjelmointi1/block_00254
(4 / 0)
  
1\
2 Huomaa! Aliohjelmien (ja metodien) nimien tulisi olla verbejä tai
3tekemistä ilmaisevia lauseita, esimerkiksi LuoPallo, Siirry,
4TormattiinEsteeseen.
timApp/static/data/ohjelmointi1/block_00255
(6 / 0)
  
1Aliohjelman nimen jälkeen ilmoitetaan sulkeiden sisässä aliohjelman
2parametrit. Jokaista parametria ennen on ilmoitettava myös parametrin
3*tietotyyppi*. Parametrinä annettiin lumiukon alimman pallon x- ja
4y-koordinaatit. Molempien tietotyyppi on double, joten myös
5vastinparametrien tyyppien tulee olla double. Annetaan myös nimet
6kuvaavasti x ja y.
timApp/static/data/ohjelmointi1/block_00256
(1 / 0)
  
1Tietotyypeistä voit lukea lisää kohdasta 7.2 ja luvusta 8.
timApp/static/data/ohjelmointi1/block_00257
(2 / 0)
  
1Huomaa! Aliohjelman parametrien nimien ei tarvitse olla samoja kuin
2kutsussa. Niiden nimet kannattaa kuitenkin olla mahdollisimman kuvaavia.
timApp/static/data/ohjelmointi1/block_00258
(5 / 0)
  
1\
2 Huomaa! Parametrien tyyppien ei tarvitse olla keskenään samoja, kunhan
3kukin parametri on yhteensopiva kutsussa olevan vastinparametrin kanssa.
4Esimerkkejä funktioista löydät kurssin wiki-sivulta:
5<https://trac.cc.jyu.fi/projects/ohj1/wiki/aliohjelmienKirjoittaminen>.
timApp/static/data/ohjelmointi1/block_00259
(6 / 0)
  
1\
2 Aliohjelmakutsulla ja aliohjelman määrittelyllä on siis hyvin vahva
3yhteys keskenään. Aliohjelmakutsussa annetut tiedot ”sijoitetaan”
4kullakin kutsukerralla aliohjelman määrittelyrivillä esitellyille
5vastinparametreille. Toisin sanoen, aliohjelmakutsun yhteydessä tapahtuu
6väljästi sanottuna seuraavaa.
timApp/static/data/ohjelmointi1/block_00260
(5 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2aliohjelman Game = this;
3aliohjelman x = 200.0;
4aliohjelman y = Level.Bottom + 300;
5```
timApp/static/data/ohjelmointi1/block_00261
(4 / 0)
  
1Voimme nyt kokeilla ajaa ohjelmaamme. Se toimii (lähtee käyntiin), mutta
2ei tietenkään vielä piirrä lumiukkoja, eikä pitäisikään, sillä luomamme
3aliohjelma on ”tyhjä”. Lisätään aaltosulkujen väliin varsinainen koodi,
4joka pallojen piirtämiseen tarvitaan.
timApp/static/data/ohjelmointi1/block_00262
(2 / 0)
  
1Pieni muutos aikaisempaan versioon kuitenkin tarvitaan. Rivit, joilla
2pallot lisätään kentälle, muutetaan muotoon
timApp/static/data/ohjelmointi1/block_00263
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2peli.Add(...);
3```
timApp/static/data/ohjelmointi1/block_00264
(1 / 0)
  
1missä pisteiden paikalle tulee pallo-olion muuttujan nimi.
timApp/static/data/ohjelmointi1/block_00265
(40 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2/// <summary>
3/// Kutsutaan PiirraLumiukko-aliohjelmaa
4/// sopivilla parametreilla.
5/// </summary>
6public override void Begin()
7{
8 Camera.ZoomToLevel();
9 Level.Background.Color = Color.Black;
10
11 PiirraLumiukko(this, 0, Level.Bottom + 200.0);
12 PiirraLumiukko(this, 200.0, Level.Bottom + 300.0);
13}
14
15/// <summary>
16/// Aliohjelma piirtää lumiukon
17/// annettuun paikkaan.
18/// </summary>
19/// <param name="g">Peli, johon lumiukko tehdään.</param>
20/// <param name="x">Lumiukon alimman pallon x-koordinaatti.</param>
21/// <param name="y">Lumiukon alimman pallon y-koordinaatti.</param>
22public static void PiirraLumiukko(Game peli, double x, double y)
23{
24 PhysicsObject p1, p2, p3;
25 p1 = new PhysicsObject(2 * 100.0, 2 * 100.0, Shape.Circle);
26 p1.X = x;
27 p1.Y = y;
28 peli.Add(p1);
29
30 p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
31 p2.X = x;
32 p2.Y = p1.Y + 100 + 50;
33 peli.Add(p2);
34
35 p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
36 p3.X = x;
37 p3.Y = p2.Y + 50 + 30;
38 peli.Add(p3);
39}
40```
timApp/static/data/ohjelmointi1/block_00266
(7 / 0)
  
1Varsinaista aliohjelman toiminnallisuutta kirjoittaessa käytämme nyt
2parametreille antamiamme nimiä. Alimman ympyrän keskipisteen
3koordinaatit saamme nyt suoraan parametreista x ja y, mutta muiden
4ympyröiden keskipisteet meidän täytyy laskea alimman ympyrän
5koordinaateista. Tämä tapahtuu täysin samalla tavalla kuin edellisessä
6esimerkissä. Itse asiassa, jos vertaa aliohjelman sisältöä edellisen
7esimerkin koodiin, on se täysin sama.
timApp/static/data/ohjelmointi1/block_00267
(6 / 0)
  
1C\#:ssa on tapana aloittaa aliohjelmien ja metodien nimet isolla
2kirjaimella ja nimessä esiintyvä jokainen uusi sana alkamaan isolla
3kirjaimella. Kirjoitustavasta käytetään termiä PascalCasing. Muuttujat
4kirjoitetaan pienellä alkukirjaimella, ja jokainen seuraava sana isolla
5alkukirjaimella: esimerkiksi double autonNopeus. Tästä käytetään nimeä
6camelCasing. Lisää C\#:n nimeämiskäytännöistä voit lukea sivulta
timApp/static/data/ohjelmointi1/block_00268
(1 / 0)
  
1<http://msdn.microsoft.com/en-us/library/ms229043.aspx>.
timApp/static/data/ohjelmointi1/block_00269
(1 / 0)
  
1Tarkastellaan seuraavaksi mitä aliohjelmakutsussa tapahtuu.
timApp/static/data/ohjelmointi1/block_00270
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2PiirraLumiukko(this, 0, Level.Bottom + 200.0);
3```
timApp/static/data/ohjelmointi1/block_00271
(5 / 0)
  
1Yllä olevalla kutsulla aliohjelman peli-nimiseen muuttujaan sijoitetaan
2this, eli kyseessä oleva peli, x-nimiseen muuttujaan sijoitetaan arvo 0
3(liukulukuun voi sijoittaa kokonaislukuarvon) ja aliohjelman muuttujaan
4y arvo Level.Bottom + 200.0. Voisimme sijoittaa tietenkin minkä tahansa
5muunkin liukuluvun.
timApp/static/data/ohjelmointi1/block_00272
(8 / 0)
  
1Aliohjelmakutsun suorituksessa lasketaan siis ensiksi jokaisen kutsussa
2olevan lausekkeen arvo ja sitten lasketut arvot sijoitetaan kutsussa
3olevassa järjestyksessä aliohjelman vastinparametreille. Siksi
4vastinparametrien pitää olla sijoitusyhteensopivia kutsun lausekkeiden
5kanssa. Esimerkin kutsussa lausekkeet ovat yksinkertaisia: muuttujan
6nimi (this), kokonaislukuarvo (0) ja reaalilukuarvo ( Level.Bottom +
7200.0). Ne voisivat kuitenkin olla kuinka monimutkaisia lausekkeita
8tahansa, esimerkiksi näin:
timApp/static/data/ohjelmointi1/block_00273
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2PiirraLumiukko(this, 22.7+sin(2.4), 80.1-Math.PI);
3```
timApp/static/data/ohjelmointi1/block_00274
(6 / 0)
  
1\
2\
3 *Lause* (statement) ja *lauseke* (expression) ovat eri asia. Lauseke on
4arvojen, aritmeettisten operaatioiden ja aliohjelmien (tai metodien
5yhdistelmä), joka evaluoituu tietyksi arvoksi. Lauseke on siis lauseen
6osa. Seuraava kuva selventää eroa.
timApp/static/data/ohjelmointi1/block_00275
(3 / 0)
  
1![\
2 Kuva 6: Lauseen ja lausekkeen
3ero](../src/luentomonistecsUusin_htm_m5dfaebb8.png)
timApp/static/data/ohjelmointi1/block_00276
(5 / 0)
  
1\
2 Koska määrittelimme koordinaattien parametrien tyypiksi double,
3voisimme yhtä hyvin antaa parametreiksi mitä tahansa muitakin
4desimaalilukuja. Täytyy muistaa, että C\#:ssa desimaalilukuvakioissa
5käytetään pistettä erottamaan kokonaisosa desimaaliosasta.
timApp/static/data/ohjelmointi1/block_00277
(1 / 0)
  
1Kokonaisuudessaan ohjelma näyttää nyt seuraavalta:
timApp/static/data/ohjelmointi1/block_00278
(64 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
201 using Jypeli;
302
403
504 /// @author Antti-Jussi Lakanen, Vesa Lappalainen
605 /// @version 22.8.2012
706 ///
807 /// <summary>
908 /// Piirretään lumiukkoja ja harjoitellaan aliohjelman käyttöä.
1009 /// </summary>
1110 public class Lumiukot : PhysicsGame
1211 {
1312 /// <summary>
1413 /// Pääohjelmassa laitetaan "peli" käyntiin.
1514 /// </summary>
1615 /// <param name="args">Ei käytössä</param>
1716 public static void Main(string[] args)
1817 {
1918 using (Lumiukot peli = new Lumiukot())
2019 {
2120 peli.Run();
2221 }
2322 }
2423
2524 /// <summary>
2625 /// Kutsutaan PiirraLumiukko-aliohjelmaa
2726 /// sopivilla parametreilla.
2827 /// </summary>
2928 public override void Begin()
3029 {
3130 Camera.ZoomToLevel();
3231 Level.Background.Color = Color.Black;
3332
3433 PiirraLumiukko(this, 0, Level.Bottom + 200.0);
3534 PiirraLumiukko(this, 200.0, Level.Bottom + 300.0);
3635 }
3736
3837 /// <summary>
3938 /// Aliohjelma piirtää lumiukon
4039 /// annettuun paikkaan.
4140 /// </summary>
4241 /// <param name="peli">Peliluokka</param>
4342 /// <param name="x">Lumiukon alimman pallon x-koordinaatti.</param>
4443 /// <param name="y">Lumiukon alimman pallon y-koordinaatti.</param>
4544 public static void PiirraLumiukko(Game peli, double x, double y)
4645 {
4746 PhysicsObject p1, p2, p3;
4847 p1 = new PhysicsObject(2 * 100.0, 2 * 100.0, Shape.Circle);
4948 p1.X = x;
5049 p1.Y = y;
5150 peli.Add(p1);
5251
5352 p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
5453 p2.X = x;
5554 p2.Y = p1.Y + 100 + 50;
5655 peli.Add(p2);
5756
5857 p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
5958 p3.X = x;
6059 p3.Y = p2.Y + 50 + 30;
6160 peli.Add(p3);
6261 }
6362 }
64```
timApp/static/data/ohjelmointi1/block_00279
(10 / 0)
  
1\
2\
3 Kutsuttaessa aliohjelmaa hyppää ohjelman suoritus välittömästi
4parametrien sijoitusten jälkeen kutsuttavan aliohjelman ensimmäiselle
5riville ja alkaa suorittamaan aliohjelmaa kutsussa määritellyillä
6parametreilla. Kun päästään aliohjelman koodin loppuun palataan
7jatkamaan kutsun jälkeisestä seuraavasta lausekkeesta. Esimerkissämme
8kun ensimmäinen lumiukko on piirretty, palataan tavallaan ensimmäisen
9kutsun puolipisteeseen ja sitten pääohjelma jatkuu kutsumalla toista
10lumiukon piirtämistä.
timApp/static/data/ohjelmointi1/block_00280
(2 / 0)
  
1Jos nyt haluaisimme piirtää lisää lumiukkoja, lisäisi jokainen uusi
2lumiukko koodia vain yhden rivin.
timApp/static/data/ohjelmointi1/block_00281
(3 / 0)
  
1Huomaa! Aliohjelmien käyttö selkeyttää ohjelmaa ja aliohjelmia kannattaa
2kirjoittaa, vaikka niitä kutsuttaisiin vain yhden kerran. Hyvää
3aliohjelmaa voidaan kutsua muustakin käyttöyhteydestä.
timApp/static/data/ohjelmointi1/block_00282
(2 / 0)
  
16.3 Aliohjelmien dokumentointi
2------------------------------
timApp/static/data/ohjelmointi1/block_00283
(5 / 0)
  
1Jokaisen aliohjelman tulisi sisältää dokumentaatiokommentti. Aliohjelman
2dokumentaatiokommentin tulee sisältää ainakin seuraavat asiat: Lyhyt
3kuvaus aliohjelman toiminnasta, selitys kaikista parametreista sekä
4selitys mahdollisesta paluuarvosta. Nämä asiat kuvataan tägien avulla
5seuraavasti:
timApp/static/data/ohjelmointi1/block_00284
(6 / 0)
  
1- Dokumentaatiokommentin alkuun laitetaan \<summary\>-tagien väliin
2 lyhyt ja selkeä kuvaus aliohjelman toiminnasta.
3
4- Jokainen parametri selitetään omien \<param\>-tagien väliin ja
5
6- paluuarvo \<returns\>-tagien väliin.
timApp/static/data/ohjelmointi1/block_00285
(2 / 0)
  
1PiirraLumiukko-aliohjelman dokumentaatiokommentit on edellisessä
2esimerkissämme riveillä 36-41.
timApp/static/data/ohjelmointi1/block_00286
(1 / 0)
  
1\
timApp/static/data/ohjelmointi1/block_00287
(9 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
236 /// <summary>
337 /// Aliohjelma piirtää lumiukon
438 /// annettuun paikkaan.
539 /// </summary>
640 /// <param name="g">Peliluokka</param>
741 /// <param name="x">Lumiukon alimman pallon x-koordinaatti.</param>
842 /// <param name="y">Lumiukon alimman pallon y-koordinaatti.</param>
9```
timApp/static/data/ohjelmointi1/block_00288
(2 / 0)
  
1*Doxygen*-työkalun (ks. <http://en.wikipedia.org/wiki/Doxygen>) tuottama
2HTML-sivu tästä luokasta näyttäisi nyt seuraavalta:
timApp/static/data/ohjelmointi1/block_00289
(3 / 0)
  
1![\
2 Kuva 7: Osa Lumiukot-luokan
3dokumentaatiosta](../src/luentomonistecsUusin_htm_5219b95e.png)
timApp/static/data/ohjelmointi1/block_00290
(7 / 0)
  
1\
2 Dokumentaatiossa näkyy kaikki luokan aliohjelmat ja metodit. Huomaa,
3että Doxygen nimittää sekä aliohjelmia että metodeja jäsenfunktioiksi
4(member functions). Kuten sanottu, nimitykset vaihtelevat
5kirjallisuudessa, ja tässä kohtaa käytössä on hieman harvinaisempi
6nimeämistapa. Kysymys on kuitenkin samasta asiasta, josta me tällä
7kurssilla käytämme nimeä aliohjelmat ja metodit.
timApp/static/data/ohjelmointi1/block_00291
(3 / 0)
  
1Jokaisesta aliohjelmasta ja metodista löytyy lisäksi tarkemmat tiedot
2Detailed Description -kohdasta. Aliohjelman PiirraLumiukko dokumentaatio
3parametreineen näkyy kuvan alaosassa.
timApp/static/data/ohjelmointi1/block_00292
(1 / 0)
  
1### 6.3.1 Huomautus
timApp/static/data/ohjelmointi1/block_00293
(4 / 0)
  
1Kaikki PiirraLumiukko-aliohjelmassa tarvittava tieto välitettiin
2parametrien avulla, eikä aliohjelman suorituksen aikana tarvittu
3aliohjelman ulkopuolisia tietoja. Tämä on tyypillistä aliohjelmille, ja
4usein lisäksi toivottava ominaisuus.
timApp/static/data/ohjelmointi1/block_00294
(2 / 0)
  
16.4 Aliohjelmat, metodit ja funktiot
2------------------------------------
timApp/static/data/ohjelmointi1/block_00295
(8 / 0)
  
1Kuten ehkä huomasit, aliohjelmilla ja metodeilla on paljon yhteistä.
2Monissa kirjoissa nimitetään myös aliohjelmia metodeiksi. Tällöin
3aliohjelmat erotetaan olioiden metodeista nimittämällä niitä
4staattisiksi metodeiksi. Tässä monisteessa metodeista puhutaan kuitenkin
5vain silloin, kun tarkoitetaan olioiden toimintoja. Jypelin
6dokumentaatiosta tutkit RandomGen-luokan staattisia metodeja, millä
7voidaan luoda esimerkiksi satunnaisia lukuja. Yksittäinen pallo
8poistettiin metodilla Destroy, joka on olion toiminto.
timApp/static/data/ohjelmointi1/block_00296
(4 / 0)
  
1Aliohjelmista puhutaan tällä kurssilla, koska sitä termiä käytetään
2monissa muissa ohjelmointikielissä. Tämä kurssi onkin ensisijaisesti
3ohjelmoinnin kurssi, jossa käytetään C\#-kieltä. Päätavoitteena on siis
4oppia ohjelmoimaan ja työkaluna meillä sen opettelussa on C\#-kieli.
timApp/static/data/ohjelmointi1/block_00297
(3 / 0)
  
1Aliohjelmamme PiirraLumiukko ei palauttanut mitään arvoa. Aliohjelmaa
2(tai metodia) joka palauttaa jonkun arvon voidaan kutsua myös tarkemmin
3*funktioksi* (function).
timApp/static/data/ohjelmointi1/block_00298
(4 / 0)
  
1Aliohjelmia ja metodeja nimitetään eri tavoin eri kielissä. Esimerkiksi
2C++-kielessä sekä aliohjelmia että metodeja sanotaan funktioiksi.
3Metodeita nimitetään C++-kielessä tarkemmin vielä jäsenfunktioiksi,
4kuten Doxygen teki myös C\#:n tapauksessa.
timApp/static/data/ohjelmointi1/block_00299
(1 / 0)
  
1Kerrataan vielä lyhyesti aliohjelman, funktion ja metodin erot.
timApp/static/data/ohjelmointi1/block_00300
(4 / 0)
  
1**Aliohjelma**\
2 Osaohjelma, joka voi tehdä kaikki toimensa käyttäen hyväkseen vain
3parametrilistassa tuotua tietoa. Paluuarvon tyyppinä on void, jolloin
4aliohjelma ei palauta mitään arvoa.
timApp/static/data/ohjelmointi1/block_00301
(6 / 0)
  
1**Funktio\
2**Aliohjelma, joka palauttaa jonkin tuloksen, esimerkiksi kahden luvun
3keskiarvon. Tämän määritelmän mukaan funktiossa on aina return-lause
4jonka perässä on lauseke, esimerkiksi return (a+b)/2.0; Puhtaassa
5aliohjelmassakin (ks. edellinen kohta) voi olla return-lause, mutta sen
6perässä ei ole lauseketta.
timApp/static/data/ohjelmointi1/block_00302
(7 / 0)
  
1**Metodi\
2**Aliohjelma, joka tarvitsee tehtävän suorittamiseksi kohteena olevan
3olion omia tietoja. Näitä käytetään tällä kurssilla, mutta ei tehdä
4alkupään esimerkeissä itse. Lopullisessa pelissä voi tulla tehtäväksi
5myös metodeja, jotka tarvitsevat peliluokan-olion tietoja toimintansa
6toteuttamiseen. Joku voi myös mahdollisesti tehdä vaikka uuden
7aseluokan, jolle kirjoitetaan omia metodeja.
timApp/static/data/ohjelmointi1/block_00303
(2 / 0)
  
1Metodi voi myös funktion tapaan palauttaa arvon tai aliohjelman tapaan
2olla palauttamatta. Emme erottele tätä enää eri nimillä.
timApp/static/data/ohjelmointi1/block_00304
(2 / 0)
  
17. Muuttujat
2============
timApp/static/data/ohjelmointi1/block_00305
(9 / 0)
  
1Muuttujat (variable) toimivat ohjelmassa tietovarastoina erilaisille
2asioille. Muuttuja on kuin pieni laatikko, johon voidaan varastoida
3asioita, esimerkiksi lukuja, sanoja, tietoa ohjelman käyttäjästä ja
4paljon muuta. Ilman muuttujia järkevä tiedon käsittely olisi oikeastaan
5mahdotonta. Olemme jo ohimennen käyttäneetkin muuttujia, esimerkiksi
6Lumiukko-esimerkissä teimme PhysicsObject-tyyppisiä muuttujia p1, p2 ja
7p3. Vastaavasti Lumiukko-aliohjelman parametrit (Game peli, double x,
8double y) ovat myös muuttujia: Game-tyyppinen oliomuuttuja peli, sekä
9double-alkeistietotyyppiset muuttujat x ja y.
timApp/static/data/ohjelmointi1/block_00306
(4 / 0)
  
1Termi *muuttuja* on lainattu ohjelmointiin matematiikasta, mutta niitä
2ei tule kuitenkaan sekoittaa keskenään - muuttuja matematiikassa ja
3muuttuja ohjelmoinnissa tarkoittavat hieman eri asioita. Tulet
4huomaamaan tämän seuraavien kappaleiden aikana.
timApp/static/data/ohjelmointi1/block_00307
(7 / 0)
  
1Muuttujien arvot tallennetaan keskusmuistiin tai rekistereihin, mutta
2ohjelmointikielissä voimme antaa kullekin muuttujalle nimen
3(identifier), jotta muuttujan arvon käsittely olisi helpompaa. Muuttujan
4nimi onkin ohjelmointikielten helpotus, sillä näin ohjelmoijan ei
5tarvitse tietää tarvitsemansa tiedon keskusmuisti- tai
6rekisteriosoitetta, vaan riittää muistaa itse nimeämänsä muuttujan nimi.
7[VES]
timApp/static/data/ohjelmointi1/block_00308
(2 / 0)
  
17.1 Muuttujan määrittely
2------------------------
timApp/static/data/ohjelmointi1/block_00309
(4 / 0)
  
1Kun matemaatikko sanoo, että ”n on yhtäsuuri kuin 1”, tarkoittaa se,
2että tuo termi (eli muuttuja) n on jollain käsittämättömällä tavalla
3sama kuin luku 1. Matematiikassa muuttujia voidaan esitellä tällä
4tavalla ”häthätää”.
timApp/static/data/ohjelmointi1/block_00310
(2 / 0)
  
1Ohjelmoijan on kuitenkin tehtävä vastaava asia hieman tarkemmin.
2C\#-kielessä tämä tapahtuisi kirjoittamalla seuraavasti:
timApp/static/data/ohjelmointi1/block_00311
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2int n;
3n = 1;
4```
timApp/static/data/ohjelmointi1/block_00312
(5 / 0)
  
1Ensimmäinen rivi tarkoittaa väljästi sanottuna, että ”lohkaise pieni
2pala - johon mahtuu int-kokoinen arvo - säilytystilaa tietokoneen
3muistista, ja käytä siitä jatkossa nimeä n. Toisella rivillä
4julistetaan, että ”talleta arvo 1 muuttujaan, jonka nimi on n, siten
5korvaten sen, mitä kyseisessä säilytystilassa mahdollisesti jo on”.
timApp/static/data/ohjelmointi1/block_00313
(1 / 0)
  
1Mikä sitten on tuo edellisen esimerkin int?
timApp/static/data/ohjelmointi1/block_00314
(12 / 0)
  
1C\#:ssa jokaisella muuttujalla täytyy olla *tietotyyppi* (usein myös
2lyhyesti *tyyppi*). Tietotyyppi on määriteltävä, jotta ohjelma tietäisi,
3millaista tietoa muuttujaan tullaan tallentamaan. Toisaalta tietotyyppi
4on määriteltävä siksi, että ohjelma osaa varata muistista sopivan
5kokoisen lohkareen muuttujan sisältämää tietoa varten. Esimerkiksi
6int-tyypin tapauksessa tilantarve olisi 32 bittiä (4 tavua), byte-tyypin
7tapauksessa 8 bittiä (1 tavu) ja double-tyypin 64 bittiä (8 tavua).
8Muuttuja määritellään (declare) kirjoittamalla ensiksi tietotyyppi ja
9sen perään muuttujan nimi. Muuttujan nimet aloitetaan C\#ssa pienellä
10kirjaimella, jonka jälkeen jokainen uusi sana alkaa aina isolla
11kirjaimella. Kuten aiemmin mainittiin, tämä nimeämistapa on nimeltään
12camelCasing.
timApp/static/data/ohjelmointi1/block_00315
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2muuttujanTietotyyppi muuttujanNimi;
3```
timApp/static/data/ohjelmointi1/block_00316
(4 / 0)
  
1Tuo mainitsemamme int on siis tietotyyppi, ja int-tyyppiseen muuttujaan
2voi tallentaa kokonaislukuja. Muuttujaan n voimme laittaa lukuja 1, 2,
33, samoin 0, -1, -2, ja niin edelleen, mutta emme lukua 0.1 tai sanaa
4”Moi”.
timApp/static/data/ohjelmointi1/block_00317
(1 / 0)
  
1Henkilön iän voisimme tallentaa seuraavaan muuttujaan:
timApp/static/data/ohjelmointi1/block_00318
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2int henkilonIka;
3```
timApp/static/data/ohjelmointi1/block_00319
(2 / 0)
  
1Huomaa, että tässä emme aseta muuttujalle mitään arvoa, vain
2määrittelemme muuttujan int-tyyppiseksi ja annamme sille nimen.
timApp/static/data/ohjelmointi1/block_00320
(3 / 0)
  
1Samantyyppisiä muuttujia voidaan määritellä kerralla useampia
2erottamalla muuttujien nimet pilkulla. Tietotyyppiä double käytetään,
3kun halutaan tallentaa desimaalilukuja.
timApp/static/data/ohjelmointi1/block_00321
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2double paino, pituus;
3```
timApp/static/data/ohjelmointi1/block_00322
(1 / 0)
  
1Määrittely onnistuu toki myös erikseen.
timApp/static/data/ohjelmointi1/block_00323
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2double paino;
3double pituus;
4```
timApp/static/data/ohjelmointi1/block_00324
(2 / 0)
  
17.2 Alkeistietotyypit
2---------------------
timApp/static/data/ohjelmointi1/block_00325
(5 / 0)
  
1C\#:n tietotyypit voidaan jakaa alkeistietotyyppeihin (primitive types)
2ja oliotietotyyppeihin (reference types). Oliotietotyyppeihin kuuluu
3muun muassa käyttämämme PhysicsObject-tyyppi, jota pallot p1 jne.
4olivat, sekä merkkijonojen tallennukseen tarkoitettu String-olio.
5Oliotyyppejä käsitellään myöhemmin luvussa 8.
timApp/static/data/ohjelmointi1/block_00326
(6 / 0)
  
1Eri tietotyypit vaativat eri määrän kapasiteettia tietokoneen muistista.
2Vaikka nykyajan koneissa on paljon muistia, on hyvin tärkeää valita
3oikean tyyppinen muuttuja kuhunkin tilanteeseen. Suurissa ohjelmissa
4ongelma korostuu hyvin nopeasti käytettäessä muuttujia, jotka kuluttavat
5tilanteeseen nähden kohtuuttoman paljon muistikapasiteettia. C\#:n
6alkeistietotyypit on lueteltu alla.
timApp/static/data/ohjelmointi1/block_00327
(1 / 0)
  
1Taulukko 1: C\#:n alkeistietotyypit koon mukaan järjestettynä.
timApp/static/data/ohjelmointi1/block_00328
(1 / 0)
  
1C\#-merkki
timApp/static/data/ohjelmointi1/block_00329
(1 / 0)
  
1Koko
timApp/static/data/ohjelmointi1/block_00330
(1 / 0)
  
1Selitys
timApp/static/data/ohjelmointi1/block_00331
(1 / 0)
  
1Arvoalue
timApp/static/data/ohjelmointi1/block_00332
(1 / 0)
  
1bool
timApp/static/data/ohjelmointi1/block_00333
(1 / 0)
  
11 bitti
timApp/static/data/ohjelmointi1/block_00334
(1 / 0)
  
1kaksiarvoinen tietotyyppi
timApp/static/data/ohjelmointi1/block_00335
(1 / 0)
  
1true tai false
timApp/static/data/ohjelmointi1/block_00336
(1 / 0)
  
1sbyte
timApp/static/data/ohjelmointi1/block_00337
(1 / 0)
  
18 bittiä
timApp/static/data/ohjelmointi1/block_00338
(1 / 0)
  
1yksi tavu
timApp/static/data/ohjelmointi1/block_00339
(1 / 0)
  
1-128..127
timApp/static/data/ohjelmointi1/block_00340
(1 / 0)
  
1byte
timApp/static/data/ohjelmointi1/block_00341
(1 / 0)
  
18 bittiä
timApp/static/data/ohjelmointi1/block_00342
(1 / 0)
  
1yksi tavu (etumerkitön)
timApp/static/data/ohjelmointi1/block_00343
(1 / 0)
  
10..255
timApp/static/data/ohjelmointi1/block_00344
(1 / 0)
  
1char
timApp/static/data/ohjelmointi1/block_00345
(1 / 0)
  
116 bittiä
timApp/static/data/ohjelmointi1/block_00346
(1 / 0)
  
1yksi merkki
timApp/static/data/ohjelmointi1/block_00347
(1 / 0)
  
1kaikki merkit
timApp/static/data/ohjelmointi1/block_00348
(1 / 0)
  
1short
timApp/static/data/ohjelmointi1/block_00349
(1 / 0)
  
116 bittiä
timApp/static/data/ohjelmointi1/block_00350
(1 / 0)
  
1pieni kokonaisluku
timApp/static/data/ohjelmointi1/block_00351
(1 / 0)
  
1-32,768..32,767
timApp/static/data/ohjelmointi1/block_00352
(1 / 0)
  
1ushort
timApp/static/data/ohjelmointi1/block_00353
(1 / 0)
  
116 bittiä
timApp/static/data/ohjelmointi1/block_00354
(1 / 0)
  
1pieni kokonaisluku (etumerkitön)
timApp/static/data/ohjelmointi1/block_00355
(1 / 0)
  
10..65,535
timApp/static/data/ohjelmointi1/block_00356
(1 / 0)
  
1int
timApp/static/data/ohjelmointi1/block_00357
(1 / 0)
  
132 bittiä
timApp/static/data/ohjelmointi1/block_00358
(1 / 0)
  
1kokonaisluku
timApp/static/data/ohjelmointi1/block_00359
(2 / 0)
  
1-2,147,483,648..\
2 2,147,483,647
timApp/static/data/ohjelmointi1/block_00360
(1 / 0)
  
1uint
timApp/static/data/ohjelmointi1/block_00361
(1 / 0)
  
132 bittiä
timApp/static/data/ohjelmointi1/block_00362
(1 / 0)
  
1kokonaisluku (etumerkitön)
timApp/static/data/ohjelmointi1/block_00363
(1 / 0)
  
10..4,294,967,295
timApp/static/data/ohjelmointi1/block_00364
(1 / 0)
  
1float
timApp/static/data/ohjelmointi1/block_00365
(1 / 0)
  
132 bittiä
timApp/static/data/ohjelmointi1/block_00366
(1 / 0)
  
1liukuluku
timApp/static/data/ohjelmointi1/block_00367
(1 / 0)
  
1noin 7 desimaalin tarkkuus,
timApp/static/data/ohjelmointi1/block_00368
(1 / 0)
  
1±1.5 × 10^-45^.. ±3.4 × 10^38^
timApp/static/data/ohjelmointi1/block_00369
(1 / 0)
  
1long
timApp/static/data/ohjelmointi1/block_00370
(1 / 0)
  
164 bittiä
timApp/static/data/ohjelmointi1/block_00371
(1 / 0)
  
1iso kokonaisluku
timApp/static/data/ohjelmointi1/block_00372
(1 / 0)
  
1-2^63^..2^63^-1
timApp/static/data/ohjelmointi1/block_00373
(1 / 0)
  
1ulong
timApp/static/data/ohjelmointi1/block_00374
(1 / 0)
  
164 bittiä
timApp/static/data/ohjelmointi1/block_00375
(1 / 0)
  
1iso kokonaisluku (etumerkitön)
timApp/static/data/ohjelmointi1/block_00376
(2 / 0)
  
10..\
2 18,446,744,073,709,615
timApp/static/data/ohjelmointi1/block_00377
(1 / 0)
  
1double
timApp/static/data/ohjelmointi1/block_00378
(1 / 0)
  
164 bittiä
timApp/static/data/ohjelmointi1/block_00379
(1 / 0)
  
1tarkka liukuluku
timApp/static/data/ohjelmointi1/block_00380
(1 / 0)
  
1noin 15 desimaalin tarkkuus,
timApp/static/data/ohjelmointi1/block_00381
(1 / 0)
  
1±5.0 × 10^-324^.. ±1.7 × 10^308^
timApp/static/data/ohjelmointi1/block_00382
(1 / 0)
  
1decimal
timApp/static/data/ohjelmointi1/block_00383
(1 / 0)
  
1128 bittiä
timApp/static/data/ohjelmointi1/block_00384
(1 / 0)
  
1erittäin tarkka liukuluku
timApp/static/data/ohjelmointi1/block_00385
(1 / 0)
  
1Noin 28 luvun tarkkuus
timApp/static/data/ohjelmointi1/block_00386
(11 / 0)
  
1\
2\
3\
4\
5 Tässä monisteessa suositellaan, että desimaalilukujen talletukseen
6käytettäväksi aina double-tietotyyppiä (jossain tapauksissa jopa
7decimal-tyyppiä), vaikka monessa paikassa float-tietotyyppiä
8käytetäänkin. Tämä johtuu siitä, että liukuluvut, joina desimaaliluvut
9tietokoneessa käsitellään, ovat harvoin tarkkoja arvoja tietokoneessa.
10Itse asiassa ne ovat tarkkoja vain kun ne esittävät jotakin kahden
11potenssin kombinaatiota, kuten esimerkiksi 2.0, 7.0, 0.5 tai 0.375.
timApp/static/data/ohjelmointi1/block_00387
(6 / 0)
  
1Useimmiten liukuluvut ovat pelkkiä approksimaatioita oikeasta
2reaaliluvusta. Esimerkiksi lukua 0.1 ei pystytä tietokoneessa esittämään
3biteillä tarkasti. Tällöin laskujen määrän kasvaessa lukujen epätarkkuus
4vain lisääntyy. Tämän takia onkin turvallisempaa käyttää aina
5double-tietotyyppiä, koska se suuremman bittimääränsä takia pystyy
6tallettamaan enemmän merkitseviä desimaaleja.
timApp/static/data/ohjelmointi1/block_00388
(5 / 0)
  
1Tietyissä sovelluksissa, joissa mahdollisimman suuri tarkkuus on
2välttämätön (kuten pankki- tai nanotason fysiikkasovellukset), on
3suositeltavaa käyttää korkeimpaa mahdollista tarkkuutta tarjoavaa
4decimal-tyyppiä. Reaalilukujen esityksestä tietokoneessa puhutaan lisää
5kohdassa [26.6](#o246Liukuluku_floatingpoint). [VES][KOS]
timApp/static/data/ohjelmointi1/block_00389
(2 / 0)
  
17.3 Arvon asettaminen muuttujaan
2--------------------------------
timApp/static/data/ohjelmointi1/block_00390
(5 / 0)
  
1Muuttujaan asetetaan arvo sijoitusoperaattorilla (assignment operator)
2"=". Lauseita, joilla asetetaan muuttujille arvoja sanotaan
3sijoituslauseiksi (assignment statement). On tärkeää huomata, että
4sijoitus tapahtuu aina oikealta vasemmalle: sijoitettava on
5yhtäsuuruusmerkin oikealla puolella ja kohde merkin vasemmalla puolella.
timApp/static/data/ohjelmointi1/block_00391
(6 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2x = 20.0;
3henkilonIka = 23;
4paino = 80.5;
5pituus = 183.5;
6```
timApp/static/data/ohjelmointi1/block_00392
(1 / 0)
  
1Muuttujaan voi asettaa arvon myös jo määrittelyn yhteydessä.
timApp/static/data/ohjelmointi1/block_00393
(6 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2bool onkoKalastaja = true;
3char merkki = 't';
4int kalojenLkm = 0;
5double luku1 = 0, luku2 = 0, luku3 = 0;
6```
timApp/static/data/ohjelmointi1/block_00394
(8 / 0)
  
1Muuttuja täytyy olla määritelty tietyn tyyppiseksi ennen kuin siihen voi
2asettaa arvoa. Muuttujaan voi asettaa vain määrittelyssä annetun
3tietotyypin mukaisia arvoja tai sen kanssa *sijoitusyhteensopivia*
4arvoja. Esimerkiksi liukulukutyyppeihin (float ja double) voi sijoittaa
5myös kokonaislukutyyppisiä arvoja, sillä kokonaisluvut on reaalilukujen
6osajoukko. Alla sijoitamme arvon 4 muuttujaan nimeltä luku2, ja
7kolmannella rivillä luku2-muuttujan sisältämän arvon (4) muuttujaan,
8jonka nimi on luku1.
timApp/static/data/ohjelmointi1/block_00395
(5 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2double luku1;
3int luku2 = 4;
4luku1 = luku2;
5```
timApp/static/data/ohjelmointi1/block_00396
(2 / 0)
  
1Toisinpäin tämä ei onnistu: double-tyyppistä arvoa ei voi sijoittaa
2int-tyyppiseen muuttujaan. Alla oleva koodi ei kääntyisi:
timApp/static/data/ohjelmointi1/block_00397
(6 / 0)
  
1``` {.huonoesimerkki-western lang="zxx" xml:lang="zxx"}
2//TÄMÄ KOODI EI KÄÄNNY!
3int luku1;
4double luku2 = 4.0;
5luku1 = luku2;
6```
timApp/static/data/ohjelmointi1/block_00398
(4 / 0)
  
1Kun decimal-tyyppinen muuttuja alustetaan jollain luvulla, tulee luvun
2perään (ennen puolipistettä) laittaa m (tai M)-merkki. Samoin
3float-tyyppisten muuttujien alustuksessa perään laitetaan f (tai
4F)-merkki.
timApp/static/data/ohjelmointi1/block_00399
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2decimal tilinSaldo = 3498.98m;
3float lampotila = -4.8f;
4```
timApp/static/data/ohjelmointi1/block_00400
(2 / 0)
  
1Huomaa, että char-tyyppiseen muuttujaan sijoitetaan arvo laittamalla
2merkki heittomerkkien väliin, esimerkiksi näin.
timApp/static/data/ohjelmointi1/block_00401
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2char ekaKirjain = 'k';
3```
timApp/static/data/ohjelmointi1/block_00402
(3 / 0)
  
1Näin sen erottaa myöhemmin käsiteltävästä String-tyyppiseen muuttujaan
2sijoittamisesta, jossa sijoitettava merkkijono laitetaan lainausmerkkien
3väliin, esimerkiksi seuraavasti.
timApp/static/data/ohjelmointi1/block_00403
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2String omaNimi = "Antti-Jussi";
3```
timApp/static/data/ohjelmointi1/block_00404
(2 / 0)
  
1Sijoituslause voi sisältää myös monimutkaisiakin lausekkeita,
2esimerkiksi aritmeettisia operaatioita:
timApp/static/data/ohjelmointi1/block_00405
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2double numeroidenKeskiarvo = (2 + 4 + 1 + 5 + 3 + 2) / 6.0;
3```
timApp/static/data/ohjelmointi1/block_00406
(1 / 0)
  
1Sijoituslause voi sisältää myös muuttujia.
timApp/static/data/ohjelmointi1/block_00407
(5 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2double huoneenPituus = 540.0;
3double huoneenLeveys = huoneenPituus;
4double huoneenAla = huoneenPituus * huoneenLeveys;
5```
timApp/static/data/ohjelmointi1/block_00408
(2 / 0)
  
1Eli sijoitettava voi olla mikä tahansa lauseke, joka tuottaa muuttujalle
2kelpaavan arvon.
timApp/static/data/ohjelmointi1/block_00409
(3 / 0)
  
1C\#:ssa täytyy aina asettaa joku arvo muuttujaan *ennen* sen
2käyttämistä. Kääntäjä ei käännä koodia, jossa käytetään muuttujaa jolle
3ei ole asetettu arvoa. Alla oleva ohjelma ei siis kääntyisi.
timApp/static/data/ohjelmointi1/block_00410
(11 / 0)
  
1``` {.huonoesimerkki-western lang="zxx" xml:lang="zxx"}
2// TÄMÄ OHJELMA EI KÄÄNNY
3public class Esimerkki
4{
5 public static void Main(string[] args)
6 {
7 int ika;
8 System.Console.WriteLine(ika);
9 }
10}
11```
timApp/static/data/ohjelmointi1/block_00411
(1 / 0)
  
1Virheilmoitus näyttää tältä:
timApp/static/data/ohjelmointi1/block_00412
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2Esimerkki.cs(4,40): error CS0165: Use of unassigned local variable
3 'ika'
4```
timApp/static/data/ohjelmointi1/block_00413
(3 / 0)
  
1Kääntäjä kertoo, että ika-nimistä muuttuja yritetään käyttää, vaikka
2sille ei ole osoitettu mitään arvoa. Tämä ei ole sallittua, joten
3ohjelman kääntämisyritys päättyy tähän.
timApp/static/data/ohjelmointi1/block_00414
(2 / 0)
  
17.4 Muuttujan nimeäminen
2------------------------
timApp/static/data/ohjelmointi1/block_00415
(10 / 0)
  
1Muuttujan nimen täytyy olla siihen tallennettavaa tietoa kuvaava.
2Yleensä pelkkä yksi kirjain on huono nimi muuttujalle, sillä se harvoin
3kuvaa kovin hyvin muuttujaa. Kuvaava muuttujan nimi selkeyttää koodia ja
4vähentää kommentoimisen tarvetta. Lyhyt muuttujan nimi ei ole
5itseisarvo. Vielä parikymmentä vuotta sitten se saattoi olla sitä, koska
6se nopeutti koodin kirjoittamista. Nykyaikaisia kehitysympäristöjä
7käytettäessä tämä ei enää pidä paikkaansa, sillä editorit osaavat
8täydentää muuttujan nimen samalla kun koodia kirjoitetaan, joten niitä
9ei käytännössä koskaan tarvitse kirjoittaa kokonaan, paitsi tietysti
10ensimmäisen kerran.
timApp/static/data/ohjelmointi1/block_00416
(5 / 0)
  
1Yksikirjaimisia muuttujien nimiäkin voi perustellusti käyttää, jos
2niillä on esimerkiksi jo matematiikasta tai fysiikasta ennestään tuttu
3merkitys. Nimet x ja y ovat hyviä kuvaamaan koordinaatteja. Nimi l (eng.
4length) viittaa pituuteen ja r (eng. radius) säteeseen. Fysikaalisessa
5ohjelmassa s voi hyvin kuvata matkaa.
timApp/static/data/ohjelmointi1/block_00417
(1 / 0)
  
1Huomaa! Muuttujan nimi ei voi C\#:ssa alkaa numerolla.
timApp/static/data/ohjelmointi1/block_00418
(3 / 0)
  
1C\#:n koodauskäytänteiden mukaan muuttujan nimi alkaa pienellä
2kirjaimella ja jos muuttujan nimi koostuu useammasta sanasta aloitetaan
3uusi sana aina isolla kirjaimella kuten alla.
timApp/static/data/ohjelmointi1/block_00419
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2int polkupyoranRenkaanKoko;
3```
timApp/static/data/ohjelmointi1/block_00420
(3 / 0)
  
1C\#:ssa muuttujan nimi voi sisältää ääkkösiä, mutta niiden käyttö ei
2suositella, koska siirtyminen koodistosta toiseen aiheuttaa usein
3ylimääräisiä ongelmia.
timApp/static/data/ohjelmointi1/block_00421
(11 / 0)
  
1*Koodisto =* Määrittelee jokaiselle *merkistön* merkille yksikäsitteisen
2koodinumeron. Merkin numeerinen esitys on usein välttämätön
3tietokoneissa. Merkistö määrittelee joukon merkkejä ja niille nimen,
4numeron ja jonkinnäköisen muodon kuvauksen. Merkistöllä ja koodistolla
5tarkoitetaan usein samaa asiaa, kuitenkin esimerkiksi Unicode-merkistö
6sisältää useita eri koodaus tapoja (UTF-8, UTF-16, UTF-32). Koodisto on
7siis se merkistön osa, joka määrittelee merkille numeerisen koodiarvon.
8Koodistoissa syntyy ongelmia yleensä silloin, kun siirrytään jostain
9skandimerkkejä (ä,ö,å, ...) sisältävästä koodistosta seitsemänbittiseen
10ASCII-koodistoon, joka ei tue skandeja. ASCII-koodistosta puhutaan lisää
11luvussa [27](#o25_ASCIIkoodi).
timApp/static/data/ohjelmointi1/block_00422
(1 / 0)
  
1### 7.4.1 C\#:n varatut sanat
timApp/static/data/ohjelmointi1/block_00423
(2 / 0)
  
1Muuttujan nimi ei saa olla mikään ohjelmointikielen varatuista sanoista,
2eli sanoista joilla on C\#:ssa joku muu merkitys.
timApp/static/data/ohjelmointi1/block_00424
(1 / 0)
  
1Taulukko 2: C\#:n varatut sanat.
timApp/static/data/ohjelmointi1/block_00425
(18 / 0)
  
1 ---------- ---------- ----------- ------------ -----------
2 abstract do in protected true
3 as double int public try
4 base else interface readonly typeof
5 bool enum internal ref uint
6 break event is return ulong
7 byte explicit lock sbyte unchecked
8 case extern long sealed unsafe
9 catch false namespace short ushort
10 char finally new sizeof using
11 checked fixed null stackalloc virtual
12 class float object static void
13 const for operator string volatile
14 continue foreach out struct while
15 decimal goto override switch
16 default if params this
17 delegate implicit private throw
18 ---------- ---------- ----------- ------------ -----------
timApp/static/data/ohjelmointi1/block_00426
(5 / 0)
  
1\
2\
3\
4\
5 7.5 Muuttujien näkyvyys -----------------------
timApp/static/data/ohjelmointi1/block_00427
(5 / 0)
  
1Muuttujaa voi käyttää (lukea ja asettaa arvoja) vain siinä lohkossa,
2missä se on määritelty. Muuttujan määrittelyn täytyy aina olla ennen
3(koodissa ylempänä), kun sitä ensimmäisen kerran käytetään. Jos muuttuja
4on käytettävissä sanotaan, että muuttuja *näkyy*. Aliohjelman sisällä
5määritelty muuttuja ei siis näy muissa aliohjelmissa.
timApp/static/data/ohjelmointi1/block_00428
(5 / 0)
  
1Luokan sisällä muuttuja voidaan määritellä myös niin, että se näkyy
2kaikkialla, siis kaikille aliohjelmille. Kun muuttuja on näkyvissä
3kaikille ohjelman osille, sanotaan sitä *globaaliksi muuttujaksi*
4(global variable). Globaaleja muuttujia tulee välttää aina kun
5mahdollista.
timApp/static/data/ohjelmointi1/block_00429
(1 / 0)
  
1Lisätietoa muuttujien näkyvyydestä löydät wikistä osoitteessa
timApp/static/data/ohjelmointi1/block_00430
(1 / 0)
  
1<https://trac.cc.jyu.fi/projects/ohj1/wiki/MuuttujienNakyvyys>.
timApp/static/data/ohjelmointi1/block_00431
(2 / 0)
  
17.6 Vakiot
2----------
timApp/static/data/ohjelmointi1/block_00432
(1 / 0)
  
1> One man's constant is another man's variable. -Alan Perlis
timApp/static/data/ohjelmointi1/block_00433
(4 / 0)
  
1Muuttujien lisäksi ohjelmointikielissä voidaan määritellä vakioita
2(constant). Vakioiden arvoa ei voi muuttaa määrittelyn jälkeen. C\#:ssa
3vakio määritellään muuten kuten muuttuja, mutta muuttujan tyypin eteen
4kirjoitetaan lisämääre const.
timApp/static/data/ohjelmointi1/block_00434
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2const int KUUKAUSIEN_LKM = 12;
3```
timApp/static/data/ohjelmointi1/block_00435
(5 / 0)
  
1Tällä kurssilla vakiot kirjoitetaan suuraakkosin siten, että sanat
2erotetaan alaviivalla (\_). Näin ne erottaa helposti muuttujien nimistä,
3jotka alkavat pienellä kirjaimella. Muitakin kirjoitustapoja on,
4esimerkiksi Pascal Casing on toinen yleisesti käytetty vakioiden
5kirjoitusohje.
timApp/static/data/ohjelmointi1/block_00436
(2 / 0)
  
17.7 Operaattorit
2----------------
timApp/static/data/ohjelmointi1/block_00437
(5 / 0)
  
1Usein meidän täytyy tallentaa muuttujiin erilaisten laskutoimitusten
2tuloksia. C\#:ssa laskutoimituksia voidaan tehdä aritmeettisilla
3operaatioilla (arithmetic operation), joista mainittiin jo kun teimme
4lumiukkoesimerkkiä. Ohjelmassa olevia aritmeettisia laskutoimituksia
5sanotaan aritmeettisiksi lausekkeiksi (arithmetic expression).
timApp/static/data/ohjelmointi1/block_00438
(5 / 0)
  
1C\#:ssa on myös vertailuoperaattoreita (comparison operators), loogisia
2operaattoreita, bittikohtaisia operaattoreita (bitwise operators),
3arvonmuunto-operaattoreita (shortcut operators), sijoitusoperaattori =,
4is-operaattori sekä ehto-operaattori ?. Tässä luvussa käsitellään näistä
5tärkeimmät.
timApp/static/data/ohjelmointi1/block_00439
(1 / 0)
  
1### 7.7.1 Aritmeettiset operaatiot
timApp/static/data/ohjelmointi1/block_00440
(3 / 0)
  
1C\#:ssa peruslaskutoimituksia suoritetaan aritmeettisilla operaatiolla,
2joista + ja - tulivatkin esille aikaisemmissa esimerkeissä.
3Aritmeettisia operaattoreita on viisi.
timApp/static/data/ohjelmointi1/block_00441
(1 / 0)
  
1Taulukko 3: Aritmeettiset operaatiot.
timApp/static/data/ohjelmointi1/block_00442
(2 / 0)
  
1Operaat-\
2 tori
timApp/static/data/ohjelmointi1/block_00443
(1 / 0)
  
1Toiminto
timApp/static/data/ohjelmointi1/block_00444
(1 / 0)
  
1Esimerkki
timApp/static/data/ohjelmointi1/block_00445
(1 / 0)
  
1-
timApp/static/data/ohjelmointi1/block_00446
(1 / 0)
  
1yhteenlasku
timApp/static/data/ohjelmointi1/block_00447
(1 / 0)
  
1System.Console.WriteLine(1+2); // tulostaa 3
timApp/static/data/ohjelmointi1/block_00448
(1 / 0)
  
1-
timApp/static/data/ohjelmointi1/block_00449
(1 / 0)
  
1vähennyslasku
timApp/static/data/ohjelmointi1/block_00450
(1 / 0)
  
1System.Console.WriteLine(1-2); // tulostaa -1
timApp/static/data/ohjelmointi1/block_00451
(1 / 0)
  
1\*
timApp/static/data/ohjelmointi1/block_00452
(1 / 0)
  
1kertolasku
timApp/static/data/ohjelmointi1/block_00453
(1 / 0)
  
1System.Console.WriteLine(2\*3); // tulostaa 6
timApp/static/data/ohjelmointi1/block_00454
(1 / 0)
  
1/
timApp/static/data/ohjelmointi1/block_00455
(1 / 0)
  
1jakolasku
timApp/static/data/ohjelmointi1/block_00456
(1 / 0)
  
1System.Console.WriteLine(6 / 2); // tulostaa 3
timApp/static/data/ohjelmointi1/block_00457
(1 / 0)
  
1System.Console.WriteLine(7 / 2); // Huom! 3
timApp/static/data/ohjelmointi1/block_00458
(1 / 0)
  
1System.Console.WriteLine(7 / 2.0); // 3.5
timApp/static/data/ohjelmointi1/block_00459
(1 / 0)
  
1System.Console.WriteLine(7.0 / 2); // 3.5
timApp/static/data/ohjelmointi1/block_00460
(1 / 0)
  
1%
timApp/static/data/ohjelmointi1/block_00461
(1 / 0)
  
1jakojäännös (modulo)
timApp/static/data/ohjelmointi1/block_00462
(1 / 0)
  
1System.Console.WriteLine(18 % 7); // tulostaa 4
timApp/static/data/ohjelmointi1/block_00463
(1 / 0)
  
1### 7.7.2 Vertailuoperaattorit
timApp/static/data/ohjelmointi1/block_00464
(4 / 0)
  
1Vertailuoperaattoreiden avulla verrataan muuttujien arvoja keskenään.
2Vertailuoperaattorit palauttavat totuusarvon (true tai false).
3Vertailuoperaattoreita on kuusi. Lisää vertailuoperaattoreista luvussa
413.
timApp/static/data/ohjelmointi1/block_00465
(1 / 0)
  
1### 7.7.3 Arvonmuunto-operaattorit
timApp/static/data/ohjelmointi1/block_00466
(4 / 0)
  
1Arvonmuunto-operaattoreiden avulla laskutoimitukset voidaan esittää
2tiiviimmässä muodossa: esimerkiksi x++; (4 merkkiä) tarkoittaa samaa
3asiaa kuin x = x+1; (6 merkkiä). Niiden avulla voidaan myös alustaa
4muuttujia.
timApp/static/data/ohjelmointi1/block_00467
(3 / 0)
  
1\
2\
3 Taulukko 4: Arvonmuunto-operaattorit.
timApp/static/data/ohjelmointi1/block_00468
(1 / 0)
  
1Ope-raattori
timApp/static/data/ohjelmointi1/block_00469
(1 / 0)
  
1Toiminto
timApp/static/data/ohjelmointi1/block_00470
(1 / 0)
  
1Esimerkki
timApp/static/data/ohjelmointi1/block_00471
(1 / 0)
  
1++
timApp/static/data/ohjelmointi1/block_00472
(1 / 0)
  
1Lisäysoperaattori. Lisää muuttujan arvoa yhdellä.
timApp/static/data/ohjelmointi1/block_00473
(1 / 0)
  
1int luku = 0;
timApp/static/data/ohjelmointi1/block_00474
(2 / 0)
  
1\
2 System.Console.WriteLine(luku++); //tulostaa 0
timApp/static/data/ohjelmointi1/block_00475
(1 / 0)
  
1System.Console.WriteLine(luku++); //tulostaa 1
timApp/static/data/ohjelmointi1/block_00476
(1 / 0)
  
1System.Console.WriteLine(luku); //tulostaa 2
timApp/static/data/ohjelmointi1/block_00477
(1 / 0)
  
1System.Console.WriteLine(++luku); //tulostaa 3
timApp/static/data/ohjelmointi1/block_00478
(1 / 0)
  
1--
timApp/static/data/ohjelmointi1/block_00479
(1 / 0)
  
1Vähennysoperaattori. Vähentää muuttujan arvoa yhdellä.
timApp/static/data/ohjelmointi1/block_00480
(1 / 0)
  
1int luku = 5;
timApp/static/data/ohjelmointi1/block_00481
(1 / 0)
  
1System.Console.WriteLine(luku--); //tulostaa 5
timApp/static/data/ohjelmointi1/block_00482
(1 / 0)
  
1System.Console.WriteLine(luku--); //tulostaa 4
timApp/static/data/ohjelmointi1/block_00483
(1 / 0)
  
1System.Console.WriteLine(luku); //tulostaa 3
timApp/static/data/ohjelmointi1/block_00484
(1 / 0)
  
1System.Console.WriteLine(--luku); //tulostaa 2
timApp/static/data/ohjelmointi1/block_00485
(1 / 0)
  
1System.Console.WriteLine(luku); //tulostaa 2
timApp/static/data/ohjelmointi1/block_00486
(1 / 0)
  
1+=
timApp/static/data/ohjelmointi1/block_00487
(1 / 0)
  
1Lisäys-operaatio.
timApp/static/data/ohjelmointi1/block_00488
(1 / 0)
  
1int luku = 0;
timApp/static/data/ohjelmointi1/block_00489
(1 / 0)
  
1luku += 2; //luku muuttujan arvo on 2
timApp/static/data/ohjelmointi1/block_00490
(1 / 0)
  
1luku += 3; //luku muuttujan arvo on 5
timApp/static/data/ohjelmointi1/block_00491
(1 / 0)
  
1luku += -1; //luku muuttujan arvo on 4
timApp/static/data/ohjelmointi1/block_00492
(1 / 0)
  
1-=
timApp/static/data/ohjelmointi1/block_00493
(1 / 0)
  
1Vähennys-operaatio
timApp/static/data/ohjelmointi1/block_00494
(1 / 0)
  
1int luku = 0;
timApp/static/data/ohjelmointi1/block_00495
(1 / 0)
  
1luku -= 2; // luku muuttujan arvo on -2
timApp/static/data/ohjelmointi1/block_00496
(1 / 0)
  
1luku -= 1 // luku muuttujan arvon -3
timApp/static/data/ohjelmointi1/block_00497
(1 / 0)
  
1\*=
timApp/static/data/ohjelmointi1/block_00498
(1 / 0)
  
1Kertolasku-operaatio
timApp/static/data/ohjelmointi1/block_00499
(1 / 0)
  
1int luku = 1;
timApp/static/data/ohjelmointi1/block_00500
(1 / 0)
  
1luku \*= 3; // luku-muuttujan arvo on 3
timApp/static/data/ohjelmointi1/block_00501
(1 / 0)
  
1luku \*= 2; //luku-muuttujan arvo on 6
timApp/static/data/ohjelmointi1/block_00502
(1 / 0)
  
1/=
timApp/static/data/ohjelmointi1/block_00503
(1 / 0)
  
1Jakolasku-operaatio
timApp/static/data/ohjelmointi1/block_00504
(1 / 0)
  
1double luku = 27;
timApp/static/data/ohjelmointi1/block_00505
(1 / 0)
  
1luku /= 3; //luku-muuttujan arvo on 9
timApp/static/data/ohjelmointi1/block_00506
(1 / 0)
  
1luku /= 2.0; //luku-muuttujan arvo on 4.5
timApp/static/data/ohjelmointi1/block_00507
(1 / 0)
  
1%=
timApp/static/data/ohjelmointi1/block_00508
(1 / 0)
  
1Jakojäännös-operaatio
timApp/static/data/ohjelmointi1/block_00509
(1 / 0)
  
1int luku = 9;
timApp/static/data/ohjelmointi1/block_00510
(1 / 0)
  
1luku %= 5; //luku-muuttujan arvo on 4
timApp/static/data/ohjelmointi1/block_00511
(1 / 0)
  
1luku %=2; //luku-muuttujan arvo on 0
timApp/static/data/ohjelmointi1/block_00512
(8 / 0)
  
1\
2\
3\
4 Lisäysoperaattoria (++) ja vähennysoperaattoria (--) voidaan käyttää,
5ennen tai jälkeen muuttujan. Käytettäessä ennen muuttujaa, arvoa
6muutetaan ensin ja mahdollinen toiminto esimerkiksi tulostus, tehdään
7vasta sen jälkeen. Jos operaattori sen sijaan on muuttujan perässä,
8toiminto tehdään ensiksi ja arvoa muutetaan vasta sen jälkeen.
timApp/static/data/ohjelmointi1/block_00513
(4 / 0)
  
1Huomaa! Arvonmuunto-operaattorit ovat ns. sivuvaikutuksellisia
2operaattoreita. Toisin sanoen, operaatio muuttaa muuttujan arvoa toisin
3kuin esimerkiksi aritmeettiset operaatiot. Seuraava esimerkki
4havainnollistaa asiaa.
timApp/static/data/ohjelmointi1/block_00514
(2 / 0)
  
1\
2\
timApp/static/data/ohjelmointi1/block_00515
(8 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2int luku1 = 5;
3int luku2 = 5;
4System.Console.WriteLine(++luku1); // tulostaa 6;
5System.Console.WriteLine(luku2 + 1 ); // tulostaa 6;
6System.Console.WriteLine(luku1); // 6
7System.Console.WriteLine(luku2); // 5
8```
timApp/static/data/ohjelmointi1/block_00516
(1 / 0)
  
1### 7.7.4 Aritmeettisten operaatioiden suoritusjärjestys
timApp/static/data/ohjelmointi1/block_00517
(4 / 0)
  
1Aritmeettisten operaatioiden suoritusjärjestys on vastaava kuin
2matematiikan laskujärjestys. Kerto- ja jakolaskut suoritetaan ennen
3yhteen- ja vähennyslaskua. Lisäksi sulkeiden sisällä olevat lausekkeet
4suoritetaan ensin.
timApp/static/data/ohjelmointi1/block_00518
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2System.Console.WriteLine(5 + 3 * 4 - 2); //tulostaa 15
3System.Console.WriteLine((5 + 3) * (4 - 2)); //tulostaa 16
4```
timApp/static/data/ohjelmointi1/block_00519
(2 / 0)
  
17.8 Huomautuksia
2----------------
timApp/static/data/ohjelmointi1/block_00520
(1 / 0)
  
1### 7.8.1 Kokonaisluvun tallentaminen liukulukumuuttujaan
timApp/static/data/ohjelmointi1/block_00521
(4 / 0)
  
1Kun yritetään tallentaa kokonaislukujen jakolaskun tulosta
2liukulukutyyppiseen (float tai double) muuttujaan, voi tulos tallettua
3kokonaislukuna, jos jakaja ja jaettava ovat molemmat ilmoitettu ilman
4desimaaliosaa.
timApp/static/data/ohjelmointi1/block_00522
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2double laskunTulos = 5 / 2;
3System.Console.WriteLine(laskunTulos); // tulostaa 2
4```
timApp/static/data/ohjelmointi1/block_00523
(2 / 0)
  
1Jos kuitenkin vähintään yksi jakolaskun luvuista on desimaalimuodossa,
2niin laskun tulos tallentuu muuttujaan oikein.
timApp/static/data/ohjelmointi1/block_00524
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2double laskunTulos = 5 / 2.0;
3System.Console.WriteLine(laskunTulos); // tulostaa 2.5
4```
timApp/static/data/ohjelmointi1/block_00525
(3 / 0)
  
1Liukuluvuilla laskettaessa kannattaa pitää desimaalimuodossa myös luvut,
2joilla ei ole desimaaliosaa, eli ilmoittaa esimerkiksi luku 5 muodossa
35.0.
timApp/static/data/ohjelmointi1/block_00526
(1 / 0)
  
1Kokonaisluvuilla laskettaessa kannattaa huomioida seuraava:
timApp/static/data/ohjelmointi1/block_00527
(10 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2int laskunTulos = 5 / 4;
3System.Console.WriteLine(laskunTulos); // tulostaa 1
4
5laskunTulos = 5 / 6;
6System.Console.WriteLine(laskunTulos); // tulostaa 0
7
8laskunTulos = 7 / 3;
9System.Console.WriteLine(laskunTulos); // tulostaa 2
10```
timApp/static/data/ohjelmointi1/block_00528
(3 / 0)
  
1Kokonaisluvuilla laskettaessa lukuja ei siis pyöristetä lähimpään
2kokonaislukuun, vaan desimaaliosa menee C\#:n jakolaskuissa ikään kuin
3"hukkaan".
timApp/static/data/ohjelmointi1/block_00529
(1 / 0)
  
1### 7.8.2 Lisäys- ja vähennysoperaattoreista
timApp/static/data/ohjelmointi1/block_00530
(1 / 0)
  
1On neljä tapaa kasvattaa luvun arvoa yhdellä.
timApp/static/data/ohjelmointi1/block_00531
(6 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2++a;
3a++; // idiomi
4a += 1;
5a = a + 1; // huonoin muutettavuuden ja kirjoittamisen kannalta
6```
timApp/static/data/ohjelmointi1/block_00532
(6 / 0)
  
1Ohjelmoinnissa *idiomilla* tarkoitetaan tapaa jolla asia yleensä
2kannattaa tehdä. Näistä a++ on ohjelmoinnissa vakiintunut tapa ja
3(yleensä) suositeltavin, siis idiomi. Kuitenkin, jos lukua a pitäisikin
4kasvattaa (tai vähentää) kahdella tai kolmella, ei tämä tapa enää
5toimisi. Seuraavassa esimerkissä tarkastellaan eri tapoja kahdella
6vähentämiseksi. Siihen on kolme vaihtoehtoista tapaa.
timApp/static/data/ohjelmointi1/block_00533
(5 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2a -= 2;
3a += -2; // lisättävä luku voisi olla muuttuja. Luku voi olla myös negatiivinen
4a = a - 2;
5```
timApp/static/data/ohjelmointi1/block_00534
(4 / 0)
  
1Tässä tapauksessa += -operaattorin käyttö olisi suositeltavinta, sillä
2lisättävä luku voi olla positiivinen tai negatiivinen (tai nolla), joten
3+= -operaattori ei tässä rajoita sitä, millaisia lukuja a-muuttujaan
4voidaan lisätä.
timApp/static/data/ohjelmointi1/block_00535
(2 / 0)
  
17.9 Esimerkki: Painoindeksi
2---------------------------
timApp/static/data/ohjelmointi1/block_00536
(2 / 0)
  
1Tehdään ohjelma joka laskee painoindeksin. Painoindeksi lasketaan
2jakamalla paino (kg) pituuden (m) neliöllä, eli kaavalla
timApp/static/data/ohjelmointi1/block_00537
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2paino / (pituus * pituus)
3```
timApp/static/data/ohjelmointi1/block_00538
(1 / 0)
  
1C\#:lla painoindeksi saadaan siis laskettua seuraavasti.
timApp/static/data/ohjelmointi1/block_00539
(22 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2/// @author Antti-Jussi Lakanen
3/// @version 22.8.2012
4///
5/// <summary>
6/// Ohjelma, joka laskee painoindeksin
7/// pituuden (m) ja painon (kg) perusteella.
8/// </summary>
9public class Painoindeksi
10{
11 /// <summary>
12 /// Pääohjelma, jossa painoindeksi tulostetaan ruudulle.
13 /// </summary>
14 public static void Main()
15 {
16 double pituus = 1.83;
17 double paino = 75.0;
18 double painoindeksi = paino / (pituus*pituus);
19 System.Console.WriteLine(painoindeksi);
20 }
21}
22```
timApp/static/data/ohjelmointi1/block_00540
(3 / 0)
  
1\
2\
3 8. Oliotietotyypit ==================
timApp/static/data/ohjelmointi1/block_00541
(6 / 0)
  
1C\#:n alkeistietotyypit antavat melko rajoittuneet puitteet
2ohjelmointiin. Niillä pystytään tallentamaan ainoastaan lukuja ja
3yksittäisiä kirjaimia. Vähänkin monimutkaisemmissa ohjelmissa tarvitaan
4kehittyneempiä rakenteita tiedon tallennukseen. C\#:ssa, Javassa ja
5muissa oliokielissä tällaisen rakenteen tarjoavat oliot. C\#:ssa jo
6merkkijonokin (String) toteutetaan oliona.
timApp/static/data/ohjelmointi1/block_00542
(2 / 0)
  
18.1 Mitä oliot ovat?
2--------------------
timApp/static/data/ohjelmointi1/block_00543
(12 / 0)
  
1Olio (object) on ”tietorakenne”, jolla pyritään ohjelmoinnissa kuvaamaan
2reaalimaailman ilmiöitä. Luokkapohjaisissa kielissä (kuten C\#, Java ja
3C++) olion rakenteen ja käyttäytymisen määrittelee luokka, joka kuvaa
4olion attribuutit ja metodit. Attribuutit ovat olion ominaisuuksia ja
5metodit olion toimintoja. Olion sanotaan olevan luokan *ilmentymä*.
6Yhdestä luokasta voi siis luoda useita olioita, joilla on samat metodit
7ja attribuutit. Attribuutit voivat saada samasta luokasta luoduilla
8olioilla eri arvoja. Attribuuttien arvot muodostavat olion tilan. Huomaa
9kuitenkin, että vaikka oliolla olisi sama tila, sen *identiteetti* on
10eri. Esimerkiksi, kaksi täsmälleen samannäköistä palloa voi olla samassa
11paikassa (näyttää yhdeltä pallolta), mutta todellisuudessa ne ovat kaksi
12eri palloa.
timApp/static/data/ohjelmointi1/block_00544
(4 / 0)
  
1Olioita voi joko tehdä itse tai käyttää jostain kirjastosta löytyviä
2valmiita olioita. Omien olioluokkien tekeminen ei kuulu vielä
3Ohjelmointi 1 -kurssin asioihin, mutta käyttäminen kyllä. Tarkastellaan
4seuraavaksi luokan ja olion suhdetta, sekä kuinka oliota käytetään.
timApp/static/data/ohjelmointi1/block_00545
(15 / 0)
  
1Luokan ja olion suhdetta voisi kuvata seuraavalla esimerkillä. Olkoon
2luentosalissa useita ihmisiä. Kaikki luentosalissa olijat ovat ihmisiä.
3Heillä on tietyt samat ominaisuudet, jotka ovat kaikilla ihmisillä,
4kuten pää, kaksi silmää ja muitakin ruumiinosia. Kuitenkin jokainen
5salissa olija on erilainen ihmisen ilmentymä, eli jokaisella oliolla on
6oma identiteetti - eiväthän he ole yksi ja sama vaan heitä on useita.
7Eri ihmisillä voi olla erilainen tukka ja eriväriset silmät ja oma
8puhetyyli. Lisäksi ihmiset voivat olla eri pituisia, painoisia jne.
9Luentosalissa olevat identtiset kaksosetkin olisivat eri ilmentymiä
10ihmisestä. Jos Ihminen olisi luokka, niin kaikki luentosalissa olijat
11olisivat Ihminen-luokan ilmentymiä eli Ihminen-olioita. Tukka, silmät,
12pituus ja paino olisivat sitten olion ominaisuuksia eli attribuutteja.
13Ihmisellä voisi olla lisäksi joitain toimintoja eli metodeja kuten Syo,
14MeneToihin, Opiskele jne. Tarkastellaan seuraavaksi hieman todellisempaa
15esimerkkiä olioista.
timApp/static/data/ohjelmointi1/block_00546
(6 / 0)
  
1Oletetaan, että suunnittelisimme yritykselle palkanmaksujärjestelmää.
2Siihen tarvittaisiin muun muassa Tyontekija-luokka. Tyontekija-luokalla
3täytyisi olla ainakin seuraavat attribuutit: nimi, tehtava, osasto,
4palkka. Luokalla täytyisi olla myös ainakin seuraavat metodit:
5MaksaPalkka, MuutaTehtava, MuutaOsasto, MuutaPalkka. Jokainen työntekijä
6olisi nyt omanlaisensa Tyontekija-luokan ilmentymä eli olio.
timApp/static/data/ohjelmointi1/block_00547
(2 / 0)
  
18.2 Olion luominen
2------------------
timApp/static/data/ohjelmointi1/block_00548
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2Tyontekija teppo = new Tyontekija("Teppo Tunari", "Projektipäällikkö", "Tutkimusosasto", 5000);
3```
timApp/static/data/ohjelmointi1/block_00549
(5 / 0)
  
1Olioviite määritellään kirjoittamalla ensiksi sen luokan nimi, josta
2olio luodaan. Seuraavaksi kirjoitetaan nimi, jonka haluamme oliolle
3antaa. Nimen jälkeen tulee yhtäsuuruusmerkki, jonka jälkeen oliota
4luotaessa kirjoitetaan sana new ilmoittamaan, että luodaan uusi olio.
5Tämä new-operaattori varaa tilan tietokoneen muistista oliota varten.
timApp/static/data/ohjelmointi1/block_00550
(8 / 0)
  
1Seuraavaksi kirjoitetaan luokan nimi uudelleen, jonka perään
2kirjoitetaan sulkuihin mahdolliset olion luontiin liittyvät parametrit.
3Parametrit riippuvat siitä kuinka luokan *konstruktori* (constructor,
4muodostaja) on toteutettu. Konstruktori on metodi, joka suoritetaan aina
5kun uusi olio luodaan. Valmiita luokkia käyttääkseen ei tarvitse
6kuitenkaan tietää konstruktorin toteutuksesta, vaan tarvittavat
7parametrit selviävät aina luokan dokumentaatiosta. Yleisessä muodossa
8uusi olio luodaan alla olevalla tavalla.
timApp/static/data/ohjelmointi1/block_00551
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2Luokka olionNimi = new Luokka(parametri1, parametri2,..., parametriN);
3```
timApp/static/data/ohjelmointi1/block_00552
(2 / 0)
  
1Jos olio ei vaadi luomisen yhteydessä parametreja, kirjoitetaan silloin
2tyhjä sulkupari.
timApp/static/data/ohjelmointi1/block_00553
(6 / 0)
  
1Ennen kuin oliolle on varattu tila tietokoneen muistista
2new-operaattorilla, ei sitä voi käyttää. Ennen new-operaattorin käyttöä
3olion arvo on null, joka tarkoittaa, että olio on käyttökelvoton,
4”mitätön”. Tällaisen olion käyttö aiheuttaa virheilmoituksen. Olio
5voidaan myös tarkoituksellisesti merkitä käyttökelvottomaksi asettamalla
6olionNimi = null.
timApp/static/data/ohjelmointi1/block_00554
(4 / 0)
  
1Uusi Tyontekija-olio voitaisiin luoda esimerkiksi seuraavasti.
2Parametrit riippuisivat nyt siitä kuinka olemme toteuttaneet
3Tyontekija-luokan konstruktorin. Tässä tapauksessa annamme nyt
4parametrina oliolle kaikki attribuutit.
timApp/static/data/ohjelmointi1/block_00555
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2Tyontekija akuAnkka = new Tyontekija("Aku Ankka", "Johtaja", "Osasto3", 3000);
3```
timApp/static/data/ohjelmointi1/block_00556
(2 / 0)
  
1Monisteen alussa loimme lumiukkoja piirrettäessä PhysicsObject-luokan
2olion seuraavasti.
timApp/static/data/ohjelmointi1/block_00557
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2PhysicsObject p1 = new PhysicsObject(2 * 100.0, 2 * 100.0, Shape.Circle);
3```
timApp/static/data/ohjelmointi1/block_00558
(3 / 0)
  
1Itse asiassa oliomuuttuja on C\#:ssa ainoastaan *viite* varsinaiseen
2olioon. Siksi niitä kutsutaankin usein myös *viitemuuttujiksi.*
3Viitemuuttujat eroavat oleellisesti alkeistietotyyppisistä muuttujista.
timApp/static/data/ohjelmointi1/block_00559
(2 / 0)
  
18.3 Oliotietotyyppien ja alkeistietotyyppien ero
2------------------------------------------------
timApp/static/data/ohjelmointi1/block_00560
(5 / 0)
  
1C\#:ssa on kahden mallisia rakenteita, joihin tietoja voidaan tallentaa.
2Tapauksesta riippuen tiedot tallennetaan joko *alkeistietotyyppeihin*
3tai *oliotietotyyppeihin*. Oliotietotyypit eroavat alkeistietotyypeistä
4siinä, että ne ovat *viitteitä* tiettyyn olioon, ja siksi niitä
5kutsutaan myös nimellä viitetyypit tai viitemuuttujat.
timApp/static/data/ohjelmointi1/block_00561
(6 / 0)
  
1- Alkeistietotyypit säilyttävät sisältämänsä tiedon yhdessä paikassa
2 tietokoneen muistissa (nimeltään *pino*).
3
4- Viitetyypit sisältävät viitteen johonkin toiseen paikkaan muistissa
5 (kutsutaan nimellä *keko*), missä varsinainen data sijaitsee.
6 Viittaus olioon sijaitsee kuitenkin pinossa.
timApp/static/data/ohjelmointi1/block_00562
(7 / 0)
  
1Yleensä meidän ei tarvitse olla kovin huolissamme siitä käytämmekö
2alkeistietotyyppiä (kuten int, double tai char) vai oliotyyppiä (kuten
3String). Yleisesti ottaen tärkein ero on siinä, että alkeistietotyyppien
4tulee (tiettyjä poikkeuksia lukuun ottamatta) aina sisältää jokin arvo,
5mutta oliotietotyypit voivat olla null-arvoisia (eli ”ei-minkään”
6arvoisia). Jäljempänä esimerkkejä alkeistietotyyppien ja viitetyyppien
7eroista.
timApp/static/data/ohjelmointi1/block_00563
(2 / 0)
  
1Samaan olioon voi viitata useampi muuttuja. Vertaa alla olevia
2koodinpätkiä.
timApp/static/data/ohjelmointi1/block_00564
(6 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2int luku1 = 10;
3int luku2 = luku1;
4luku1 = 0;
5Console.WriteLine(luku2); //tulostaa 10
6```
timApp/static/data/ohjelmointi1/block_00565
(6 / 0)
  
1Yllä oleva tulostaa ”10” niin kuin pitääkin. Muuttujan luku2 arvo ei
2siis muutu, vaikka asetamme kolmannella rivillä muuttujaan luku1 arvon
30. Tämä johtuu siitä, että toisella rivillä asetamme muuttujaan luku2
4muuttujan luku1 arvon, emmekä viitettä muuttujaan luku1.
5Oliotietotyyppisten muuttujien kanssa asia on toinen. Vertaa yllä olevaa
6esimerkkiä seuraavaan:
timApp/static/data/ohjelmointi1/block_00566
(8 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2PhysicsObject p1 = new PhysicsObject(2*100.0, 2*100.0, Shape.Circle);
3Add(p1);
4p1.X = -50;
5
6PhysicsObject p2 = p1;
7p2.X = 100;
8```
timApp/static/data/ohjelmointi1/block_00567
(1 / 0)
  
1Yllä oleva koodi piirtää seuraavan kuvan:
timApp/static/data/ohjelmointi1/block_00568
(4 / 0)
  
1![\
2 Kuva 8: Molemmat muuttujat, p1 ja p2, liikuttelevat samaa ympyrää.
3Lopputuloksena ympyrä seisoo pisteessä
4x=100.](../src/luentomonistecsUusin_htm_m3838408a.png)
timApp/static/data/ohjelmointi1/block_00569
(6 / 0)
  
1\
2 Nopeasti voisi olettaa, että ikkunassamme näkyisi nyt vain kaksi
3samanlaista ympyrää eri paikoissa. Näin ei kuitenkaan ole, vaan molemmat
4PhysicsObject-oliot viittaavat samaan ympyrään, jonka säde on 50. Tämä
5johtuu siitä, että muuttujat p1 ja p2 ovat olioviitteitä, jotka
6viittaavat (ts. osoittavat) samaan olioon.
timApp/static/data/ohjelmointi1/block_00570
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2PhysicsObject p2 = p1;
3```
timApp/static/data/ohjelmointi1/block_00571
(2 / 0)
  
1Toisin sanoen yllä olevalla rivillä ei luoda uutta PhysicsObject-oliota,
2vaan ainoastaan uusi olioviite, joka viittaa nyt samaan olioon kuin p1.
timApp/static/data/ohjelmointi1/block_00572
(3 / 0)
  
1![\
2 Kuva 9: Sekä p1 että p2 viittaavat samaan
3olioon.](../src/luentomonistecsUusin_htm_75ff594f.png)
timApp/static/data/ohjelmointi1/block_00573
(4 / 0)
  
1\
2\
3 *Oliomuuttuja =* Viite todelliseen olioon. Samaan olioon voi olla
4useitakin viitteitä.
timApp/static/data/ohjelmointi1/block_00574
(1 / 0)
  
1Viitteitä käsitellään tarkemmin luvussa 14.
timApp/static/data/ohjelmointi1/block_00575
(2 / 0)
  
18.4 Metodin kutsuminen
2----------------------
timApp/static/data/ohjelmointi1/block_00576
(4 / 0)
  
1Jokaisella tietystä luokasta luodulla oliolla on käytössä kaikki tämän
2luokan julkiset metodit. Metodikutsussa käsketään oliota tekemään
3jotain. Voisimme esimerkiksi käskeä PhysicsObject-oliota liikkumaan, tai
4Tyontekija-oliota muuttamaan palkkaansa.
timApp/static/data/ohjelmointi1/block_00577
(5 / 0)
  
1Olion metodeita kutsutaan kirjoittamalla ensiksi olion nimi, piste ja
2kutsuttavan metodin nimi. Metodin mahdolliset parametrit laitetaan
3sulkeiden sisään ja erotetaan toisistaan pilkulla. Jos metodi ei vaadi
4parametreja, täytyy sulut silti kirjoittaa, niiden sisälle ei vaan tule
5mitään. Yleisessä muodossa metodikutsu on seuraava:
timApp/static/data/ohjelmointi1/block_00578
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2olionNimi.MetodinNimi(parametri1,parametri2,...parametriN);
3```
timApp/static/data/ohjelmointi1/block_00579
(2 / 0)
  
1Voisimme nyt esimerkiksi muuttaa akuAnkka-olion palkkaa alla olevalla
2tavalla.
timApp/static/data/ohjelmointi1/block_00580
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2akuAnkka.MuutaPalkka(3500);
3```
timApp/static/data/ohjelmointi1/block_00581
(2 / 0)
  
1Tai laittaa p1-olion (oletetaan että p1 on PhysicsObject-olio)
2liikkeelle käyttäen Hit-metodia.
timApp/static/data/ohjelmointi1/block_00582
(3 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2p1.Hit(new Vector(1000.0, 500.0));
3```
timApp/static/data/ohjelmointi1/block_00583
(5 / 0)
  
1String-luokasta löytyy esimerkiksi Contains-metodi, joka palauttaa arvon
2True tai False. Parametrina Contains-metodille annetaan merkkijono, ja
3metodi etsii oliosta antamaamme merkkijonoa vastaavia ilmentymiä. Jos
4olio sisältää merkkijonon (yhden tai useamman kerran) palautetaan True.
5Muutoin palautetaan False. Alla esimerkki.
timApp/static/data/ohjelmointi1/block_00584
(4 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2String lause = "Pekka meni kauppaan";
3Console.WriteLine(lause.Contains("eni")); // Tulostaa True
4```
timApp/static/data/ohjelmointi1/block_00585
(2 / 0)
  
18.5 Metodin ja aliohjelman ero
2------------------------------
timApp/static/data/ohjelmointi1/block_00586
(3 / 0)
  
1Aliohjelma esitellään static-tyyppiseksi, mikäli aliohjelma ei käytä
2mitään muita tietoja kuin parametreinä tuodut tiedot. Esimerkiksi
3luvussa 20.4.2 on seuraava aliohjelma.
timApp/static/data/ohjelmointi1/block_00587
(9 / 0)
  
1``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2private void KuunteleLiiketta(AnalogState hiirenTila)
3{
4 pallo.X = Mouse.PositionOnWorld.X;
5 pallo.Y = Mouse.PositionOnWorld.Y;
6
7 Vector hiirenLiike = hiirenTila.MouseMovement;
8}
9```
timApp/static/data/ohjelmointi1/block_00588
(5 / 0)
  
1Tässä tarvitaan hiiren tilan lisäksi pelioliossa esitellyn pallon
2tietoja, joten enää ei ole kyse stattisesta aliohjelmasta ja siksi
3static-sana jätetään pois. Metodi sen sijaan pystyy käyttämään *olion*
4omia "ominaisuuksia", attribuutteja, metodeja ja ns. ominaisuus-kenttiä
5(property fields).
timApp/static/data/ohjelmointi1/block_00589
(2 / 0)
  
18.6 Olion tuhoaminen ja roskienkeruu
2------------------------------------
timApp/static/data/ohjelmointi1/block_00590
(7 / 0)
  
1Kun olioon ei enää viittaa yhtään muuttujaa (olioviitettä), täytyy olion
2käyttämät muistipaikat vapauttaa muuhun käyttöön. Oliot poistetaan
3muistista puhdistusoperaation avulla. Tästä huolehtii C\#:n
4automaattinen roskienkeruu (garbage collection). Kun olioon ei ole enää
5viitteitä, se merkitään poistettavaksi ja aina tietyin väliajoin
6*puhdistusoperaatio* (kutsutaan usein myös nimellä roskienkerääjä,
7garbage collector) vapauttaa merkittyjen olioiden muistipaikat.
timApp/static/data/ohjelmointi1/block_00591
(10 / 0)
  
1Kaikissa ohjelmointikielissä näin ei ole (esim. alkuperäinen C++), vaan
2muistin vapauttamisesta ja olioiden tuhoamisesta tulee useimmiten
3huolehtia itse. Näissä kielissä on yleensä destruktori (destructor =
4hajottaja), joka suoritetaan aina kun olio tuhotaan. Itse
5kirjoitettavasta destruktorista on tapana kutsua olion elinaikanaan
6luomien olioiden tuhoamista tai muiden resurssien vapauttamista. Vertaa
7konstruktoriin, joka suoritettiin kun olio luodaan. Haastavaksi näiden
8kielien yhteydessä tuleekin se, että joissakin tapauksissa olioiden
9elinkaari on automaattista ja joissakin ei. Siksi muistivuodot ovat
10erittäin yleisiä aloittelevilla C++ -ohjelmoijilla.
timApp/static/data/ohjelmointi1/block_00592
(11 / 0)
  
1Yleensä C\#-ohjelmoijan ei tarvitse huolehtia muistin vapauttamisesta,
2mutta on tiettyjä tilanteita, joissa voidaan itse joutua poistamaan
3oliot. Yksi esimerkki tällaisesta tilanteesta on tiedostojen käsittely:
4Jos olio on avannut tiedoston, olisi viimeistään ennen olion tuhoamista
5järkevää sulkea tiedosto. Tällöin samassa yhteydessä olion tuhottavaksi
6merkitsemisen kanssa suoritettaisiin myös tiedoston sulkeminen. Tämä
7tehdään esittelemällä *hajotin* (destructor), joka on luokan metodi ja
8jonka tehtävänä on tyhjentää olio kaikesta sen sisältämästä tiedosta
9sekä vapauttaa sen sisältämät rakenteet, kuten kytkökset avoinna oleviin
10resursseihin (esim tiedostoon, tosin yleensä tiedostoa ei ole hyvä pitää
11avoinna niin kauan aikaa kuin jonkin olion elinkaari voi olla).
timApp/static/data/ohjelmointi1/block_00593
(2 / 0)
  
18.7 Olioluokkien dokumentaatio
2------------------------------
timApp/static/data/ohjelmointi1/block_00594
(9 / 0)
  
1Luokan dokumentaatio sisältää tiedot luokasta, luokan konstruktoreista
2ja metodeista. Luokkien dokumentaatioissa on yleensä linkkejä
3esimerkkeihin, kuten myös String-luokan tapauksessa. Tutustutaan nyt
4tarkemmin String-luokan dokumentaatioon. String-luokan dokumentaatio
5löytyy sivulta
6<http://msdn.microsoft.com/en-us/library/system.string.aspx>, ja lista
7*jäsenistä* eli käytössä olevista konstruktoreista, attribuuteista
8(fields), ominaisuuksista (property) ja metodeista sivulta
9<http://msdn.microsoft.com/en-us/library/system.string_