Commit b1f8ac89920cba206f4b4ef619756ad9f81029ab

  • avatar
  • Samuel Uusi-Mäkelä <kaiutindev @gm…l.com> (Committer)
  • Tue Jun 03 13:48:30 EEST 2014
  • avatar
  • Samuel Uusi-Mäkelä <kaiutindev @gm…l.com> (Author)
  • Tue Jun 03 13:48:30 EEST 2014
Markdownfilu oikeaan paikkaan
timApp/lecture.markdown
(7004 / 4573)
  
1<h1><script> alert("borz");</script>Esipuhe</h1>
2<p>Tämä moniste on luentomoniste kurssille Ohjelmointi 1. Luentomoniste
1Esipuhe
2=======
3
4Tämä moniste on luentomoniste kurssille Ohjelmointi 1. Luentomoniste
35tarkoittaa sitä, että sen ei ole tarkoitus korvata kunnon kirjaa, vaan
46esittää asiat samassa järjestyksessä ja samassa valossa kuin ne
57esitetään luennolla. Jotta moniste ei paisuisi kohtuuttomasti, ei
1313aloittelijoille tarkoitetut. Osin tämä on luonnollista, koska ihmisetkin
1414tarvitsevat jonkin yhteisen kielen kommunikoidakseen toisen kanssa.
1515Siksi ohjelmoinnin aloittaminen ilman, että ensin opetellaan jonkun
16kielen perusteet, on aika haastavaa.</p>
17<p>Jäsentämisen selkeyden takia kirjoissa käsitellään yleensä yksi aihe
16kielen perusteet, on aika haastavaa.
17
18Jäsentämisen selkeyden takia kirjoissa käsitellään yleensä yksi aihe
1819perusteellisesti alusta loppuun. Aloittaessaan puhumaan lapsi ei
1920kuitenkaan ole kykeneväinen omaksumaan kaikkea tietyn lauserakenteen
2021kieliopista. Vastaavasti ohjelmoinnin alkeita kahlattaessa
2424asioista annetaan ensin esimerkkejä tai johdatellaan niiden tarpeeseen,
2525ja sitten jonkin verran selitetään mistä oli kyse. Tästä syystä tästä
2626monisteesta saa yhden näkemyksen mukaisen pintaraapaisun asioille ja
27kirjoista ja nettilähteistä asiaa on syvennettävä.</p>
28<p>Tässä monisteessa käytetään esimerkkikielenä <em>C#</em>-kieltä. Kuitenkin
27kirjoista ja nettilähteistä asiaa on syvennettävä.
28
29Tässä monisteessa käytetään esimerkkikielenä *C\#*-kieltä. Kuitenkin
2930nimenomaan esimerkkinä, koska monisteen rakenne ja esimerkit voisivat
3031olla aivan samanlaisia mille tahansa muullekin ohjelmointikielelle.
3132Tärkeintä on nimenomaan ohjelmoinnin ajattelutavan oppiminen. Kielen
3838kirjoittaminen on hieman haastavampaa, mutta samat rakenteet sielläkin
3939toistuvat. Ohjelmointikielet tulevat ja menevät. Tätäkin vastaavaa
4040kurssia on pidetty Jyväskylän yliopistossa seuraavilla kielillä:
41Fortran, Pascal, C, C++, Java ja nyt C#. Joissakin yliopistoissa
42aloituskielenä on Python.</p>
43<p>Ohjelmointia on täysin mahdotonta oppia pelkästään kirjoja lukemalla.
41Fortran, Pascal, C, C++, Java ja nyt C\#. Joissakin yliopistoissa
42aloituskielenä on Python.
43
44Ohjelmointia on täysin mahdotonta oppia pelkästään kirjoja lukemalla.
4445Siksi kurssi sisältää luentojen ohella myös viikoittaisten
4546harjoitustehtävien (demojen) tekemistä, ohjattua pääteharjoittelua
4647tietokoneluokassa sekä harjoitustyön tekemisen. Näistä lisätietoa,
4748samoin kuin kurssilla käytettävien työkalujen hankkimisesta ja
48asentamisesta löytyy kurssin kotisivuilta:</p>
49<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
50https://trac.cc.jyu.fi/projects/ohj1</code></p>
51<p>Tämä moniste perustuu Martti Hyvösen ja Vesa Lappalaisen syksyllä 2009
52kirjoittamaan <em>Ohjelmointi 1</em> -monisteeseen, joka osaltaan sai muotonsa
49asentamisesta löytyy kurssin kotisivuilta:
50
51``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
52https://trac.cc.jyu.fi/projects/ohj1
53```
54
55Tämä moniste perustuu Martti Hyvösen ja Vesa Lappalaisen syksyllä 2009
56kirjoittamaan *Ohjelmointi 1* -monisteeseen, joka osaltaan sai muotonsa
5357monen eri kirjoittajan työn tuloksena aina 80-luvulta alkaen. Suurimman
54panoksen monisteeseen ovat antaneet Timo Männikkö ja Vesa Lappalainen.</p>
55<p>Jyväskylässä 2.1.2013</p>
56<p>Martti Hyvönen, Vesa Lappalainen, Antti-Jussi Lakanen</p>
57<h1>1. Mitä ohjelmointi on?</h1>
58<p>Ohjelmointi on yksinkertaisimmillaan toimintaohjeiden antamista ennalta
58panoksen monisteeseen ovat antaneet Timo Männikkö ja Vesa Lappalainen.
59
60Jyväskylässä 2.1.2013
61
62Martti Hyvönen, Vesa Lappalainen, Antti-Jussi Lakanen
63
641. Mitä ohjelmointi on?
65=======================
66
67Ohjelmointi on yksinkertaisimmillaan toimintaohjeiden antamista ennalta
5968määrätyn toimenpiteen suorittamista varten. Ohjelmoinnin kaltaista
6069toimintaa esiintyy jokaisen ihmisen arkielämässä lähes päivittäin.
6170Algoritmista esimerkkinä voisi olla se, että annamme jollekulle
7373komentoja, jotka ohjaavat toimenpiteen suoritusta. Alkeellista
7474ohjelmointia on tavallaan myös mikroaaltouunin käyttäminen, sillä
7575tällöin uunille annetaan ohjeet siitä, kuinka kauan ja kuinka suurella
76teholla sen tulee toimia.</p>
77<p>Kaikissa edellisissä esimerkeissä oli siis kyse yksikäsitteisten
76teholla sen tulee toimia.
77
78Kaikissa edellisissä esimerkeissä oli siis kyse yksikäsitteisten
7879ohjeiden antamisesta. Kuitenkin esimerkit käsittelivät hyvinkin
7980erilaisia viestintätilanteita. Ihmisten välinen kommunikaatio,
8081mikroaaltouunin kytkimien kiertäminen tai nappien painaminen, samoin
8585ratkaisuun käytettävissä olevista välineistä. Ihmisten välinen
8686kommunikaatio voi tapahtua puhumalla, kirjoittamalla tai näiden
8787yhdistelmänä. Samoin ohjelmoinnissa voidaan usein valita erilaisia
88toteutustapoja tehtävän luonteesta riippuen.</p>
89<p>Ohjelmoinnissa on olemassa eri tasoja riippuen siitä, minkälaista
88toteutustapoja tehtävän luonteesta riippuen.
89
90Ohjelmoinnissa on olemassa eri tasoja riippuen siitä, minkälaista
9091työvälinettä tehtävän ratkaisuun käytetään. Pitkälle kehitetyt korkean
9192tason työvälineet mahdollistavat työskentelyn käsitteillä ja
9293ilmaisuilla, jotka parhaimmillaan muistuttavat luonnollisen kielen
9394käyttämiä käsitteitä ja ilmaisuja, kun taas matalan tason työvälineillä
9495työskennellään hyvin yksinkertaisilla ja alkeellisilla käsitteillä ja
95ilmaisuilla.</p>
96<p>Eräänä esimerkkinä ohjelmoinnista voidaan pitää sokerikakun
97valmistukseen kirjoitettua ohjetta:</p>
98<p>``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
99Sokerikakku</p>
100<p>6 munaa
96ilmaisuilla.
97
98Eräänä esimerkkinä ohjelmoinnista voidaan pitää sokerikakun
99valmistukseen kirjoitettua ohjetta:
100
101``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
102Sokerikakku
103
1046 munaa
1011051,5 dl sokeria
1021061,5 dl jauhoja
1031,5 tl leivinjauhetta</p>
104<ol>
105<li>Vatkaa sokeri ja munat vaahdoksi.</li>
106<li>Sekoita jauhot ja leivinjauhe.</li>
107<li>Sekoita muna-sokerivaahto ja jauhoseos.</li>
108<li>Paista 45 min 175°C lämpötilassa.
109```</li>
110</ol>
111<p>Valmistusohje on ilmiselvästi kirjoitettu ihmistä varten, vieläpä
1071,5 tl leivinjauhetta
108
1091. Vatkaa sokeri ja munat vaahdoksi.
1102. Sekoita jauhot ja leivinjauhe.
1113. Sekoita muna-sokerivaahto ja jauhoseos.
1124. Paista 45 min 175°C lämpötilassa.
113```
114
115Valmistusohje on ilmiselvästi kirjoitettu ihmistä varten, vieläpä
112116sellaista ihmistä, joka tietää leipomisesta melko paljon. Jos sama ohje
113117kirjoitettaisiin ihmiselle, joka ei eläessään ole leiponut mitään, ei
114118edellä esitetty ohje olisi alkuunkaan riittävä, vaan siinä täytyisi
115119huomioida useita leipomiseen liittyviä niksejä: uunin ennakkoon
116lämmittäminen, vaahdon vatkauksen salat, yms.</p>
117<p>Koneelle kirjoitettavat ohjeet poikkeavat merkittävästi ihmisille
120lämmittäminen, vaahdon vatkauksen salat, yms.
121
122Koneelle kirjoitettavat ohjeet poikkeavat merkittävästi ihmisille
118123kirjoitetuista ohjeista. Kone ei osaa automaattisesti kysyä neuvoa
119124törmätessään uuteen ja ennalta arvaamattomaan tilanteeseen. Se toimii
120125täsmälleen niiden ohjeiden mukaan, jotka sille on annettu, olivatpa ne
128128luovuuteen. Näin ollen tämän päivän ohjelmointikielillä koneelle
129129tarkoitetut ohjeet on esitettävä hyvin tarkoin määritellyssä muodossa ja
130130niissä on pyrittävä ottamaan huomioon kaikki mahdollisesti esille
131tulevat tilanteet. [MÄN]</p>
132<h1>2. Ensimmäinen C#-ohjelma</h1>
133<h2>2.1 Ohjelman kirjoittaminen</h2>
134<p>C#-ohjelmia (lausutaan <em>c sharp</em>) voi kirjoittaa millä tahansa
131tulevat tilanteet. [MÄN]
132
1332. Ensimmäinen C\#-ohjelma
134==========================
135
1362.1 Ohjelman kirjoittaminen
137---------------------------
138
139C\#-ohjelmia (lausutaan *c sharp*) voi kirjoittaa millä tahansa
135140tekstieditorilla. Tekstieditoreja on kymmeniä, ellei satoja, joten yhden
136141nimeäminen on vaikeaa. Osa on kuitenkin suunniteltu varta vasten
137142ohjelmointia ajatellen. Tällaiset tekstieditorit osaavat muotoilla
138143ohjelmoijan kirjoittamaa lähdekoodia (tai lyhyesti koodia)
139144automaattisesti siten, että lukeminen on helpompaa ja siten ymmärtäminen
140ja muokkaaminen nopeampaa. Ohjelmoijien suosimia ovat mm. <em>Vim,</em> <em>Emacs,
141ConTEXT</em> <em>ja</em> <em>NotePad++</em>, mutta monet muutkin ovat varmasti hyviä.
145ja muokkaaminen nopeampaa. Ohjelmoijien suosimia ovat mm. *Vim,* *Emacs,
146ConTEXT* *ja* *NotePad++*, mutta monet muutkin ovat varmasti hyviä.
142147Monisteen alun esimerkkien kirjoittamiseen soveltuu hyvin mikä tahansa
143tekstieditori.</p>
144<p><em>Koodi, lähdekoodi =</em> Ohjelmoijan tuottama tiedosto, josta varsinainen
145ohjelma muutetaan tietokoneen ymmärtämäksi konekieleksi.</p>
146<p>Kirjoitetaan tekstieditorilla alla olevan mukainen C#-ohjelma ja
148tekstieditori.
149
150*Koodi, lähdekoodi =* Ohjelmoijan tuottama tiedosto, josta varsinainen
151ohjelma muutetaan tietokoneen ymmärtämäksi konekieleksi.
152
153Kirjoitetaan tekstieditorilla alla olevan mukainen C\#-ohjelma ja
147154tallennetaan se vaikka nimellä HelloWorld.cs. Tiedoston tarkenteeksi
148155(eli niin sanottu tiedostopääte) on sovittu juuri tuo .cs, mikä tulee
149156käytetyn ohjelmointikielen nimestä, joten tälläkin kurssilla käytämme
150157sitä. Kannattaa olla tarkkana tiedostoa tallennettaessa, sillä jotkut
151158tekstieditorit yrittävät oletuksena tallentaa kaikki tiedostot
152159tarkenteella .txt ja tällöin tiedoston nimi voi helposti tulla muotoon
153HelloWorld.cs.txt.</p>
154<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
160HelloWorld.cs.txt.
161
162``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
155163public class HelloWorld
156164{
157165 public static void Main()
158166 {
159167 System.Console.WriteLine("Hello World!");
160168 }
161}</code></p>
162<p>Tämän ohjelman pitäisi tulostaa näytölle teksti</p>
163<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
164Hello World!</code></p>
165<p>Voidaksemme kokeilla ohjelmaa käytännössä, täytyy se ensiksi kääntää
166tietokoneen ymmärtämään muotoon.</p>
167<p><em>Kääntäminen =</em> Kirjoitetun lähdekoodin muuntamista suoritettavaksi
168ohjelmaksi.</p>
169<p>Esimerkkejä muilla ohjelmointikielillä kirjoitetusta HelloWorld
170-ohjelmasta löydät vaikkapa:</p>
171<p><a href="http://www2.latech.edu/~acm/HelloWorld.html">http://www2.latech.edu/\~acm/HelloWorld.html</a>.</p>
172<h2>2.2 Ohjelman kääntäminen ja ajaminen</h2>
173<p>Jotta ohjelman kääntäminen ja suorittaminen onnistuu, täytyy koneelle
174olla asennettuna joku C#-sovelluskehitin. Mikäli käytät Windowsia, niin
169}
170```
171
172Tämän ohjelman pitäisi tulostaa näytölle teksti
173
174``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
175Hello World!
176```
177
178Voidaksemme kokeilla ohjelmaa käytännössä, täytyy se ensiksi kääntää
179tietokoneen ymmärtämään muotoon.
180
181*Kääntäminen =* Kirjoitetun lähdekoodin muuntamista suoritettavaksi
182ohjelmaksi.
183
184Esimerkkejä muilla ohjelmointikielillä kirjoitetusta HelloWorld
185-ohjelmasta löydät vaikkapa:
186
187[http://www2.latech.edu/\~acm/HelloWorld.html](http://www2.latech.edu/~acm/HelloWorld.html).
188
1892.2 Ohjelman kääntäminen ja ajaminen
190------------------------------------
191
192Jotta ohjelman kääntäminen ja suorittaminen onnistuu, täytyy koneelle
193olla asennettuna joku C\#-sovelluskehitin. Mikäli käytät Windowsia, niin
175194aluksi riittää hyvin Microsoft .NET SDK (Software Development Kit, suom.
176195kehitystyökalut). Muiden käyttöjärjestelmien tapauksessa
177sovelluskehittimeksi käy esimerkiksi <em>Novell Mono</em>. Hyvin monet tämän
196sovelluskehittimeksi käy esimerkiksi *Novell Mono*. Hyvin monet tämän
178197kurssin harjoituksista on tehtävissä Mono-sovelluskehittimellä, mutta
179198tämän monisteen ohjeet ja esimerkit tullaan käsittelemään
180199Windows-ympäristössä. Edelleen, Jypeli-kirjaston käyttäminen on
181mahdollista vain Windows-ympäristössä.</p>
182<p>Lisätietoa .NET-kehitystyökaluista ja asentamisesta löytyy kurssin
200mahdollista vain Windows-ympäristössä.
201
202Lisätietoa .NET-kehitystyökaluista ja asentamisesta löytyy kurssin
183203kotisivuilta:
184<a href="https://trac.cc.jyu.fi/projects/ohj1/wiki/dotnet-tyokalut">https://trac.cc.jyu.fi/projects/ohj1/wiki/dotnet-tyokalut</a>.
204[https://trac.cc.jyu.fi/projects/ohj1/wiki/dotnet-tyokalut](https://trac.cc.jyu.fi/projects/ohj1/wiki/dotnet-tyokalut).
185205Kun sovelluskehitin on asennettu, käynnistetään komentorivi (Command
186206Prompt, lyhyemmin cmd) ja siirrytään siihen hakemistoon, johon
187207HelloWorld.cs tiedosto on tallennettu. Ohjelma käännetään nyt
188komennolla:</p>
189<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
190csc HelloWorld.cs</code></p>
191<p>Komento ”csc” tulee sanoista <em>C Sharp Compiler</em> (compiler = kääntäjä).
208komennolla:
209
210``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
211csc HelloWorld.cs
212```
213
214Komento ”csc” tulee sanoista *C Sharp Compiler* (compiler = kääntäjä).
192215Kääntämisen jälkeen hakemistoon ilmestyy HelloWorld.exe-niminen
193216tiedosto, joka voidaan ajaa kuten minkä tahansa ohjelman syöttämällä
194ohjelman nimi:</p>
195<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
196HelloWorld</code></p>
197<p>Ohjelman tulisi nyt tulostaa näyttöön teksti Hello World!, kuten alla
198olevassa kuvassa.</p>
199<p><img alt="\
217ohjelman nimi:
218
219``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
220HelloWorld
221```
222
223Ohjelman tulisi nyt tulostaa näyttöön teksti Hello World!, kuten alla
224olevassa kuvassa.
225
226![\
200227 Kuva 1: Ohjelman kääntäminen ja ajaminen Windowsin
201komentorivillä." src="../src/luentomonistecsUusin_htm_m16b63f32.png" /></p>
202<p>\
228komentorivillä.](../src/luentomonistecsUusin_htm_m16b63f32.png)
229
230\
203231 Huomaa, että käännettäessä kirjoitetaan koko tiedoston nimi
204.cs-tarkentimen kanssa.</p>
205<p>Jos saat virheilmoituksen</p>
206<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
207'csc' is not recognized as an internal or external command, operable program or batch file.</code></p>
208<p>niin kääntäjäohjelmaa csc.exe ei silloin löydy niin sanotusta
209<em>hakupolusta</em>. Ohjelman lisääminen hakupolkuun onnistuu komennolla:</p>
210<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
211set PATH=%WINDIR%\Microsoft.NET\Framework\v4.0.30319;%path%</code></p>
212<p>Jotta kääntäjää ei tarvitsisi joka kerta lisätä hakupolkuun, voi sen
232.cs-tarkentimen kanssa.
233
234Jos saat virheilmoituksen
235
236``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
237'csc' is not recognized as an internal or external command, operable program or batch file.
238```
239
240niin kääntäjäohjelmaa csc.exe ei silloin löydy niin sanotusta
241*hakupolusta*. Ohjelman lisääminen hakupolkuun onnistuu komennolla:
242
243``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
244set PATH=%WINDIR%\Microsoft.NET\Framework\v4.0.30319;%path%
245```
246
247Jotta kääntäjää ei tarvitsisi joka kerta lisätä hakupolkuun, voi sen
213248lisätä siihen pysyvästi. Esimerkiksi Windows 7:ssä tämä tapahtuu
214seuraavasti.</p>
215<p>Klikkaa Oma tietokone -kuvaketta hiiren oikealla painikkeella ja valitse
216<strong>Ominaisuudet</strong> (Properties). Valitse sitten vasemmalta Advanced system
249seuraavasti.
250
251Klikkaa Oma tietokone -kuvaketta hiiren oikealla painikkeella ja valitse
252**Ominaisuudet** (Properties). Valitse sitten vasemmalta Advanced system
217253settings ja Advanced-välilehdeltä Environment variables. Ylemmästä
218laatikosta valitse muuttuja PATH ja paina <strong>Muokkaa</strong>. Siirry rivin
219Variable value loppuun, kirjoita puolipiste (;) ja heti perään polku</p>
220<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
221%WINDIR%\Microsoft.NET\Framework\v4.0.30319</code></p>
222<p>XP:ssä vastaavasti Oma tietokone → Ominaisuudet → Lisäasetukset →
223Ympäristömuuttujat.</p>
224<h2>2.3 Ohjelman rakenne</h2>
225<p>Ensimmäinen kirjoittamamme ohjelma HelloWorld.cs on oikeastaan
226yksinkertaisin mahdollinen C#-ohjelma. Alla yksinkertaisimman ohjelman
227kaksi ensimmäistä riviä.</p>
228<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
254laatikosta valitse muuttuja PATH ja paina **Muokkaa**. Siirry rivin
255Variable value loppuun, kirjoita puolipiste (;) ja heti perään polku
256
257``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
258%WINDIR%\Microsoft.NET\Framework\v4.0.30319
259```
260
261XP:ssä vastaavasti Oma tietokone → Ominaisuudet → Lisäasetukset →
262Ympäristömuuttujat.
263
2642.3 Ohjelman rakenne
265--------------------
266
267Ensimmäinen kirjoittamamme ohjelma HelloWorld.cs on oikeastaan
268yksinkertaisin mahdollinen C\#-ohjelma. Alla yksinkertaisimman ohjelman
269kaksi ensimmäistä riviä.
270
271``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
229272public class HelloWorld
230{</code></p>
231<p>Ensimmäisellä rivillä määritellään <em>luokka</em> (class) jonka nimi on
273{
274```
275
276Ensimmäisellä rivillä määritellään *luokka* (class) jonka nimi on
232277HelloWorld. Tässä vaiheessa riittää ajatella luokkaa ”kotina”
233<em>aliohjelmille</em>. Aliohjelmista puhutaan lisää hieman myöhemmin.
278*aliohjelmille*. Aliohjelmista puhutaan lisää hieman myöhemmin.
234279Toisaalta luokkaa voidaan verrata ”piparkakkumuottiin”-se on
235280rakennusohje olioiden (eli ”piparkakkujen”) luomista varten. Ohjelman
236281ajamisen aikana olioita syntyy luokkaan kirjoitetun koodin avulla.
237282Olioita voidaan myös tuhota. Yhdellä luokalla voidaan siis tehdä monta
238283samanlaista oliota, aivan kuten yhdellä piparkakkumuotilla voidaan tehdä
239monta samanlaista (samannäköistä) piparia.</p>
240<p>Jokaisessa C#-ohjelmassa on vähintään yksi luokka, mutta luokkia voi
284monta samanlaista (samannäköistä) piparia.
285
286Jokaisessa C\#-ohjelmassa on vähintään yksi luokka, mutta luokkia voi
241287olla enemmänkin. Luokan, jonka sisään ohjelma kirjoitetaan, on hyvä olla
242288samanniminen kuin tiedoston nimi. Jos tiedoston nimi on HelloWorld.cs,
243289on suositeltavaa, että luokan nimi on myös HelloWorld, kuten meidän
244290esimerkissämme. Tässä vaiheessa ei kuitenkaan vielä kannata liikaa
245291vaivata päätänsä sillä, mikä luokka oikeastaan on, se selviää tarkemmin
246myöhemmin.</p>
247<p>Huomaa! C#:ssa <em>ei</em> samasteta isoja ja pieniä kirjaimia. Ole siis
248tarkkana kirjoittaessasi luokkien nimiä.</p>
249<p>Huomaa! Vahva suositus (ja tämän kurssin tapa) on, että luokka alkaa
250isolla alkukirjaimella, ja ettei skandeja käytetä luokan nimessä.</p>
251<p>Luokan edessä oleva public-sana on eräs <em>saantimääre</em> (eng. <em>access
252modifier</em>). Saantimääreen avulla luokka voidaan asettaa rajoituksetta
292myöhemmin.
293
294Huomaa! C\#:ssa *ei* samasteta isoja ja pieniä kirjaimia. Ole siis
295tarkkana kirjoittaessasi luokkien nimiä.
296
297Huomaa! Vahva suositus (ja tämän kurssin tapa) on, että luokka alkaa
298isolla alkukirjaimella, ja ettei skandeja käytetä luokan nimessä.
299
300Luokan edessä oleva public-sana on eräs *saantimääre* (eng. *access
301modifier*). Saantimääreen avulla luokka voidaan asettaa rajoituksetta
253302tai osittain muiden (luokkien) saataville, tai piilottaa kokonaan. Sana
254303public tarkoittaa, että luokka on muiden luokkien näkökulmasta
255<em>julkinen</em>, kuten luokat useimmiten ovat. Muita saantimääreitä ovat
256protected, internal ja private.</p>
257<p>Määreen voi myös jättää kirjoittamatta luokan eteen, jolloin luokan
304*julkinen*, kuten luokat useimmiten ovat. Muita saantimääreitä ovat
305protected, internal ja private.
306
307Määreen voi myös jättää kirjoittamatta luokan eteen, jolloin luokan
258308määreeksi tulee automaattisesti internal. Puhumme aliohjelmista
259309myöhemmin, mutta mainittakoon, että vastaavasti, jos aliohjelmasta
260310jättää määreen kirjoittamatta, tulee siitä private. Tällä kurssilla
261311kuitenkin harjoitellaan kirjoittamaan julkisia luokkia (ja aliohjelmia),
262jolloin public-sana kirjoitetaan aina luokan ja aliohjelman eteen.</p>
263<p>Toisella rivillä on oikealle auki oleva <em>aaltosulku</em>. Useissa
312jolloin public-sana kirjoitetaan aina luokan ja aliohjelman eteen.
313
314Toisella rivillä on oikealle auki oleva *aaltosulku*. Useissa
264315ohjelmointikielissä yhteen liittyvät asiat ryhmitellään tai kootaan
265316aaltosulkeiden sisälle. Oikealle auki olevaa aaltosulkua sanotaan
266317aloittavaksi aaltosuluksi ja tässä tapauksessa se kertoo kääntäjälle,
319319aloittavaa aaltosulkua kohti täytyy olla vasemmalle auki oleva lopettava
320320aaltosulku. HelloWorld-luokan lopettava aaltosulku on rivillä viisi,
321321joka on samalla ohjelman viimeinen rivi. Aaltosulkeiden rajoittamaa
322aluetta kutsutaan <em>lohkoksi</em> (block).</p>
323<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
322aluetta kutsutaan *lohkoksi* (block).
323
324``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
324325public static void Main()
325{</code></p>
326<p>Rivillä kolme määritellään (tai oikeammin <em>esitellään</em>) uusi aliohjelma
326{
327```
328
329Rivillä kolme määritellään (tai oikeammin *esitellään*) uusi aliohjelma
327330nimeltä Main. Nimensä ansiosta se on tämän luokan pääohjelma. Sanat
328331static ja void kuuluvat aina Main-aliohjelman esittelyyn. Paneudumme
329332niihin tarkemmin hieman myöhemmin, mutta sanottakoon tässä kohtaa, että
330static tarkoittaa, että aliohjelma on <em>luokkakohtainen</em> (vastakohtana
331<em>oliokohtainen</em>, jolloin static-sanaa ei kirjoiteta). Vastaavasti void
332merkitsee, ettei aliohjelma palauta mitään tietoa.</p>
333<p>Samoin kuin luokan, niin myös pääohjelman sisältö kirjoitetaan
334aaltosulkeiden sisään. C#:ssa ohjelmoijan kirjoittaman koodin
333static tarkoittaa, että aliohjelma on *luokkakohtainen* (vastakohtana
334*oliokohtainen*, jolloin static-sanaa ei kirjoiteta). Vastaavasti void
335merkitsee, ettei aliohjelma palauta mitään tietoa.
336
337Samoin kuin luokan, niin myös pääohjelman sisältö kirjoitetaan
338aaltosulkeiden sisään. C\#:ssa ohjelmoijan kirjoittaman koodin
335339suorittaminen alkaa aina käynnistettävän luokan pääohjelmasta. Toki
336sisäisesti ehtii tapahtua paljon asioita jo ennen tätä.</p>
337<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
338System.Console.WriteLine("Hello World!");</code></p>
339<p>Rivillä neljä tulostetaan näytölle Hello World!. C#:ssa tämä tapahtuu
340sisäisesti ehtii tapahtua paljon asioita jo ennen tätä.
341
342``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
343System.Console.WriteLine("Hello World!");
344```
345
346Rivillä neljä tulostetaan näytölle Hello World!. C\#:ssa tämä tapahtuu
340347pyytämällä .NET-ympäristön mukana tulevan luokkakirjaston
341348System-luokkakirjaston Console-luokkaa tulostamaan
342WriteLine()-<em>metodilla</em> (method).</p>
343<p>Huomaa! Viitattaessa aliohjelmiin on kirjallisuudessa usein tapana
349WriteLine()-*metodilla* (method).
350
351Huomaa! Viitattaessa aliohjelmiin on kirjallisuudessa usein tapana
344352kirjoittaa aliohjelman nimen perään sulut. Kirjoitustyyli korostaa, että
345353kyseessä on aliohjelma, mutta asiayhteydestä riippuen sulut voi myös
346354jättää kirjoittamatta. Tässä monisteessa käytetään pääsääntöisesti
347jälkimmäistä tapaa, tilanteesta riippuen.</p>
348<p>Kirjastoista, olioista ja metodeista puhutaan lisää kohdassa 4.1 ja
355jälkimmäistä tapaa, tilanteesta riippuen.
356
357Kirjastoista, olioista ja metodeista puhutaan lisää kohdassa 4.1 ja
349358luvussa 8. Tulostettava merkkijono kirjoitetaan sulkeiden sisälle
350359lainausmerkkeihin (Shift + 2). Tämä rivi on myös tämän ohjelman ainoa
351<em>lause</em> (statement). Lauseiden voidaan ajatella olevan yksittäisiä
352toimenpiteitä, joista ohjelma koostuu. Jokainen lause päättyy C#:ssa
360*lause* (statement). Lauseiden voidaan ajatella olevan yksittäisiä
361toimenpiteitä, joista ohjelma koostuu. Jokainen lause päättyy C\#:ssa
353362puolipisteeseen. Koska lauseen loppuminen ilmoitetaan puolipisteellä, ei
354C#:n syntaksissa (syntax) ”tyhjillä merkeillä” (white space), kuten
363C\#:n syntaksissa (syntax) ”tyhjillä merkeillä” (white space), kuten
355364rivinvaihdoilla ja välilyönneillä ole merkitystä ohjelman toiminnan
356365kannalta. Ohjelmakoodin luettavuuden kannalta niillä on kuitenkin suuri
357366merkitys. Huomaa, että puolipisteen unohtaminen on yksi yleisimmistä
358ohjelmointivirheistä ja tarkemmin sanottuna <em>syntaksivirheistä.</em></p>
359<p><em>Syntaksi</em> = Tietyn ohjelmointikielen (esimerkiksi C#:n)
360kielioppisäännöstö.</p>
361<h3>2.3.1 Virhetyypit</h3>
362<p>Ohjelmointivirheet voidaan jakaa karkeasti <em>syntaksivirheisiin</em> ja
363<em>loogisiin virheisiin</em>.</p>
364<p>Syntaksivirhe estää ohjelman kääntymisen vaikka merkitys eli
365<em>semantiikka</em> olisikin oikein. Siksi ne huomataankin aina viimeistään
367ohjelmointivirheistä ja tarkemmin sanottuna *syntaksivirheistä.*
368
369*Syntaksi* = Tietyn ohjelmointikielen (esimerkiksi C\#:n)
370kielioppisäännöstö.
371
372### 2.3.1 Virhetyypit
373
374Ohjelmointivirheet voidaan jakaa karkeasti *syntaksivirheisiin* ja
375*loogisiin virheisiin*.
376
377Syntaksivirhe estää ohjelman kääntymisen vaikka merkitys eli
378*semantiikka* olisikin oikein. Siksi ne huomataankin aina viimeistään
366379ohjelmaa käännettäessä. Syntaksivirhe voi olla esimerkiksi joku
367kirjoitusvirhe tai puolipisteen unohtaminen lauseen lopusta.</p>
368<p>Loogisissa virheissä semantiikka, eli merkitys, on väärin. Ne on
380kirjoitusvirhe tai puolipisteen unohtaminen lauseen lopusta.
381
382Loogisissa virheissä semantiikka, eli merkitys, on väärin. Ne on
369383vaikeampi huomata, sillä ohjelma kääntyy semanttisista virheistä
370384huolimatta. Ohjelma voi jopa näyttää toimivan täysin oikein. Jos
371looginen virhe ei löydy <em>testauksessakaan</em> (testing), voivat seuraukset
385looginen virhe ei löydy *testauksessakaan* (testing), voivat seuraukset
372386ohjelmistosta riippuen olla tuhoisia. Tässä yksi tunnettu esimerkki
373loogisesta virheestä:</p>
374<p><a href="http://money.cnn.com/magazines/fortune/fortune_archive/2000/02/07/272831/index.htm">http://money.cnn.com/magazines/fortune/fortune_archive/2000/02/07/272831/index.htm</a>.</p>
375<h3>2.3.2 Kääntäjän virheilmoitusten tulkinta</h3>
376<p>Alla on esimerkki syntaksivirheestä HelloWorld-ohjelmassa.</p>
377<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
387loogisesta virheestä:
388
389[http://money.cnn.com/magazines/fortune/fortune\_archive/2000/02/07/272831/index.htm](http://money.cnn.com/magazines/fortune/fortune_archive/2000/02/07/272831/index.htm).
390
391### 2.3.2 Kääntäjän virheilmoitusten tulkinta
392
393Alla on esimerkki syntaksivirheestä HelloWorld-ohjelmassa.
394
395``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
378396public class HelloWorld
379397{
380398 public static void Main()
381399 {
382400 System.Console.Writeline("Hello World!");
383401 }
384}</code></p>
385<p>Ohjelmassa on pieni kirjoitusvirhe, joka on (ilman apuvälineitä) melko
386hankala huomata. Tutkitaan csc-kääntäjän antamaa virheilmoitusta.</p>
387<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
402}
403```
404
405Ohjelmassa on pieni kirjoitusvirhe, joka on (ilman apuvälineitä) melko
406hankala huomata. Tutkitaan csc-kääntäjän antamaa virheilmoitusta.
407
408``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
388409HelloWorld.cs(5,17): error CS0117: 'System.Console' does not contain a
389 definition for 'Writeline'</code></p>
390<p>Kääntäjä kertoo, että tiedostossa HelloWorld.cs rivillä 5 ja sarakkeessa
410 definition for 'Writeline'
411```
412
413Kääntäjä kertoo, että tiedostossa HelloWorld.cs rivillä 5 ja sarakkeessa
39141417 on seuraava virhe: System.Console-luokka ei tunne Writeline-komentoa.
392415Tämä onkin aivan totta, sillä WriteLine kirjoitetaan isolla L:llä.
393Korjattuamme tuon ohjelma toimii jälleen.</p>
394<p>Valitettavasti virheilmoituksen sisältö ei aina kuvaa ongelmaa kovinkaan
416Korjattuamme tuon ohjelma toimii jälleen.
417
418Valitettavasti virheilmoituksen sisältö ei aina kuvaa ongelmaa kovinkaan
395419hyvin. Alla olevassa esimerkissä on erehdytty laittamaan puolipisteen
396väärään paikkaan.</p>
397<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
420väärään paikkaan.
421
422``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
398423public class HelloWorld
399424{
400425 public static void Main();
401426 {
402427 System.Console.Writeline("Hello World!");
403428 }
404}</code></p>
405<p>Virheilmoitus, tai oikeastaan virheilmoitukset, näyttävät seuraavalta.</p>
406<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
429}
430```
431
432Virheilmoitus, tai oikeastaan virheilmoitukset, näyttävät seuraavalta.
433
434``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
407435HelloWorld.cs(4,3): error CS1519: Invalid token '{' in class, struct, or
408436 interface member declaration
409437HelloWorld.cs(5,26): error CS1519: Invalid token '(' in class, struct, or
410438 interface member declaration
411439HelloWorld.cs(7,1): error CS1022: Type or namespace definition, or end-of-file
412 expected</code></p>
413<p>Ensimmäinen virheilmoitus osoittaa riville 4, vaikka todellisuudessa
440 expected
441```
442
443Ensimmäinen virheilmoitus osoittaa riville 4, vaikka todellisuudessa
414444ongelma on rivillä 3. Toisin sanoen, näistä virheilmoituksista ei ole
415445meille tässä tilanteessa lainkaan apua, päinvastoin, ne kehottavat
416tekemään jotain, mitä emme halua.</p>
417<h3>2.3.3 Tyhjät merkit (White spaces)</h3>
418<p>Esimerkkinämme ollut HelloWorld-ohjelma voitaisiin, ilman että sen
446tekemään jotain, mitä emme halua.
447
448### 2.3.3 Tyhjät merkit (White spaces)
449
450Esimerkkinämme ollut HelloWorld-ohjelma voitaisiin, ilman että sen
419451toiminta muuttuisi, vaihtoehtoisesti kirjoittaa myös seuraavassa
420muodossa.</p>
421<p>``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
452muodossa.
453
454``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
422455public class HelloWorld
423 {</p>
424<pre><code> public static void Main()
425</code></pre>
426<p>{
456 {
457
458
459 public static void Main()
460 {
427461System.Console.WriteLine("Hello World!");
428 }</p>
429<p>}
430```</p>
431<p>\
432 \</p>
433<p>Edelleen, koodi voitaisiin kirjoittaa myös seuraavasti.</p>
434<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
462 }
463
464
465}
466```
467
468\
469 \
470
471Edelleen, koodi voitaisiin kirjoittaa myös seuraavasti.
472
473``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
435474public class HelloWorld { public static void Main() {
436 System.Console.WriteLine("Hello World!"); } }</code></p>
437<p>Vaikka molemmat yllä olevista esimerkeistä ovat syntaksiltaan oikein,
438eli ne noudattavat C#:n kielioppisääntöjä, on niiden luettavuus
439huomattavasti heikompi kuin alkuperäisen ohjelmamme. C#:ssa on
475 System.Console.WriteLine("Hello World!"); } }
476```
477
478Vaikka molemmat yllä olevista esimerkeistä ovat syntaksiltaan oikein,
479eli ne noudattavat C\#:n kielioppisääntöjä, on niiden luettavuus
480huomattavasti heikompi kuin alkuperäisen ohjelmamme. C\#:ssa on
440481yhteisesti sovittuja koodauskäytänteet (code conventions), jotka
441482määrittelevät, miten ohjelmakoodia tulisi kirjoittaa. Kun kaikki
442483kirjoittavat samalla tavalla, on muiden koodin lukeminen helpompaa.
443484Tämän monisteen esimerkit on pyritty kirjoittamaan näiden käytänteiden
444485mukaisesti. Linkkejä koodauskäytänteisiin löytyy kurssin wiki-sivulta
445osoitteesta</p>
446<p><a href="https://trac.cc.jyu.fi/projects/ohj1/wiki/CsKoodausKaytanteet">https://trac.cc.jyu.fi/projects/ohj1/wiki/CsKoodausKaytanteet</a><a href="https://trac.cc.jyu.fi/projects/ohj1/wiki/CsKoodausKaytanteet">.</a></p>
447<p>Merkkijonoja käsiteltäessä välilyönneillä, tabulaattoreilla ja
448rivinvaihdoilla on kuitenkin merkitystä. Vertaa alla olevia tulostuksia.</p>
449<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
450System.Console.WriteLine("Hello World!");</code></p>
451<p>Yllä oleva rivi tulostaa: Hello World!, kun taas alla oleva rivi
452tulostaa: H e l l o W o r l d !</p>
453<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
454System.Console.WriteLine("H e l l o W o r l d !");</code></p>
455<h2>2.4 Kommentointi</h2>
456<blockquote>
457<p>“Good programmers use their brains, but good guidelines save us having
458to think out every case.” -Francis Glassborow</p>
459</blockquote>
460<p>Lähdekoodia on usein vaikea ymmärtää pelkkää ohjelmointikieltä
486osoitteesta
487
488[https://trac.cc.jyu.fi/projects/ohj1/wiki/CsKoodausKaytanteet](https://trac.cc.jyu.fi/projects/ohj1/wiki/CsKoodausKaytanteet)[.](https://trac.cc.jyu.fi/projects/ohj1/wiki/CsKoodausKaytanteet)
489
490Merkkijonoja käsiteltäessä välilyönneillä, tabulaattoreilla ja
491rivinvaihdoilla on kuitenkin merkitystä. Vertaa alla olevia tulostuksia.
492
493``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
494System.Console.WriteLine("Hello World!");
495```
496
497Yllä oleva rivi tulostaa: Hello World!, kun taas alla oleva rivi
498tulostaa: H e l l o W o r l d !
499
500``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
501System.Console.WriteLine("H e l l o W o r l d !");
502```
503
5042.4 Kommentointi
505----------------
506
507> “Good programmers use their brains, but good guidelines save us having
508> to think out every case.” -Francis Glassborow
509
510Lähdekoodia on usein vaikea ymmärtää pelkkää ohjelmointikieltä
461511lukemalla. Tämän takia koodin sekaan voi ja pitää lisätä selosteita eli
462<em>kommentteja</em>. Kommentit ovat sekä koodin kirjoittajaa itseään varten
512*kommentteja*. Kommentit ovat sekä koodin kirjoittajaa itseään varten
463513että tulevia ohjelman lukijoita ja ylläpitäjiä varten. Monet asiat
464514voivat kirjoitettaessa tuntua ilmeisiltä, mutta jo viikon päästä saakin
465pähkäillä, että miksihän tuonkin tuohon kirjoitin.</p>
466<p>Kääntäjä jättää kommentit huomioimatta, joten ne eivät vaikuta ohjelman
467toimintaan. C#:ssa on kolmenlaisia kommentteja.</p>
468<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
469// Yhden rivin kommentti</code></p>
470<p>Yhden rivin kommentti alkaa kahdella vinoviivalla (//). Sen vaikutus
471kestää koko rivin loppuun.</p>
472<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
515pähkäillä, että miksihän tuonkin tuohon kirjoitin.
516
517Kääntäjä jättää kommentit huomioimatta, joten ne eivät vaikuta ohjelman
518toimintaan. C\#:ssa on kolmenlaisia kommentteja.
519
520``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
521// Yhden rivin kommentti
522```
523
524Yhden rivin kommentti alkaa kahdella vinoviivalla (//). Sen vaikutus
525kestää koko rivin loppuun.
526
527``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
473528/* Tämä kommentti
474529 on usean
475530 rivin
476 pituinen */</code></p>
477<p>Vinoviivalla ja asteriskilla alkava (/*) kommentti kestää niin kauan
478kunnes vastaan tulee asteriski ja vinoviiva ( */). Huomaa, ettei
479asteriskin ja vinoviivan väliin tule välilyöntiä.</p>
480<h3>2.4.1 Dokumentointi</h3>
481<p>Kolmas kommenttityyppi on <em>dokumentaatiokommentti</em>.
531 pituinen */
532```
533
534Vinoviivalla ja asteriskilla alkava (/\*) kommentti kestää niin kauan
535kunnes vastaan tulee asteriski ja vinoviiva ( \*/). Huomaa, ettei
536asteriskin ja vinoviivan väliin tule välilyöntiä.
537
538### 2.4.1 Dokumentointi
539
540Kolmas kommenttityyppi on *dokumentaatiokommentti*.
482541Dokumentaatiokommenteissa on tietty syntaksi, ja tätä noudattamalla
483542voidaan dokumentaatiokommentit muuttaa sellaiseen muotoon, että
484543kommentteihin perustuvaa yhteenvetoa on mahdollista tarkastella
485nettiselaimen avulla.</p>
486<p>Dokumentaatiokommentti olisi syytä kirjoittaa ennen jokaista luokkaa,
544nettiselaimen avulla.
545
546Dokumentaatiokommentti olisi syytä kirjoittaa ennen jokaista luokkaa,
487547pääohjelmaa, aliohjelmaa ja metodia (aliohjelmista ja metodeista
488puhutaan myöhemmin). Lisäksi jokainen C#-tiedosto alkaa aina
548puhutaan myöhemmin). Lisäksi jokainen C\#-tiedosto alkaa aina
489549dokumentaatiokommentilla, josta selviää tiedoston tarkoitus, tekijä ja
490versio.</p>
491<p>Dokumentaatiokommentit kirjoitetaan siten, että rivin alussa on aina
550versio.
551
552Dokumentaatiokommentit kirjoitetaan siten, että rivin alussa on aina
492553aina kolme vinoviivaa (Shift + 7). Jokainen seuraava
493554dokumentaatiokommenttirivi aloitetaan siis myöskin kolmella
494vinoviivalla.</p>
495<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
555vinoviivalla.
556
557``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
496558/// Tämä
497559/// on
498/// dokumentaatiokommentti</code></p>
499<p>Dokumentoiminen tapahtuu <em>tagien</em> avulla. Jos olet joskus kirjoittanut
560/// dokumentaatiokommentti
561```
562
563Dokumentoiminen tapahtuu *tagien* avulla. Jos olet joskus kirjoittanut
500564HTML-sivuja, on merkintätapa sinulle tuttu. Dokumentaatiokommentit
501alkavat aloitustagilla, muotoa \&lt;esimerkki>, jonka perään tulee
565alkavat aloitustagilla, muotoa \<esimerkki\>, jonka perään tulee
502566kommentin asiasisältö. Kommentti loppuu lopetustagiin, muotoa
503\&lt;/esimerkki>, siis muuten sama kuin aloitustagi, mutta ensimmäisen
504kulmasulun jälkeen on yksi vinoviiva.</p>
505<p>C#-tageja ovat esimerkiksi \&lt;summary>, jolla ilmoitetaan pieni
567\</esimerkki\>, siis muuten sama kuin aloitustagi, mutta ensimmäisen
568kulmasulun jälkeen on yksi vinoviiva.
569
570C\#-tageja ovat esimerkiksi \<summary\>, jolla ilmoitetaan pieni
506571yhteenveto kommenttia seuraavasta koodilohkosta (esimerkiksi pääohjelma
507tai metodi). Yhteenveto päättyy \&lt;/summary> -lopetustagiin.</p>
508<p>Ohjelman kääntämisen yhteydessä dokumentaatiotagit voidaan kirjoittaa
509erilliseen <em>XML</em>-tiedostoon, josta ne voidaan edelleen muuntaa helposti
572tai metodi). Yhteenveto päättyy \</summary\> -lopetustagiin.
573
574Ohjelman kääntämisen yhteydessä dokumentaatiotagit voidaan kirjoittaa
575erilliseen *XML*-tiedostoon, josta ne voidaan edelleen muuntaa helposti
510576selattaviksi HTML-sivuiksi. Tageja voi keksiä itsekin lisää, mutta tämän
511577kurssin tarpeisiin riittää hyvin suositeltujen tagien luettelo. Tiedot
512suositelluista tageista löytyvät C#:n dokumentaatiosta:</p>
513<p><a href="http://msdn.microsoft.com/en-us/library/5ast78ax.aspx">http://msdn.microsoft.com/en-us/library/5ast78ax.aspx</a><a href="http://msdn.microsoft.com/en-us/library/5ast78ax.aspx">.</a></p>
514<p>Voisimme kirjoittaa nyt C#-kommentit HelloWorld-ohjelman alkuun
515seuraavasti:</p>
516<p>``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
578suositelluista tageista löytyvät C\#:n dokumentaatiosta:
579
580[http://msdn.microsoft.com/en-us/library/5ast78ax.aspx](http://msdn.microsoft.com/en-us/library/5ast78ax.aspx)[.](http://msdn.microsoft.com/en-us/library/5ast78ax.aspx)
581
582Voisimme kirjoittaa nyt C\#-kommentit HelloWorld-ohjelman alkuun
583seuraavasti:
584
585``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
517586/// @author Antti-Jussi Lakanen
518587/// @version 28.8.2012
519588///
520589/// <summary>
521590/// Esimerkkiohjelma, joka tulostaa tekstin "Hello World!"
522/// </summary></p>
523<p>public class HelloWorld
591/// </summary>
592
593public class HelloWorld
524594{
525595 /// <summary>
526596 /// Pääohjelma, joka hoitaa varsinaisen tulostamisen.
601601 System.Console.WriteLine("Hello World!"); // Tämä lause tulostaa ruudulle
602602 } // Ohjelman suoritus päättyy tähän
603603}
604```</p>
605<p>Ohjelman alussa kerrotaan kohteen tekijän nimi. Tämän jälkeen tulee
604```
605
606Ohjelman alussa kerrotaan kohteen tekijän nimi. Tämän jälkeen tulee
606607ensimmäinen dokumentaatiokommentti (huomaa kolme vinoviivaa), joka on
607608lyhyt ja ytimekäs kuvaus tästä luokasta. Huomaa, että jossain
608609dokumentaation tiivistelmissä näytetään vain tuo ensimmäinen virke.
609[DOC] [HYV]</p>
610<p><em>Dokumentointi on erittäin keskeinen osa ohjelmistotyötä</em>. Luokkien ja
610[DOC] [HYV]
611
612*Dokumentointi on erittäin keskeinen osa ohjelmistotyötä*. Luokkien ja
611613koodirivien määrän kasvaessa dokumentointi helpottaa niin omaa
612614työskentelyä kuin tulevien käyttäjien ja ylläpitäjien tehtävää.
613615Dokumentoinnin tärkeys näkyy muun muassa siinä, että jopa 40-60%
614616ylläpitäjien ajasta kuluu muokattavan ohjelman ymmärtämiseen.
615[KOSK][KOS]</p>
616<h1>3. Algoritmit</h1>
617<blockquote>
618<p>“First, solve the problem. Then, write the code.” - John Johnson</p>
619</blockquote>
620<h2>3.1 Mikä on algoritmi?</h2>
621<p>Pyrittäessä kirjoittamaan koneelle kelpaavia ohjeita joudutaan
617[KOSK][KOS]
618
6193. Algoritmit
620=============
621
622> “First, solve the problem. Then, write the code.” - John Johnson
623
6243.1 Mikä on algoritmi?
625----------------------
626
627Pyrittäessä kirjoittamaan koneelle kelpaavia ohjeita joudutaan
622628suoritettavana oleva toimenpide kirjaamaan sarjana yksinkertaisia
623629toimenpiteitä. Toimenpidesarjan tulee olla yksikäsitteinen, eli sen
624630tulee joka tilanteessa tarjota yksi ja vain yksi tapa toimia, eikä siinä
625631saa esiintyä ristiriitaisuuksia. Yksikäsitteistä kuvausta tehtävän
626ratkaisuun tarvittavista toimenpiteistä kutsutaan algoritmiksi.</p>
627<p>Ohjelman kirjoittaminen voidaan aloittaa hahmottelemalla tarvittavat
632ratkaisuun tarvittavista toimenpiteistä kutsutaan algoritmiksi.
633
634Ohjelman kirjoittaminen voidaan aloittaa hahmottelemalla tarvittavat
628635algoritmit eli kirjaamalla lista niistä toimenpiteistä, joita tehtävän
629suoritukseen tarvitaan:</p>
630<p>``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
631Kahvin keittäminen:</p>
632<ol>
633<li>Täytä pannu vedellä.</li>
634<li>Keitä vesi.</li>
635<li>Lisää kahvijauhot.</li>
636<li>Anna tasaantua.</li>
637<li>Tarjoile kahvi.
638```</li>
639</ol>
640<p>Algoritmi on yleisesti ottaen mahdollisimman pitkälle tarkennettu
636suoritukseen tarvitaan:
637
638``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
639Kahvin keittäminen:
640
6411. Täytä pannu vedellä.
6422. Keitä vesi.
6433. Lisää kahvijauhot.
6444. Anna tasaantua.
6455. Tarjoile kahvi.
646```
647
648Algoritmi on yleisesti ottaen mahdollisimman pitkälle tarkennettu
641649toimenpidesarja, jossa askel askeleelta esitetään yksikäsitteisessä
642muodossa ne toimenpiteet, joita asetetun ongelman ratkaisuun tarvitaan.</p>
643<h2>3.2 Tarkentaminen</h2>
644<p>Kun tarkastellaan lähes mitä tahansa tehtävänantoa, huomataan, että
650muodossa ne toimenpiteet, joita asetetun ongelman ratkaisuun tarvitaan.
651
6523.2 Tarkentaminen
653-----------------
654
655Kun tarkastellaan lähes mitä tahansa tehtävänantoa, huomataan, että
645656tehtävän suoritus koostuu selkeästi toisistaan eroavista osatehtävistä.
646657Se, miten yksittäinen osatehtävä ratkaistaan, ei vaikuta muiden
647658osatehtävien suorittamiseen. Vain sillä, että kukin osasuoritus tehdään,
648659on merkitystä. Esimerkiksi pannukahvinkeitossa jokainen osatehtävä
649voidaan jakaa edelleen osasiin:</p>
650<p>``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
651Kahvinkeitto:</p>
652<ol>
653<li>Täytä pannu vedellä:
660voidaan jakaa edelleen osasiin:
661
662``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
663Kahvinkeitto:
664
6651. Täytä pannu vedellä:
654666 1.1. Pistä pannu hanan alle.
655667 1.2. Avaa hana.
656 1.3. Anna veden valua, kunnes vettä on riittävästi.</li>
657<li>Keitä vesi:
668 1.3. Anna veden valua, kunnes vettä on riittävästi.
6692. Keitä vesi:
658670 2.1. Aseta pannu hellalle.
659671 2.2. Kytke virta keittolevyyn.
660 2.3. Anna lämmetä, kunnes vesi kiehuu.</li>
661<li>Lisää kahvinporot:
672 2.3. Anna lämmetä, kunnes vesi kiehuu.
6733. Lisää kahvinporot:
662674 3.1. Mittaa kahvinporot.
663 3.2. Sekoita kahvinporot kiehuvaan veteen.</li>
664<li>Anna tasaantua:
675 3.2. Sekoita kahvinporot kiehuvaan veteen.
6764. Anna tasaantua:
665677 4.1. Odota, kunnes suurin osa valmiista kahvista on vajonnut
666 pannun pohjalle.</li>
667<li>Tarjoile kahvi:
678 pannun pohjalle.
6795. Tarjoile kahvi:
668680 5.1. Tämä sitten onkin jo oma tarinansa...
669```</li>
670</ol>
671<p>Edellä esitetyn kahvinkeitto-ongelman ratkaisu esitettiin jakamalla
681```
682
683Edellä esitetyn kahvinkeitto-ongelman ratkaisu esitettiin jakamalla
672684ratkaisu viiteen osavaiheeseen. Ratkaisun algoritmi sisältää viisi
673685toteutettavaa lausetta. Kun näitä viittä lausetta tarkastellaan
674686lähemmin, osoittautuu, että niistä kukin on edelleen jaettavissa
675687osavaiheisiin, eli ratkaisun pääalgoritmi voidaan jakaa edelleen
676688alialgoritmeiksi, joissa askel askeleelta esitetään, kuinka kukin
677osatehtävä ratkaistaan.</p>
678<p>Algoritmien kirjoittaminen osoittautuu hierarkkiseksi prosessiksi, jossa
689osatehtävä ratkaistaan.
690
691Algoritmien kirjoittaminen osoittautuu hierarkkiseksi prosessiksi, jossa
679692aluksi tehtävä jaetaan osatehtäviin, joita edelleen tarkennetaan, kunnes
680693kukin osatehtävä on niin yksinkertainen, ettei sen suorittamisessa enää
681ole mitään moniselitteistä.</p>
682<h2>3.3 Yleistäminen</h2>
683<p>Eräs tärkeä algoritmien kirjoittamisen vaihe on yleistäminen. Tällöin
694ole mitään moniselitteistä.
695
6963.3 Yleistäminen
697----------------
698
699Eräs tärkeä algoritmien kirjoittamisen vaihe on yleistäminen. Tällöin
684700valmiiksi tehdystä algoritmista pyritään paikantamaan kaikki alunperin
685701annetusta tehtävästä riippuvat tekijät, ja pohditaan voitaisiinko ne
686kenties kokonaan poistaa tai korvata joillakin yleisemmillä tekijöillä.</p>
687<h2>3.4 Harjoitus</h2>
688<p>Tarkastele edellä esitettyä algoritmia kahvin keittämiseksi ja luo
702kenties kokonaan poistaa tai korvata joillakin yleisemmillä tekijöillä.
703
7043.4 Harjoitus
705-------------
706
707Tarkastele edellä esitettyä algoritmia kahvin keittämiseksi ja luo
689708vastaava algoritmi teen keittämiseksi. Vertaile algoritmeja: mitä samaa
690709ja mitä eroa niissä on? Onko mahdollista luoda algoritmi, joka
691710yksiselitteisesti selviäisi sekä kahvin että teen keitosta? Onko
692711mahdollista luoda algoritmi, joka saman tien selviytyisi maitokaakosta
693ja rommitotista?</p>
694<h2>3.5 Peräkkäisyys</h2>
695<p>Kuten luvussa 1 olevassa reseptissä ja muissakin ihmisille
712ja rommitotista?
713
7143.5 Peräkkäisyys
715----------------
716
717Kuten luvussa 1 olevassa reseptissä ja muissakin ihmisille
696718kirjoitetuissa ohjeissa, niin myös tietokoneelle esitetyt ohjeet luetaan
697719ylhäältä alaspäin, ellei muuta ilmoiteta. Esimerkiksi ohjeen lumiukon
698piirtämisestä voisi esittää yksinkertaistettuna alla olevalla tavalla.</p>
699<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
720piirtämisestä voisi esittää yksinkertaistettuna alla olevalla tavalla.
721
722``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
700723Piirrä säteeltään 20cm kokoinen ympyrä koordinaatiston pisteeseen (20, 80)
701724Piirrä säteeltään 15cm kokoinen ympyrä edellisen ympyrän päälle
702Piirrä säteeltään 10cm kokoinen ympyrä edellisen ympyrän päälle</code></p>
703<p>Yllä oleva koodi ei ole vielä mitään ohjelmointikieltä, mutta se
725Piirrä säteeltään 10cm kokoinen ympyrä edellisen ympyrän päälle
726```
727
728Yllä oleva koodi ei ole vielä mitään ohjelmointikieltä, mutta se
704729sisältää jo ajatuksen siitä kuinka lumiukko voitaisiin tietokoneella
705piirtää. Piirrämme lumiukon C#-ohjelmointikielellä seuraavassa luvussa.</p>
706<h1>4. Yksinkertainen graafinen C#-ohjelma</h1>
707<p>Seuraavissa esimerkeissä käytetään Jyväskylän yliopistossa
708kehitettyä<em>Jypeli-ohjelmointikirjastoa.</em> Kirjaston voit ladata koneelle
709osoitteesta</p>
710<p><a href="https://trac.cc.jyu.fi/projects/npo/wiki/LataaJypeli">https://trac.cc.jyu.fi/projects/npo/wiki/LataaJypeli</a>,</p>
711<p>josta löytyy myös ohjeet kirjaston asennukseen ja käyttöön. Huomaa, että
730piirtää. Piirrämme lumiukon C\#-ohjelmointikielellä seuraavassa luvussa.
731
7324. Yksinkertainen graafinen C\#-ohjelma
733=======================================
734
735Seuraavissa esimerkeissä käytetään Jyväskylän yliopistossa
736kehitettyä*Jypeli-ohjelmointikirjastoa.* Kirjaston voit ladata koneelle
737osoitteesta
738
739[https://trac.cc.jyu.fi/projects/npo/wiki/LataaJypeli](https://trac.cc.jyu.fi/projects/npo/wiki/LataaJypeli),
740
741josta löytyy myös ohjeet kirjaston asennukseen ja käyttöön. Huomaa, että
712742tietokoneellasi tulee olla asennettuna .NET Framework 4 sekä XNA Game
713743Studio 4, jotta graafinen ohjelma voidaan kääntää. .NET-frameworkin
714asennusohjeet löytyvät osoitteesta</p>
715<p><a href="https://trac.cc.jyu.fi/projects/ohj1/wiki/dotnet-tyokalut">https://trac.cc.jyu.fi/projects/ohj1/wiki/dotnet-tyokalut</a>.</p>
716<p>Vaikka tässä kohtaa emme vielä Visual Studio 2010 -kehitysympäristöä
744asennusohjeet löytyvät osoitteesta
745
746[https://trac.cc.jyu.fi/projects/ohj1/wiki/dotnet-tyokalut](https://trac.cc.jyu.fi/projects/ohj1/wiki/dotnet-tyokalut).
747
748Vaikka tässä kohtaa emme vielä Visual Studio 2010 -kehitysympäristöä
717749tarvitsekaan, on sen asentaminen tässä kohtaa myös viisasta, sillä
718750Visual Studio tulisi olla asennettuna ennen XNA:n ja Jypelin
719asentamista.</p>
720<h2>4.1 Mikä on kirjasto?</h2>
721<p>C#-ohjelmat koostuvat luokista. Luokat taas sisältävät metodeja (ja
751asentamista.
752
7534.1 Mikä on kirjasto?
754---------------------
755
756C\#-ohjelmat koostuvat luokista. Luokat taas sisältävät metodeja (ja
722757aliohjelmia), jotka suorittavat tehtäviä ja mahdollisesti palauttavat
723758arvoja suoritettuaan näitä tehtäviä. Metodi voisi esimerkiksi laskea
724759kahden luvun summan ja palauttaa tuloksen tai piirtää ohjelmoijan
725760haluaman kokoisen ympyrän. Samaan asiaan liittyviä metodeja kootaan
726761luokkaan ja luokkia kootaan edelleen kirjastoiksi. Idea kirjastoissa on,
727762ettei kannata tehdä uudelleen sitä minkä joku on jo tehnyt. Toisin
728sanoen, pyörää ei kannata keksiä uudelleen.</p>
729<p>C#-ohjelmoijan kannalta oleellisin kirjasto on .NET Framework
763sanoen, pyörää ei kannata keksiä uudelleen.
764
765C\#-ohjelmoijan kannalta oleellisin kirjasto on .NET Framework
730766luokkakirjasto. Luokkakirjaston dokumentaatioon (documentation)
731767kannattaa tutustua, sillä sieltä löytyy monia todella hyödyllisiä
732metodeja. Dokumentaatio löytyy Microsoftin sivuilta osoitteesta</p>
733<p><a href="http://msdn.microsoft.com/en-us/library/ms229335.aspx">http://msdn.microsoft.com/en-us/library/ms229335.aspx</a>.</p>
734<p><em>Dokumentaatio =</em> Sisältää tiedot kaikista kirjaston luokista ja niiden
735metodeista (ja aliohjelmista). Löytyy useimmiten ainakin WWW-muodossa.</p>
736<h2>4.2 Jypeli-kirjasto</h2>
737<p>Jypeli-kirjaston kehittäminen aloitettiin Jyväskylän yliopistossa
768metodeja. Dokumentaatio löytyy Microsoftin sivuilta osoitteesta
769
770[http://msdn.microsoft.com/en-us/library/ms229335.aspx](http://msdn.microsoft.com/en-us/library/ms229335.aspx).
771
772*Dokumentaatio =* Sisältää tiedot kaikista kirjaston luokista ja niiden
773metodeista (ja aliohjelmista). Löytyy useimmiten ainakin WWW-muodossa.
774
7754.2 Jypeli-kirjasto
776-------------------
777
778Jypeli-kirjaston kehittäminen aloitettiin Jyväskylän yliopistossa
738779keväällä 2009. Tämän monisteen esimerkeissä käytetään versiota 4.
739780Jypeli-kirjastoon on kirjoitettu valmiita luokkia ja metodeja siten,
740781että esimerkiksi fysiikan ja matematiikan ilmiöiden, sekä pelihahmojen
741ja liikkeiden ohjelmointi lopulliseen ohjelmaan on helpompaa.</p>
742<h2>4.3 Esimerkki: Lumiukko</h2>
743<p>Piirretään lumiukko käyttämällä Jypeli-kirjastoa. Mallikoodin vasemmassa
782ja liikkeiden ohjelmointi lopulliseen ohjelmaan on helpompaa.
783
7844.3 Esimerkki: Lumiukko
785-----------------------
786
787Piirretään lumiukko käyttämällä Jypeli-kirjastoa. Mallikoodin vasemmassa
744788reunassa juoksee myös rivinumerointi, joka ei kuulu koodiin, mutta
745helpottaa lukemista.</p>
746<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
789helpottaa lukemista.
790
791``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
74779201 // Otetaan käyttöön Jyväskylän yliopiston Jypeli-kirjasto
74879302 using Jypeli;
74979403
79679605 /// @version 22.12.2011
79779706 ///
79879807 ///
79908 /// &lt;summary&gt;
79908 /// <summary>
80080009 /// Luokka, jossa harjoitellaan piirtämistä lisäämällä ympyröitä ruudulle
80110 /// &lt;/summary&gt;
80110 /// </summary>
80280211 public class Lumiukko : PhysicsGame
80380312 {
80413 /// &lt;summary&gt;
80413 /// <summary>
80580514 /// Pääohjelmassa laitetaan "peli" käyntiin Jypelille tyypilliseen tapaan
80615 /// &lt;/summary&gt;
80716 /// &lt;param name="args"&gt;Ei käytössä&lt;/param&gt;
80615 /// </summary>
80716 /// <param name="args">Ei käytössä</param>
80880817 public static void Main(string[] args)
80980918 {
81081019 using (Lumiukko peli = new Lumiukko())
81381322 }
81481423 }
81581524
81625 /// &lt;summary&gt;
81625 /// <summary>
81781726 /// Piirretään oliot ja zoomataan kamera niin että kenttä näkyy kokonaan.
81827 /// &lt;/summary&gt;
81827 /// </summary>
81981928 public override void Begin()
82082029 {
82182130 Camera.ZoomToLevel();
83383342 p3.Y = p2.Y + 50 + 30;
83483443 Add(p3);
83583544 }
83645 }</code></p>
837<p>Ajettaessa ohjelman tulisi piirtää yksinkertainen lumiukko keskelle
838ruutua, kuten alla olevassa kuvassa. 4.3.1 Ohjelman suoritus</p>
839<p><img alt="\
83645 }
837```
838
839Ajettaessa ohjelman tulisi piirtää yksinkertainen lumiukko keskelle
840ruutua, kuten alla olevassa kuvassa. 4.3.1 Ohjelman suoritus
841
842![\
840843 Kuva 2: Lumiukko Jypeli-kirjaston avulla
841piirrettynä" src="../src/luentomonistecsUusin_htm_m793342fb.png" /></p>
842<p>\</p>
843<h3>4.3.1 Ohjelman suoritus</h3>
844<p>Ohjelman suoritus aloitetaan aina pääohjelmasta ja sitten edetään rivi
844piirrettynä](../src/luentomonistecsUusin_htm_m793342fb.png)
845
846\
847
848### 4.3.1 Ohjelman suoritus
849
850Ohjelman suoritus aloitetaan aina pääohjelmasta ja sitten edetään rivi
845851riviltä ylhäältä alaspäin ohjelman loppuun niin kauan kuin lauseita
846852riittää. Ohjelmassa voi olla myös rakenteita, joissa toistetaan tiettyjä
847853rivejä useampaan kertaan vain muuttamalla jotain arvoa tai arvoja.
848854Pääohjelmassa voi olla myös aliohjelmakutsuja jolloin hypätään
849855pääohjelmasta suorittamaan aliohjelmaa ja palataan sitten takaisin
850pääohjelman suoritukseen. Aliohjelmista puhutaan enemmän luvussa 6.</p>
851<h3>4.3.2 Ohjelman oleellisemmat kohdat</h3>
852<p>Tarkastellaan ohjelman oleellisempia kohtia.</p>
853<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
85402 using Jypeli;</code></p>
855<p>Aluksi meidän täytyy kertoa kääntäjälle, että haluamme ottaa käyttöön
856pääohjelman suoritukseen. Aliohjelmista puhutaan enemmän luvussa 6.
857
858### 4.3.2 Ohjelman oleellisemmat kohdat
859
860Tarkastellaan ohjelman oleellisempia kohtia.
861
862``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
86302 using Jypeli;
864```
865
866Aluksi meidän täytyy kertoa kääntäjälle, että haluamme ottaa käyttöön
856867koko Jypeli-kirjaston. Nyt Jypeli-kirjaston kaikki luokat (ja niiden
857metodit) ovat käytettävissämme.</p>
858<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
85908 /// &lt;summary&gt;
868metodit) ovat käytettävissämme.
869
870``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
87108 /// <summary>
86087209 /// Luokka, jossa harjoitellaan piirtämistä lisäämällä ympyröitä ruudulle
86110 /// &lt;/summary&gt;
87310 /// </summary>
86287411 public class Lumiukko : PhysicsGame
86312 {</code></p>
864<p>Rivit 8-10 ovat dokumentaatiokommentteja. Rivillä 11 luodaan
87512 {
876```
877
878Rivit 8-10 ovat dokumentaatiokommentteja. Rivillä 11 luodaan
865879Lumiukko-luokka, joka hieman poikkeaa HelloWorld-esimerkin tavasta luoda
866880uusi luokka. Tässä kohtaa käytämme ensimmäisen kerran Jypeli-kirjastoa,
867881ja koodissa kerrommekin, että Lumiukko-luokka, jota juuri olemme
868882tekemässä, ”perustuu” Jypeli-kirjastossa olevaan PhysicsGame-luokkaan.
869883Täsmällisemmin sanottuna Lumiukko-luokka peritään PhysicsGame-luokasta.
870884Tuon PhysicsGame-luokan avulla objektien piirtäminen, myöhemmin
871liikuttelu ruudulla ja fysiikan lakien hyödyntäminen on vaivatonta.</p>
872<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
87313 /// &lt;summary&gt;
885liikuttelu ruudulla ja fysiikan lakien hyödyntäminen on vaivatonta.
886
887``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
88813 /// <summary>
87488914 /// Pääohjelmassa laitetaan "peli" käyntiin Jypelille tyypilliseen tapaan.
87515 /// &lt;/summary&gt;
87616 /// &lt;param name="args"&gt;Ei käytössä&lt;/param&gt;
89015 /// </summary>
89116 /// <param name="args">Ei käytössä</param>
87789217 public static void Main(String[] args)
87889318 {
87989419 using (Lumiukko peli = new Lumiukko())
88089520 {
88189621 peli.Run();
88289722 }
88323 }</code></p>
884<p>Myös Main-metodi, eli pääohjelma, on Jypeli-peleissä käytännössä aina
89823 }
899```
900
901Myös Main-metodi, eli pääohjelma, on Jypeli-peleissä käytännössä aina
885902tällainen vakiomuotoinen, joten jatkossa siihen ei tarvitse juurikaan
886903koskea. Ohitamme tässä vaiheessa pääohjelman sisällön mainitsemalla
887904vain, että pääohjelmassa Lumiukko-luokasta tehdään uusi olio (eli uusi
888905”peli”), joka sitten laitetaan käyntiin peli.Run()-kohdassa.
889906Jypeli-kirjaston rakenteesta johtuen kaikki varsinainen peliin liittyvä
890907koodi kirjoitetaan omaan aliohjelmaansa, Begin-aliohjelmaan, jota
891käsittelemme seuraavaksi.</p>
892<p>Tarkasti ottaen Begin alkaa riviltä 29. Ensimmäinen lause on kirjoitettu
893riville 30.</p>
894<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
908käsittelemme seuraavaksi.
909
910Tarkasti ottaen Begin alkaa riviltä 29. Ensimmäinen lause on kirjoitettu
911riville 30.
912
913``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
89591430 Camera.ZoomToLevel();
89631 Level.Background.Color = Color.Black;</code></p>
897<p>Näistä kahdesta rivistä ensimmäisellä kutsutaan Camera-luokan
91531 Level.Background.Color = Color.Black;
916```
917
918Näistä kahdesta rivistä ensimmäisellä kutsutaan Camera-luokan
898919ZoomToLevel-aliohjelmaa, joka pitää huolen siitä, että ”kamera” on
899920kohdistettuna ja zoomattuna oikeaan kohtaan. Aliohjelma ei ota vastaan
900921parametreja, joten sulkujen sisältö jää tyhjäksi. Toisella rivillä
901muutetaan taustan väri.</p>
902<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
922muutetaan taustan väri.
923
924``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
90392533 PhysicsObject p1 = new PhysicsObject(2*100.0, 2*100.0, Shape.Circle);
90492634 p1.Y = Level.Bottom + 200.0;
90535 Add(p1);</code></p>
906<p>Näiden kolmen rivin aikana luomme uuden fysiikkaolio-ympyrän, annamme
92735 Add(p1);
928```
929
930Näiden kolmen rivin aikana luomme uuden fysiikkaolio-ympyrän, annamme
907931sille säteen, y-koordinaatin, sekä lisäämme sen ”pelikentälle”, eli
908näkyvälle alueelle valmiissa ohjelmassa.</p>
909<p>Tarkemmin sanottuna luomme uuden PhysicsObject-<em>olion</em> eli
910PhysicsObject-luokan <em>ilmentymän</em>, jonka nimeksi annamme p1.
932näkyvälle alueelle valmiissa ohjelmassa.
933
934Tarkemmin sanottuna luomme uuden PhysicsObject-*olion* eli
935PhysicsObject-luokan *ilmentymän*, jonka nimeksi annamme p1.
911936PhysicsObject-oliot ovat pelialueella liikkuvia olioita, jotka
912937noudattavat fysiikan lakeja. Sulkujen sisään laitamme tiedon siitä,
913938millaisen objektin haluamme luoda - tässä tapauksessa leveys ja korkeus
914939(Jypeli-mitoissa, ei pikseleissä), sekä olion muoto. Teemme siis
915ympyrän, jonka säde on 100 (leveys 2 * 100 ja korkeus 2 * 100). Muita
940ympyrän, jonka säde on 100 (leveys 2 \* 100 ja korkeus 2 \* 100). Muita
916941Shape-kokoelmasta löytyviä muotoja ovat muiden muassa kolmio, neliö,
917sydän jne. Olioista puhutaan lisää luvussa 8.</p>
918<p>Kokeile itse muuttaa olion muotoa!</p>
919<p>Seuraavalla rivillä asetetaan olion paikka Y-arvon avulla. Huomaa että Y
942sydän jne. Olioista puhutaan lisää luvussa 8.
943
944Kokeile itse muuttaa olion muotoa!
945
946Seuraavalla rivillä asetetaan olion paikka Y-arvon avulla. Huomaa että Y
920947kirjoitetaan isolla kirjaimella. Tämä on p1-olion ominaisuus,
921948attribuutti. X-koordinaattia meidän ei tarvitse tässä erikseen asettaa,
922949se on oletusarvoisesti 0 ja se kelpaa meille. Saadaksemme ympyrät
923950piirrettyä oikeille paikoilleen, täytyy meidän laskea koordinaattien
924951paikat. Oletuksena ikkunan keskipiste on koordinaatiston origo eli piste
925952(0, 0). x-koordinaatin arvot kasvavat oikealle ja y:n arvot ylöspäin,
926samoin kuin ”normaalissa” koulusta tutussa koordinaatistossa.</p>
927<p>Peliolio täytyy aina lisätä kentälle, ennen kuin se saadaan näkyviin.
953samoin kuin ”normaalissa” koulusta tutussa koordinaatistossa.
954
955Peliolio täytyy aina lisätä kentälle, ennen kuin se saadaan näkyviin.
928956Tämä tapahtuu Add-metodin avulla, joka ottaa parametrina kentälle
929lisättävän olion nimen (tässä p1).</p>
930<p>Metodeille annettavia tietoja sanotaan <em>parametreiksi</em> (parameter).
957lisättävän olion nimen (tässä p1).
958
959Metodeille annettavia tietoja sanotaan *parametreiksi* (parameter).
931960ZoomToLevel-metodi ei ota vastaan yhtään parametria, mutta Add-metodi
932961sen sijaan ottaa yhden parametrin: PhysicsObject-tyyppisen olion.
933Add-metodille voidaan antaa toinenkin parametri: <em>taso</em>, jolle olio
962Add-metodille voidaan antaa toinenkin parametri: *taso*, jolle olio
934963lisätään. Tasojen avulla voidaan hallita, mitkä oliot lisätään
935964päällimmäiseksi. Tasoparametri voidaan kuitenkin jättää antamatta,
936965jolloin ohjelma itse päättää tasojen parhaan järjestyksen. Parametrit
937966kirjoitetaan metodin nimen perään sulkeisiin ja ne erotetaan toisistaan
938pilkuilla.</p>
939<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
940MetodinNimi(parametri1, parametri2,..., parametriX);</code></p>
941<p>Seuraavien rivien aikana luomme vielä kaksi ympyrää vastaavalla tavalla,
942mutta vaihtaen sädettä ja ympyrän koordinaatteja.</p>
943<p>Esimerkissä koordinaattien laskemiseen on käytetty C#:n <em>aritmeettisia
944operaatioita</em>. Voisimme tietenkin laskea koordinaattien pisteet myös
967pilkuilla.
968
969``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
970MetodinNimi(parametri1, parametri2,..., parametriX);
971```
972
973Seuraavien rivien aikana luomme vielä kaksi ympyrää vastaavalla tavalla,
974mutta vaihtaen sädettä ja ympyrän koordinaatteja.
975
976Esimerkissä koordinaattien laskemiseen on käytetty C\#:n *aritmeettisia
977operaatioita*. Voisimme tietenkin laskea koordinaattien pisteet myös
945978itse, mutta miksi tehdä niin jos tietokone voi laskea pisteet
946puolestamme? C#:n aritmeettiset perusoperaatiot ovat summa (+),
947vähennys (-), kerto (*), jako (/) ja jakojäännös (%). Aritmeettisista
948operaatioista puhutaan lisää muuttujien yhteydessä kohdassa 7.7.1.</p>
949<p>Keskimmäinen ympyrä tulee alimman ympyrän yläpuolelle niin, että ympyrät
979puolestamme? C\#:n aritmeettiset perusoperaatiot ovat summa (+),
980vähennys (-), kerto (\*), jako (/) ja jakojäännös (%). Aritmeettisista
981operaatioista puhutaan lisää muuttujien yhteydessä kohdassa 7.7.1.
982
983Keskimmäinen ympyrä tulee alimman ympyrän yläpuolelle niin, että ympyrät
950984sivuavat toisiaan. Keskimmäisen ympyrän keskipiste sijoittuu siis siten,
951että sen x-koordinaatti on 0 ja y-koordinaatti on <em>alimman ympyrän
952paikka</em> +<em>alimman ympyrän säde + keskimmäisen ympyrän säde</em>. Kun
985että sen x-koordinaatti on 0 ja y-koordinaatti on *alimman ympyrän
986paikka* +*alimman ympyrän säde + keskimmäisen ympyrän säde*. Kun
953987haluamme, että keskimmäisen ympyrän säde on 50, niin silloin
954988keskimmäisen ympyrän keskipiste tulee kohtaan (0, p1.Y + 100 + 50) ja se
955piirretään lauseella:</p>
956<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
989piirretään lauseella:
990
991``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
957992PhysicsObject p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
958993p2.Y = p1.Y + 100 + 50;
959Add(p2);</code></p>
960<p>Huomaa, että fysiikkaolion Y-ominaisuuden asettamisen (<em>set</em>) lisäksi
961voimme myös lukea tai pyytää (<em>get</em>) kyseisen ominaisuuden arvon. Yllä
994Add(p2);
995```
996
997Huomaa, että fysiikkaolion Y-ominaisuuden asettamisen (*set*) lisäksi
998voimme myös lukea tai pyytää (*get*) kyseisen ominaisuuden arvon. Yllä
962999teemme sen kirjoittamalla yksinkertaisesti sijoitusoperaattorin oikealle
963puolelle p1.Y.</p>
964<p>Seuraava kuva havainnollistaa ensimmäisen ja toisen pallon asettelua.</p>
965<p><img alt="\
1000puolelle p1.Y.
1001
1002Seuraava kuva havainnollistaa ensimmäisen ja toisen pallon asettelua.
1003
1004![\
9661005 Kuva 3: Lumiukon kaksi ensimmäistä palloa asemoituina
967paikoilleen." src="../src/luentomonistecsUusin_htm_m58b94a29.png" /></p>
968<p>\
1006paikoilleen.](../src/luentomonistecsUusin_htm_m58b94a29.png)
1007
1008\
9691009 \
970 \</p>
971<p>Ylin ympyrä sivuaa sitten taas keskimmäistä ympyrää. Harjoitustehtäväksi
972jätetään laskea ylimmän ympyrän koordinaatit, kun ympyrän säde on 30.</p>
973<p>Kaikki tiedot luokista, luokkien metodeista sekä siitä mitä parametreja
1010 \
1011
1012Ylin ympyrä sivuaa sitten taas keskimmäistä ympyrää. Harjoitustehtäväksi
1013jätetään laskea ylimmän ympyrän koordinaatit, kun ympyrän säde on 30.
1014
1015Kaikki tiedot luokista, luokkien metodeista sekä siitä mitä parametreja
9741016metodeille tulee antaa löydät käyttämäsi kirjaston dokumentaatiosta.
9751017Jypelin luokkadokumentaatio löytyy osoitteesta:
976<a href="http://kurssit.it.jyu.fi/npo/material/latest/documentation/html/">http://kurssit.it.jyu.fi/npo/material/latest/documentation/html/</a>.</p>
977<h2>4.4 Harjoitus</h2>
978<p>Etsi Jypeli-kirjaston dokumentaatiosta RandomGen-luokka. Mitä tietoa
1018[http://kurssit.it.jyu.fi/npo/material/latest/documentation/html/](http://kurssit.it.jyu.fi/npo/material/latest/documentation/html/).
1019
10204.4 Harjoitus
1021-------------
1022
1023Etsi Jypeli-kirjaston dokumentaatiosta RandomGen-luokka. Mitä tietoa
9791024löydät NextInt(int min, int max)-metodista? Mitä muita metodeja luokassa
980on?</p>
981<h2>4.5 Kääntäminen ja luokkakirjastoihin viittaaminen</h2>
982<p>Jotta Lumiukko-esimerkkiohjelma voitaisiin nyt kääntää C#-kääntäjällä,
1025on?
1026
10274.5 Kääntäminen ja luokkakirjastoihin viittaaminen
1028--------------------------------------------------
1029
1030Jotta Lumiukko-esimerkkiohjelma voitaisiin nyt kääntää C\#-kääntäjällä,
9831031tulee Jypeli-kirjasto olla tallennettuna tietokoneelle. Jypeli käyttää
9841032XNA-kirjaston lisäksi vapaan lähdekoodin fysiikka- ja
9851033matematiikkakirjastoja. Fysiikka- ja matematiikkakirjastot on
986sisäänrakennettuina Jypeli-kirjastoon.</p>
987<p>Ennen kääntämistä kopioi seuraavat tiedostot kurssin kotisivuilta
988(<a href="https://trac.cc.jyu.fi/projects/ohj1/wiki/csharpCommandLine">https://trac.cc.jyu.fi/projects/ohj1/wiki/csharpCommandLine</a>)
989samaan kansioon Lumiukko.cs-tiedoston kanssa.</p>
990<ul>
991<li>Jypeli.dll</li>
992</ul>
993<p>Meidän täytyy vielä välittää kääntäjälle tieto siitä, että
1034sisäänrakennettuina Jypeli-kirjastoon.
1035
1036Ennen kääntämistä kopioi seuraavat tiedostot kurssin kotisivuilta
1037([https://trac.cc.jyu.fi/projects/ohj1/wiki/csharpCommandLine](https://trac.cc.jyu.fi/projects/ohj1/wiki/csharpCommandLine))
1038samaan kansioon Lumiukko.cs-tiedoston kanssa.
1039
1040- Jypeli.dll
1041
1042Meidän täytyy vielä välittää kääntäjälle tieto siitä, että
9941043Jypeli-kirjastoa tarvitaan Lumiukko-koodin kääntämiseen. Lisäksi
995annetaan kääntäjälle tieto siitä, että ohjelma tehdään <em>32-bittisille</em>
1044annetaan kääntäjälle tieto siitä, että ohjelma tehdään *32-bittisille*
9961045järjestelmille (x86). Tämä tehdään csc-ohjelman
997<code>/reference</code>{.terminaali-western}-parametrin avulla. Lisäksi tarvitaan
1046`/reference`{.terminaali-western}-parametrin avulla. Lisäksi tarvitaan
9981047referenssi Jypelin käyttämään XNA-kirjastoon. Kirjoita nyt
9991048komentoriville(kaikki rivit samalle riville niin, että /-viivan edessä
1000on yksi välilyönti)</p>
1001<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1002csc Lumiukko.cs /reference:Jypeli.dll;"%XNAGSv4%\References\Windows\x86\Microsoft.Xna.Framework.Game.dll" /platform:x86</code></p>
1003<p>Jos käyttöjärjestelmäsi ei tunnista csc-komentoa, niin kertaa luvussa 2
1049on yksi välilyönti)
1050
1051``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1052csc Lumiukko.cs /reference:Jypeli.dll;"%XNAGSv4%\References\Windows\x86\Microsoft.Xna.Framework.Game.dll" /platform:x86
1053```
1054
1055Jos käyttöjärjestelmäsi ei tunnista csc-komentoa, niin kertaa luvussa 2
10041056olevat ohjeet komennon asettamisesta
1005<code>PATH</code>{.terminaali-western}-ympäristömuuttujan poluksi.</p>
1006<p>Vinkki! Yllä esitelty kääntämiskomento on varsin pitkä. Asioiden
1057`PATH`{.terminaali-western}-ympäristömuuttujan poluksi.
1058
1059Vinkki! Yllä esitelty kääntämiskomento on varsin pitkä. Asioiden
10071060helpottamiseksi voit kirjoittaa tiedoston csk.bat, joka sisältää
10081061seuraavan tekstin (komento on yksi pitkä rivi):\
10091062 \
1010@"%WINDIR%\Microsoft.NET\Framework\v4.0.30319\csc" %*
1011/reference:Jypeli.dll;"%XNAGSv4%References\Windows\x86\Microsoft.Xna.Framework.Game.dll";"%XNAGSv4%References\Windows\x86\Microsoft.Xna.Framework.dll"
1063@"%WINDIR%\\Microsoft.NET\\Framework\\v4.0.30319\\csc" %\*
1064/reference:Jypeli.dll;"%XNAGSv4%References\\Windows\\x86\\Microsoft.Xna.Framework.Game.dll";"%XNAGSv4%References\\Windows\\x86\\Microsoft.Xna.Framework.dll"
10121065/platform:x86 /define:WINDOWS\
10131066 \
10141067Tämä asettaa puolestasi reference ja platform -parametrit. Varmista,
10151068että tekemäsi csk.bat-tiedosto on ”polussa”. Tämän jälkeen kääntäminen
1016onnistuu yksinkertaisemmin: csk OhjelmanNimi.cs</p>
1017<h1>5. Lähdekoodista prosessorille</h1>
1018<h2>5.1 Kääntäminen</h2>
1019<p>Tarkastellaan nyt tarkemmin sitä kuinka C#-lähdekoodi muuttuu lopulta
1069onnistuu yksinkertaisemmin: csk OhjelmanNimi.cs
1070
10715. Lähdekoodista prosessorille
1072==============================
1073
10745.1 Kääntäminen
1075---------------
1076
1077Tarkastellaan nyt tarkemmin sitä kuinka C\#-lähdekoodi muuttuu lopulta
10201078prosessorin ymmärtämään muotoon. Kun ohjelmoija luo ohjelman
1021lähdekoodin, joka käyttää <em>.NET Framework</em> -ympäristöä, tapahtuu
1079lähdekoodin, joka käyttää *.NET Framework* -ympäristöä, tapahtuu
10221080kääntäminen sisäisesti kahdessa vaiheessa. Ohjelma käännetään ensin
1023eräänlaiselle välikielelle, <em>MSIL</em>:lle (Microsoft Intermediate
1081eräänlaiselle välikielelle, *MSIL*:lle (Microsoft Intermediate
10241082Language), joka ei ole vielä suoritettavissa millään
10251083käyttöjärjestelmällä. Tästä välivaiheen koodista käännetään ajon aikana
10261084valmis ohjelma halutulle käyttöjärjestelmälle, kuten Mac Os X:lle tai
1027Linuxille, niin sanotulla <em>JIT-kääntäjällä</em> (Just-In-Time). JIT-kääntäjä
1085Linuxille, niin sanotulla *JIT-kääntäjällä* (Just-In-Time). JIT-kääntäjä
10281086muuntaa välivaiheen koodin juuri halutulle käyttöjärjestelmälle
10291087sopivaksi koodiksi nimenomaan ohjelmaa ajettaessa - tästä tulee nimi
1030”just-in-time”.</p>
1031<p>Ennen ensimmäistä kääntämistä kääntäjä tarkastaa, että koodi on
1032syntaksiltaan oikein. [VES][KOS]</p>
1033<p>Kääntäminen tehtiin Windowsissa komentorivillä (Command Prompt)
1034käyttämällä komentoa</p>
1035<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1036csc Tiedostonnimi.cs</code></p>
1037<p>tai hyödyntämällä edellisessä luvussa esiteltyä komentojonoa</p>
1038<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1039csk Tiedostonnimi.cs</code></p>
1040<h2>5.2 Suorittaminen</h2>
1041<p>C#:n tuottaa siis lähdekoodista suoritettavan (tai ”ajettavan”)
1088”just-in-time”.
1089
1090Ennen ensimmäistä kääntämistä kääntäjä tarkastaa, että koodi on
1091syntaksiltaan oikein. [VES][KOS]
1092
1093Kääntäminen tehtiin Windowsissa komentorivillä (Command Prompt)
1094käyttämällä komentoa
1095
1096``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1097csc Tiedostonnimi.cs
1098```
1099
1100tai hyödyntämällä edellisessä luvussa esiteltyä komentojonoa
1101
1102``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1103csk Tiedostonnimi.cs
1104```
1105
11065.2 Suorittaminen
1107-----------------
1108
1109C\#:n tuottaa siis lähdekoodista suoritettavan (tai ”ajettavan”)
10421110tiedoston. Tämä tiedosto on käyttöjärjestelmäriippuvainen, ja
10431111suoritettavissa vain sillä alustalla, johon käännös on tehty. Toisin
10441112sanoen, Windows-ympäristössä käännetyt ohjelmat eivät ole ajettavissa OS
1045X -käyttöjärjestelmässä, ja toisin päin.</p>
1046<p>Toisin kuin C#, eräät toiset ohjelmointikielet tuottavat
1047käyttöjärjestelmäriippumatonta koodia. Esimerkiksi <em>Java</em>-kielessä
1048kääntäjän tuottama tiedosto on niin sanottua <em>tavukoodia</em>, joka on
1113X -käyttöjärjestelmässä, ja toisin päin.
1114
1115Toisin kuin C\#, eräät toiset ohjelmointikielet tuottavat
1116käyttöjärjestelmäriippumatonta koodia. Esimerkiksi *Java*-kielessä
1117kääntäjän tuottama tiedosto on niin sanottua *tavukoodia*, joka on
10491118käyttöjärjestelmäriippumatonta koodia. Tavukoodin suorittamiseen
10501119tarvitaan Java-virtuaalikone (Java Virtual Machine). Java-virtuaalikone
10511120on oikeaa tietokonetta matkiva ohjelma, joka tulkkaa tavukoodia ja
10521121suorittaa sitä sitten kohdekoneen prosessorilla. Tässä on merkittävä ero
10531122perinteisiin käännettäviin kieliin (esimerkiksi C ja C++), joissa
1054käännös on tehtävä erikseen jokaiselle eri laitealustalle. [VES][KOS]</p>
1055<p>\
1056 \</p>
1057<h1>6. Aliohjelmat</h1>
1058<blockquote>
1059<p>“Copy and paste is a design error.” - David Parnas</p>
1060</blockquote>
1061<p>Pääohjelman lisäksi ohjelma voi sisältää muitakin aliohjelmia.
1062Aliohjelmaa <em>kutsutaan</em> pääohjelmasta, metodista tai toisesta
1123käännös on tehtävä erikseen jokaiselle eri laitealustalle. [VES][KOS]
1124
1125\
1126 \
1127
11286. Aliohjelmat
1129==============
1130
1131> “Copy and paste is a design error.” - David Parnas
1132
1133Pääohjelman lisäksi ohjelma voi sisältää muitakin aliohjelmia.
1134Aliohjelmaa *kutsutaan* pääohjelmasta, metodista tai toisesta
10631135aliohjelmasta suorittamaan tiettyä tehtävää. Aliohjelmat voivat saada
10641136parametreja ja palauttaa arvon, kuten metoditkin. Pohditaan seuraavaksi
1065mihin aliohjelmia tarvitaan.</p>
1066<p>Jos tehtävänämme olisi piirtää useampi lumiukko, niin tämänhetkisellä
1137mihin aliohjelmia tarvitaan.
1138
1139Jos tehtävänämme olisi piirtää useampi lumiukko, niin tämänhetkisellä
10671140tietämyksellämme tekisimme todennäköisesti jonkin alla olevan kaltaisen
1068ratkaisun.</p>
1069<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1141ratkaisun.
1142
1143``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1070114401 using Jypeli;
1071114502
107203 /// &lt;summary&gt;
114603 /// <summary>
1073114704 /// Piirretään lumiukko.
107405 /// &lt;/summary&gt;
114805 /// </summary>
1075114906 public class Lumiukko : PhysicsGame
1076115007 {
107708 /// &lt;summary&gt;
115108 /// <summary>
1078115209 /// Pääohjelmassa peli käyntiin.
107910 /// &lt;/summary&gt;
108011 /// &lt;param name="args"&gt;Ei käytössä.&lt;/param&gt;
115310 /// </summary>
115411 /// <param name="args">Ei käytössä.</param>
1081115512 public static void Main(String[] args)
1082115613 {
1083115714 using (Lumiukko game = new Lumiukko())
1160116017 }
1161116118 }
1162116219
116320 /// &lt;summary&gt;
116320 /// <summary>
1164116421 /// Aliohjelma, jossa
1165116522 /// piirretään ympyrät.
116623 /// &lt;/summary&gt;
116623 /// </summary>
1167116724 public override void Begin()
1168116825 {
1169116926 Camera.ZoomToLevel();
1200120057 p3.Y = p2.Y + 50 + 30;
1201120158 Add(p3);
1202120259 }
120360 }</code></p>
1204<p>Huomataan, että ensimmäisen ja toisen lumiukon piirtäminen tapahtuu
120360 }
1204```
1205
1206Huomataan, että ensimmäisen ja toisen lumiukon piirtäminen tapahtuu
12051207lähes samanlaisilla koodinpätkillä. Itse asiassa ainoa ero on, että
12061208jälkimmäisen lumiukon pallot saavat ensimmäisestä lumiukosta eroavat
12071209koordinaatit. Toisaalta voisimme kirjoittaa koodin myös niin, että
1208lumiukon alimman pallon keskipiste tallennetaan <em>muuttujiin</em> x ja y.
1210lumiukon alimman pallon keskipiste tallennetaan *muuttujiin* x ja y.
12091211Näiden pisteiden avulla voimme sitten laskea muiden pallojen paikat.
12101212Määritellään heti alussa myös p1, p2 ja p3 PhysicsObject-olioiksi.
12111213Rivinumerointi on tässä jätetty pois selvyyden vuoksi. Luvun lopussa
1212korjattu ohjelma esitellään kokonaisuudessaan rivinumeroinnin kanssa.</p>
1213<p>``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1214korjattu ohjelma esitellään kokonaisuudessaan rivinumeroinnin kanssa.
1215
1216``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
12141217double x, y;
1215PhysicsObject p1, p2, p3;</p>
1216<p>// Tehdään ensimmäinen lumiukko
1218PhysicsObject p1, p2, p3;
1219
1220// Tehdään ensimmäinen lumiukko
12171221x = 0; y = Level.Bottom + 200.0;
1218p1 = new PhysicsObject(2<em>100.0, 2</em>100.0, Shape.Circle);
1222p1 = new PhysicsObject(2*100.0, 2*100.0, Shape.Circle);
12191223p1.X = x;
12201224p1.Y = y;
1221Add(p1);</p>
1222<p>p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
1225Add(p1);
1226
1227p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
12231228p2.X = x;
12241229p2.Y = y + 100 + 50; // y + 1. pallon säde + 2. pallon säde
1225Add(p2);</p>
1226<p>p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
1230Add(p2);
1231
1232p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
12271233p3.X = x;
12281234p3.Y = y + 100 + 2 * 50 + 30; // y + 1. pallon säde + 2. halk. + 3. säde
12291235Add(p3);
1230```</p>
1231<p>Vastaavasti toiselle lumiukolle: asetetaan vain x:n ja y:n arvot
1232oikeiksi.</p>
1233<p>``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1236```
1237
1238Vastaavasti toiselle lumiukolle: asetetaan vain x:n ja y:n arvot
1239oikeiksi.
1240
1241``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
12341242// Tehdään toinen lumiukko
12351243x = 200; y = Level.Bottom + 300.0;
12361244p1 = new PhysicsObject(2 * 100.0, 2 * 100.0, Shape.Circle);
12371245p1.X = x;
12381246p1.Y = y;
1239Add(p1);</p>
1240<p>p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
1247Add(p1);
1248
1249p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
12411250p2.X = x;
12421251p2.Y = y + 100 + 50;
1243Add(p2);</p>
1244<p>p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
1252Add(p2);
1253
1254p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
12451255p3.X = x;
12461256p3.Y = y + 100 + 2*50 + 30;
12471257Add(p3);
1248```</p>
1249<p>Tarkastellaan nyt muutoksia hieman tarkemmin.</p>
1250<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1251double x, y;</code></p>
1252<p>Yllä olevalla rivillä esitellään kaksi liukuluku<em>tyyppistä</em> <em>muuttujaa</em>.
1253Liukuluku on eräs tapa esittää <em>reaalilukuja</em> tietokoneissa. C#:ssa
1254jokaisella muuttujalla on oltava tyyppi ja eräs liukulukutyyppi C#:ssa
1255on double. Muuttujista ja niiden tyypeistä puhutaan lisää luvussa 7.</p>
1256<p><em>Liukuluku</em> (floating point) = Tietokoneissa käytettävä esitysmuoto
1257reaaliluvuille. Tarkempaa tietoa liukuluvuista löytyy luvusta 26.</p>
1258<p>\</p>
1259<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1260x = 0; y = Level.Bottom + 200.0;</code></p>
1261<p>Yllä olevalla rivillä on kaksi lausetta. Ensimmäisellä asetetaan
1258```
1259
1260Tarkastellaan nyt muutoksia hieman tarkemmin.
1261
1262``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1263double x, y;
1264```
1265
1266Yllä olevalla rivillä esitellään kaksi liukuluku*tyyppistä* *muuttujaa*.
1267Liukuluku on eräs tapa esittää *reaalilukuja* tietokoneissa. C\#:ssa
1268jokaisella muuttujalla on oltava tyyppi ja eräs liukulukutyyppi C\#:ssa
1269on double. Muuttujista ja niiden tyypeistä puhutaan lisää luvussa 7.
1270
1271*Liukuluku* (floating point) = Tietokoneissa käytettävä esitysmuoto
1272reaaliluvuille. Tarkempaa tietoa liukuluvuista löytyy luvusta 26.
1273
1274\
1275
1276``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1277x = 0; y = Level.Bottom + 200.0;
1278```
1279
1280Yllä olevalla rivillä on kaksi lausetta. Ensimmäisellä asetetaan
12621281muuttujaan x arvo 0 ja toisella muuttujaan y arvo 50 (jos Level.Bottom
12631282sattuu olemaan vaikka -150). Nyt voimme käyttää lumiukon pallojen
1264laskentaan näitä muuttujia.</p>
1265<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1266x = 300; y = Level.Bottom + 300.0;</code></p>
1267<p>Vastaavasti yllä olevalla rivillä asetetaan nyt muuttujiin uudet arvot,
1283laskentaan näitä muuttujia.
1284
1285``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1286x = 300; y = Level.Bottom + 300.0;
1287```
1288
1289Vastaavasti yllä olevalla rivillä asetetaan nyt muuttujiin uudet arvot,
12681290joita käytetään seuraavan lumiukon pallojen paikkojen laskemiseen.
12691291Huomaa, että y-koordinaatti saa negatiivisen arvon, jolloin lumiukon
1270alimman pallon keskipiste painuu kuvaruudun keskitason alapuolelle.</p>
1271<p>Nyt alimman pallon x-koordinaatiksi sijoitetaankin <em>muuttuja</em> x, ja
1272vastaavasti y-koordinaatin arvoksi asetetaan <em>muuttuja</em> y, ja muiden
1292alimman pallon keskipiste painuu kuvaruudun keskitason alapuolelle.
1293
1294Nyt alimman pallon x-koordinaatiksi sijoitetaankin *muuttuja* x, ja
1295vastaavasti y-koordinaatin arvoksi asetetaan *muuttuja* y, ja muiden
12731296pallojen sijainnit lasketaan ensimmäisen pallon koordinaattien
1274perusteella.</p>
1275<p><img alt="\
1297perusteella.
1298
1299![\
12761300 Kuva 4: Kaksi
1277lumiukkoa." src="../src/luentomonistecsUusin_htm_m12339dd1.png" /></p>
1278<p>\
1301lumiukkoa.](../src/luentomonistecsUusin_htm_m12339dd1.png)
1302
1303\
12791304 Näiden muutosten jälkeen molempien lumiukkojen varsinainen piirtäminen
1280tapahtuu nyt <strong>täysin samalla koodilla</strong>.</p>
1281<p>Uusien lumiukkojen piirtäminen olisi nyt jonkin verran helpompaa, sillä
1305tapahtuu nyt **täysin samalla koodilla**.
1306
1307Uusien lumiukkojen piirtäminen olisi nyt jonkin verran helpompaa, sillä
12821308meidän ei tarvitse kuin ilmoittaa ennen piirtämistä uuden lumiukon
12831309paikka ja varsinaisen lumiukkojen piirtäminen onnistuisi kopioimilla ja
12841310liittämällä koodia (copy-paste). Kuitenkin, jos koodia kirjoittaessa
12851311joutuu tekemään suoraa kopiointia, pitäisi pysähtyä miettimään, että
1286onko tässä mitään järkeä.</p>
1287<p>Kahden lumiukon tapauksessa tämä vielä onnistuu ilman, että koodin määrä
1312onko tässä mitään järkeä.
1313
1314Kahden lumiukon tapauksessa tämä vielä onnistuu ilman, että koodin määrä
12881315kasvaa kohtuuttomasti, mutta entä jos meidän pitäisi piirtää 10 tai 100
12891316lumiukkoa? Kuinka monta riviä ohjelmaan tulisi silloin? Kun lähes
12901317samanlainen koodinpätkä tulee useampaan kuin yhteen paikkaan, on
1291useimmiten syytä muodostaa siitä oma <em>aliohjelma</em>. Koodin monistaminen
1318useimmiten syytä muodostaa siitä oma *aliohjelma*. Koodin monistaminen
12921319moneen paikkaan lisäisi vain koodirivien määrää, tekisi ohjelman
1293ymmärtämisestä vaikeampaa ja vaikeuttaisi testaamista.</p>
1294<p>\
1295 \</p>
1296<p>Lisäksi jos monistetussa koodissa olisi vikaa, jouduttaisiin korjaukset
1320ymmärtämisestä vaikeampaa ja vaikeuttaisi testaamista.
1321
1322\
1323 \
1324
1325Lisäksi jos monistetussa koodissa olisi vikaa, jouduttaisiin korjaukset
12971326tekemään myös useampaan paikkaan. Hyvän ohjelman yksi mitta (kriteeri)
12981327onkin, että jos jotain pitää muuttaa, niin kohdistuvatko muutokset
12991328kohdistuvat vain yhteen paikkaan (hyvä) vai joudutaanko muutoksia
1300tekemään useaan paikkaan (huono).</p>
1301<h2>6.1 Aliohjelman kutsuminen</h2>
1302<p>Haluamme siis aliohjelman, joka piirtää meille lumiukon tiettyyn
1329tekemään useaan paikkaan (huono).
1330
13316.1 Aliohjelman kutsuminen
1332--------------------------
1333
1334Haluamme siis aliohjelman, joka piirtää meille lumiukon tiettyyn
13031335pisteeseen. Kuten metodeille, myös aliohjelmalle viedään parametrien
13041336avulla sen tarvitsemaa tietoa. Parametreina tulisi viedä vain
1305minimaaliset tiedot, joilla aliohjelman tehtävä saadaan suoritettua.</p>
1306<p>Sovitaan, että aliohjelmamme piirtää aina samankokoisen lumiukon
1337minimaaliset tiedot, joilla aliohjelman tehtävä saadaan suoritettua.
1338
1339Sovitaan, että aliohjelmamme piirtää aina samankokoisen lumiukon
13071340haluamaamme pisteeseen. Mitkä ovat ne välttämättömät tiedot, jotka
1308aliohjelma tarvitsee piirtääkseen lumiukon?</p>
1309<p>Aliohjelma tarvitsee tiedon <em>mihin</em> pisteeseen lumiukko piirretään.
1341aliohjelma tarvitsee piirtääkseen lumiukon?
1342
1343Aliohjelma tarvitsee tiedon *mihin* pisteeseen lumiukko piirretään.
13101344Viedään siis parametrina lumiukon alimman pallon keskipiste. Muiden
13111345pallojen paikat voidaan laskea tämän pisteen avulla. Lisäksi tarvitaan
13121346yksi Game-tyyppinen parametri, jotta aliohjelmaamme voisi kutsua myös
1313toisesta ohjelmasta. Nämä parametrit riittävät lumiukon piirtämiseen.</p>
1314<p>Kun aliohjelmaa käytetään ohjelmassa, sanotaan, että aliohjelmaa
1315<em>kutsutaan</em>. Kutsu tapahtuu kirjoittamalla aliohjelman nimi ja antamalla
1347toisesta ohjelmasta. Nämä parametrit riittävät lumiukon piirtämiseen.
1348
1349Kun aliohjelmaa käytetään ohjelmassa, sanotaan, että aliohjelmaa
1350*kutsutaan*. Kutsu tapahtuu kirjoittamalla aliohjelman nimi ja antamalla
13161351sille parametrit. Aliohjelmakutsun erottaa metodikutsusta vain se, että
13171352metodi liittyy aina tiettyyn olioon. Esimerkiksi pallo-olio p1
13181353voitaisiin poistaa pelikentällä kutsumalla metodia Destroy(), eli
1319kirjoittaisimme:</p>
1320<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1321p1.Destroy();</code></p>
1322<p>Toisin sanoen metodeja kutsuttaessa täytyy ensin kirjoittaa sen olion
1354kirjoittaisimme:
1355
1356``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1357p1.Destroy();
1358```
1359
1360Toisin sanoen metodeja kutsuttaessa täytyy ensin kirjoittaa sen olion
13231361nimi, jonka metodia kutsutaan, ja sen jälkeen pisteellä erotettuna
13241362kirjoittaa haluttu metodin nimi. Sulkujen sisään tulee luonnollisesti
13251363tarvittavat parametrit. Yllä olevan esimerkin Destroy-metodi ei ota
1326vastaan yhtään parametria.</p>
1327<p>Päätetään, että aliohjelman nimi on PiirraLumiukko. Sovitaan myös, että
1364vastaan yhtään parametria.
1365
1366Päätetään, että aliohjelman nimi on PiirraLumiukko. Sovitaan myös, että
13281367aliohjelman ensimmäinen parametri on tämä peli, johon lumiukko ilmestyy
13291368(kirjoitetaan this). Toinen parametri on lumiukon alimman pallon
13301369keskipisteen x-koordinaatti ja kolmas parametri lumiukon alimman pallon
13311370keskipisteen y-koordinaatti. Tällöin kentälle voitaisiin piirtää
13321371lumiukko, jonka alimman pallon keskipiste on (0, Level.Bottom + 200.0),
1333seuraavalla kutsulla:</p>
1334<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1335PiirraLumiukko(this, 0, Level.Bottom + 200.0);</code></p>
1336<p>Kutsussa voisi myös ensiksi mainita sen luokan nimen mistä aliohjelma
1372seuraavalla kutsulla:
1373
1374``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1375PiirraLumiukko(this, 0, Level.Bottom + 200.0);
1376```
1377
1378Kutsussa voisi myös ensiksi mainita sen luokan nimen mistä aliohjelma
13371379löytyy. Tällä kutsulla aliohjelmaa voisi kutsua myös muista luokista,
1338koska määrittelimme Lumiukot-luokan julkiseksi (public).</p>
1339<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1340Lumiukot.PiirraLumiukko(this, 0, Level.Bottom + 200.0);</code></p>
1341<p>Vaikka tämä muoto muistuttaa jo melko paljon metodin kutsua on ero
1342kuitenkin selvä. Metodia kutsuttaessa toimenpide tehdään aina <em>tietylle
1343oliolle</em>, kuten p1.Destroy() tuhoaa juuri sen pallon, johon p1-olio
1380koska määrittelimme Lumiukot-luokan julkiseksi (public).
1381
1382``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1383Lumiukot.PiirraLumiukko(this, 0, Level.Bottom + 200.0);
1384```
1385
1386Vaikka tämä muoto muistuttaa jo melko paljon metodin kutsua on ero
1387kuitenkin selvä. Metodia kutsuttaessa toimenpide tehdään aina *tietylle
1388oliolle*, kuten p1.Destroy() tuhoaa juuri sen pallon, johon p1-olio
13441389viittaa. Pallojahan voi tietenkin olla myös muita erinimisiä (kuten
13451390esimerkissämme onkin). Alla olevassa aliohjelmakutsussa kuitenkin
1346käytetään vain luokasta Lumiukot löytyvää PiirraLumiukko-aliohjelmaa.</p>
1347<p>Jos olisimme toteuttaneet jo varsinaisen aliohjelman, piirtäisi Begin
1348meille nyt kaksi lumiukkoa.</p>
1349<p>``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1391käytetään vain luokasta Lumiukot löytyvää PiirraLumiukko-aliohjelmaa.
1392
1393Jos olisimme toteuttaneet jo varsinaisen aliohjelman, piirtäisi Begin
1394meille nyt kaksi lumiukkoa.
1395
1396``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
13501397/// <summary>
13511398/// Kutsutaan PiirraLumiukko-aliohjelmaa
13521399/// sopivilla parametreilla.
14011401public override void Begin()
14021402{
14031403 Camera.ZoomToLevel();
1404 Level.Background.Color = Color.Black;</p>
1405<p>PiirraLumiukko(this, 0, Level.Bottom + 200.0);
1404 Level.Background.Color = Color.Black;
1405
1406 PiirraLumiukko(this, 0, Level.Bottom + 200.0);
14061407 PiirraLumiukko(this, 200.0, Level.Bottom + 300.0);
14071408}
1408```</p>
1409<p>Koska PiirraLumiukko-aliohjelmaa ei luonnollisesti vielä ole olemassa,
1409```
1410
1411Koska PiirraLumiukko-aliohjelmaa ei luonnollisesti vielä ole olemassa,
14101412ei ohjelmamme vielä toimi. Seuraavaksi meidän täytyy toteuttaa itse
1411aliohjelma, jotta kutsut alkavat toimimaan.</p>
1412<p>Usein ohjelman toteutuksessa on viisasta edetä juuri tässä
1413aliohjelma, jotta kutsut alkavat toimimaan.
1414
1415Usein ohjelman toteutuksessa on viisasta edetä juuri tässä
14131416järjestyksessä: suunnitellaan aliohjelmakutsu ensiksi, kirjoitetaan
14141417kutsu sille kuuluvalle paikalle, ja vasta sitten toteutetaan varsinainen
1415aliohjelman kirjoittaminen.</p>
1416<p>Lisätietoja aliohjelmien kutsumisesta löydät kurssin wiki-sivulta:
1417<a href="https://trac.cc.jyu.fi/projects/ohj1/wiki/aliohjelmienKutsuminen">https://trac.cc.jyu.fi/projects/ohj1/wiki/aliohjelmienKutsuminen</a>.</p>
1418<h2>6.2 Aliohjelman kirjoittaminen</h2>
1419<p>Ennen varsinaista aliohjelman toiminnallisuuden kirjoittamista täytyy
1418aliohjelman kirjoittaminen.
1419
1420Lisätietoja aliohjelmien kutsumisesta löydät kurssin wiki-sivulta:
1421[https://trac.cc.jyu.fi/projects/ohj1/wiki/aliohjelmienKutsuminen](https://trac.cc.jyu.fi/projects/ohj1/wiki/aliohjelmienKutsuminen).
1422
14236.2 Aliohjelman kirjoittaminen
1424------------------------------
1425
1426Ennen varsinaista aliohjelman toiminnallisuuden kirjoittamista täytyy
14201427aliohjelmalle tehdä määrittely (kutsutaan myös esittelyksi,
14211428declaration). Kirjoitetaan määrittely aliohjelmalle, jonka kutsun jo
1422teimme edellisessä alaluvussa.</p>
1423<p>Lisätään ohjelmaamme aliohjelman runko. Dokumentoidaan aliohjelma myös
1424saman tien.</p>
1425<p>``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1429teimme edellisessä alaluvussa.
1430
1431Lisätään ohjelmaamme aliohjelman runko. Dokumentoidaan aliohjelma myös
1432saman tien.
1433
1434``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
14261435/// <summary>
14271436/// Kutsutaan PiirraLumiukko-aliohjelmaa
14281437/// sopivilla parametreilla.
14391439public override void Begin()
14401440{
14411441 Camera.ZoomToLevel();
1442 Level.Background.Color = Color.Black;</p>
1443<p>PiirraLumiukko(this, 0, Level.Bottom + 200.0);
1442 Level.Background.Color = Color.Black;
1443
1444 PiirraLumiukko(this, 0, Level.Bottom + 200.0);
14441445 PiirraLumiukko(this, 200.0, Level.Bottom + 300.0);
1445}</p>
1446<p>/// <summary>
1446}
1447
1448/// <summary>
14471449/// Aliohjelma piirtää lumiukon
14481450/// annettuun paikkaan.
14491451/// </summary>
14551455public static void PiirraLumiukko(Game peli, double x, double y)
14561456{
14571457}
1458```</p>
1459<p>Alla oleva kuva selvittää aliohjelmakutsun ja aliohjelman määrittelyn
1460sekä vastinparametrien yhteyttä.</p>
1461<p><img alt="\
1458```
1459
1460Alla oleva kuva selvittää aliohjelmakutsun ja aliohjelman määrittelyn
1461sekä vastinparametrien yhteyttä.
1462
1463![\
14621464 Kuva 5: Aliohjelmakutsu ja aliohjelman
1463vastinparametrit." src="../src/luentomonistecsUusin_htm_m48da2e91.png" /></p>
1464<p>\
1465 Aliohjelman toteutuksen ensimmäistä riviä</p>
1466<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1467public static void PiirraLumiukko(Game peli, double x, double y)</code></p>
1468<p>sanotaan aliohjelman <em>otsikoksi</em> (header) tai <em>esittelyriviksi</em>. Otsikon
1469alussa määritellään aliohjelman <em>näkyvyys</em> julkiseksi (public). Kun
1465vastinparametrit.](../src/luentomonistecsUusin_htm_m48da2e91.png)
1466
1467\
1468 Aliohjelman toteutuksen ensimmäistä riviä
1469
1470``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1471public static void PiirraLumiukko(Game peli, double x, double y)
1472```
1473
1474sanotaan aliohjelman *otsikoksi* (header) tai *esittelyriviksi*. Otsikon
1475alussa määritellään aliohjelman *näkyvyys* julkiseksi (public). Kun
14701476näkyvyys on julkinen, niin aliohjelmaa voidaan kutsua eli käyttää myös
14711477muissa luokissa. Aliohjelma määritellään myös staattiseksi (static),
14721478sillä jos emme määrittelisi aliohjelmaa staattiseksi, olisi se
14731479oikeastaan metodi, eli olion toiminto (ks. luku 8.5). Statttinen
14741480aliohjelma pystyy tekemään kaikki toimensa parametreinä tuodun tiedon
1475perusteella.</p>
1476<p>Aliohjelmalle on annettu myös palautusarvoksi void, joka tarkoittaa
1481perusteella.
1482
1483Aliohjelmalle on annettu myös palautusarvoksi void, joka tarkoittaa
14771484sitä, että aliohjelma ei palauta mitään arvoa. Aliohjelma voisi
14781485nimittäin myös lopettaessaan palauttaa jonkun arvon, jota tarvitsisimme
14791486ohjelmassamme. Tällaisista aliohjelmista puhutaan luvussa 9.
14801487void-määrityksen jälkeen aliohjelmalle on annettu nimeksi
1481PiirraLumiukko.</p>
1482<p>Huomaa! C#:ssa aliohjelmat kirjoitetaan tyypillisesti isolla
1483alkukirjaimella.</p>
1484<p>\</p>
1485<p>Huomaa! Aliohjelmien (ja metodien) nimien tulisi olla verbejä tai
1488PiirraLumiukko.
1489
1490Huomaa! C\#:ssa aliohjelmat kirjoitetaan tyypillisesti isolla
1491alkukirjaimella.
1492
1493\
1494
1495Huomaa! Aliohjelmien (ja metodien) nimien tulisi olla verbejä tai
14861496tekemistä ilmaisevia lauseita, esimerkiksi LuoPallo, Siirry,
1487TormattiinEsteeseen.</p>
1488<p>Aliohjelman nimen jälkeen ilmoitetaan sulkeiden sisässä aliohjelman
1497TormattiinEsteeseen.
1498
1499Aliohjelman nimen jälkeen ilmoitetaan sulkeiden sisässä aliohjelman
14891500parametrit. Jokaista parametria ennen on ilmoitettava myös parametrin
1490<em>tietotyyppi</em>. Parametrinä annettiin lumiukon alimman pallon x- ja
1501*tietotyyppi*. Parametrinä annettiin lumiukon alimman pallon x- ja
14911502y-koordinaatit. Molempien tietotyyppi on double, joten myös
14921503vastinparametrien tyyppien tulee olla double. Annetaan myös nimet
1493kuvaavasti x ja y.</p>
1494<p>Tietotyypeistä voit lukea lisää kohdasta 7.2 ja luvusta 8.</p>
1495<p>Huomaa! Aliohjelman parametrien nimien ei tarvitse olla samoja kuin
1496kutsussa. Niiden nimet kannattaa kuitenkin olla mahdollisimman kuvaavia.</p>
1497<p>\</p>
1498<p>Huomaa! Parametrien tyyppien ei tarvitse olla keskenään samoja, kunhan
1504kuvaavasti x ja y.
1505
1506Tietotyypeistä voit lukea lisää kohdasta 7.2 ja luvusta 8.
1507
1508Huomaa! Aliohjelman parametrien nimien ei tarvitse olla samoja kuin
1509kutsussa. Niiden nimet kannattaa kuitenkin olla mahdollisimman kuvaavia.
1510
1511\
1512
1513Huomaa! Parametrien tyyppien ei tarvitse olla keskenään samoja, kunhan
14991514kukin parametri on yhteensopiva kutsussa olevan vastinparametrin kanssa.
15001515Esimerkkejä funktioista löydät kurssin wiki-sivulta:
1501<a href="https://trac.cc.jyu.fi/projects/ohj1/wiki/aliohjelmienKirjoittaminen">https://trac.cc.jyu.fi/projects/ohj1/wiki/aliohjelmienKirjoittaminen</a>.</p>
1502<p>\</p>
1503<p>Aliohjelmakutsulla ja aliohjelman määrittelyllä on siis hyvin vahva
1516[https://trac.cc.jyu.fi/projects/ohj1/wiki/aliohjelmienKirjoittaminen](https://trac.cc.jyu.fi/projects/ohj1/wiki/aliohjelmienKirjoittaminen).
1517
1518\
1519
1520Aliohjelmakutsulla ja aliohjelman määrittelyllä on siis hyvin vahva
15041521yhteys keskenään. Aliohjelmakutsussa annetut tiedot ”sijoitetaan”
15051522kullakin kutsukerralla aliohjelman määrittelyrivillä esitellyille
15061523vastinparametreille. Toisin sanoen, aliohjelmakutsun yhteydessä tapahtuu
1507väljästi sanottuna seuraavaa.</p>
1508<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1524väljästi sanottuna seuraavaa.
1525
1526``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
15091527aliohjelman Game = this;
15101528aliohjelman x = 200.0;
1511aliohjelman y = Level.Bottom + 300;</code></p>
1512<p>Voimme nyt kokeilla ajaa ohjelmaamme. Se toimii (lähtee käyntiin), mutta
1529aliohjelman y = Level.Bottom + 300;
1530```
1531
1532Voimme nyt kokeilla ajaa ohjelmaamme. Se toimii (lähtee käyntiin), mutta
15131533ei tietenkään vielä piirrä lumiukkoja, eikä pitäisikään, sillä luomamme
15141534aliohjelma on ”tyhjä”. Lisätään aaltosulkujen väliin varsinainen koodi,
1515joka pallojen piirtämiseen tarvitaan.</p>
1516<p>Pieni muutos aikaisempaan versioon kuitenkin tarvitaan. Rivit, joilla
1517pallot lisätään kentälle, muutetaan muotoon</p>
1518<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1519peli.Add(...);</code></p>
1520<p>missä pisteiden paikalle tulee pallo-olion muuttujan nimi.</p>
1521<p>``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1535joka pallojen piirtämiseen tarvitaan.
1536
1537Pieni muutos aikaisempaan versioon kuitenkin tarvitaan. Rivit, joilla
1538pallot lisätään kentälle, muutetaan muotoon
1539
1540``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1541peli.Add(...);
1542```
1543
1544missä pisteiden paikalle tulee pallo-olion muuttujan nimi.
1545
1546``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
15221547/// <summary>
15231548/// Kutsutaan PiirraLumiukko-aliohjelmaa
15241549/// sopivilla parametreilla.
15511551public override void Begin()
15521552{
15531553 Camera.ZoomToLevel();
1554 Level.Background.Color = Color.Black;</p>
1555<p>PiirraLumiukko(this, 0, Level.Bottom + 200.0);
1554 Level.Background.Color = Color.Black;
1555
1556 PiirraLumiukko(this, 0, Level.Bottom + 200.0);
15561557 PiirraLumiukko(this, 200.0, Level.Bottom + 300.0);
1557}</p>
1558<p>/// <summary>
1558}
1559
1560/// <summary>
15591561/// Aliohjelma piirtää lumiukon
15601562/// annettuun paikkaan.
15611563/// </summary>
15701570 p1 = new PhysicsObject(2 * 100.0, 2 * 100.0, Shape.Circle);
15711571 p1.X = x;
15721572 p1.Y = y;
1573 peli.Add(p1);</p>
1574<p>p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
1573 peli.Add(p1);
1574
1575 p2 = new PhysicsObject(2 * 50.0, 2 * 50.0, Shape.Circle);
15751576 p2.X = x;
15761577 p2.Y = p1.Y + 100 + 50;
1577 peli.Add(p2);</p>
1578<p>p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
1578 peli.Add(p2);
1579
1580 p3 = new PhysicsObject(2 * 30.0, 2 * 30.0, Shape.Circle);
15791581 p3.X = x;
15801582 p3.Y = p2.Y + 50 + 30;
15811583 peli.Add(p3);
15821584}
1583```</p>
1584<p>Varsinaista aliohjelman toiminnallisuutta kirjoittaessa käytämme nyt
1585```
1586
1587Varsinaista aliohjelman toiminnallisuutta kirjoittaessa käytämme nyt
15851588parametreille antamiamme nimiä. Alimman ympyrän keskipisteen
15861589koordinaatit saamme nyt suoraan parametreista x ja y, mutta muiden
15871590ympyröiden keskipisteet meidän täytyy laskea alimman ympyrän
15881591koordinaateista. Tämä tapahtuu täysin samalla tavalla kuin edellisessä
15891592esimerkissä. Itse asiassa, jos vertaa aliohjelman sisältöä edellisen
1590esimerkin koodiin, on se täysin sama.</p>
1591<p>C#:ssa on tapana aloittaa aliohjelmien ja metodien nimet isolla
1593esimerkin koodiin, on se täysin sama.
1594
1595C\#:ssa on tapana aloittaa aliohjelmien ja metodien nimet isolla
15921596kirjaimella ja nimessä esiintyvä jokainen uusi sana alkamaan isolla
15931597kirjaimella. Kirjoitustavasta käytetään termiä PascalCasing. Muuttujat
15941598kirjoitetaan pienellä alkukirjaimella, ja jokainen seuraava sana isolla
15951599alkukirjaimella: esimerkiksi double autonNopeus. Tästä käytetään nimeä
1596camelCasing. Lisää C#:n nimeämiskäytännöistä voit lukea sivulta</p>
1597<p><a href="http://msdn.microsoft.com/en-us/library/ms229043.aspx">http://msdn.microsoft.com/en-us/library/ms229043.aspx</a>.</p>
1598<p>Tarkastellaan seuraavaksi mitä aliohjelmakutsussa tapahtuu.</p>
1599<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1600PiirraLumiukko(this, 0, Level.Bottom + 200.0);</code></p>
1601<p>Yllä olevalla kutsulla aliohjelman peli-nimiseen muuttujaan sijoitetaan
1600camelCasing. Lisää C\#:n nimeämiskäytännöistä voit lukea sivulta
1601
1602[http://msdn.microsoft.com/en-us/library/ms229043.aspx](http://msdn.microsoft.com/en-us/library/ms229043.aspx).
1603
1604Tarkastellaan seuraavaksi mitä aliohjelmakutsussa tapahtuu.
1605
1606``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1607PiirraLumiukko(this, 0, Level.Bottom + 200.0);
1608```
1609
1610Yllä olevalla kutsulla aliohjelman peli-nimiseen muuttujaan sijoitetaan
16021611this, eli kyseessä oleva peli, x-nimiseen muuttujaan sijoitetaan arvo 0
16031612(liukulukuun voi sijoittaa kokonaislukuarvon) ja aliohjelman muuttujaan
16041613y arvo Level.Bottom + 200.0. Voisimme sijoittaa tietenkin minkä tahansa
1605muunkin liukuluvun.</p>
1606<p>Aliohjelmakutsun suorituksessa lasketaan siis ensiksi jokaisen kutsussa
1614muunkin liukuluvun.
1615
1616Aliohjelmakutsun suorituksessa lasketaan siis ensiksi jokaisen kutsussa
16071617olevan lausekkeen arvo ja sitten lasketut arvot sijoitetaan kutsussa
16081618olevassa järjestyksessä aliohjelman vastinparametreille. Siksi
16091619vastinparametrien pitää olla sijoitusyhteensopivia kutsun lausekkeiden
16101620kanssa. Esimerkin kutsussa lausekkeet ovat yksinkertaisia: muuttujan
16111621nimi (this), kokonaislukuarvo (0) ja reaalilukuarvo ( Level.Bottom +
16121622200.0). Ne voisivat kuitenkin olla kuinka monimutkaisia lausekkeita
1613tahansa, esimerkiksi näin:</p>
1614<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1615PiirraLumiukko(this, 22.7+sin(2.4), 80.1-Math.PI);</code></p>
1616<p>\
1617 \</p>
1618<p><em>Lause</em> (statement) ja <em>lauseke</em> (expression) ovat eri asia. Lauseke on
1623tahansa, esimerkiksi näin:
1624
1625``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1626PiirraLumiukko(this, 22.7+sin(2.4), 80.1-Math.PI);
1627```
1628
1629\
1630 \
1631
1632*Lause* (statement) ja *lauseke* (expression) ovat eri asia. Lauseke on
16191633arvojen, aritmeettisten operaatioiden ja aliohjelmien (tai metodien
16201634yhdistelmä), joka evaluoituu tietyksi arvoksi. Lauseke on siis lauseen
1621osa. Seuraava kuva selventää eroa.</p>
1622<p><img alt="\
1635osa. Seuraava kuva selventää eroa.
1636
1637![\
16231638 Kuva 6: Lauseen ja lausekkeen
1624ero" src="../src/luentomonistecsUusin_htm_m5dfaebb8.png" /></p>
1625<p>\
1639ero](../src/luentomonistecsUusin_htm_m5dfaebb8.png)
1640
1641\
16261642 Koska määrittelimme koordinaattien parametrien tyypiksi double,
16271643voisimme yhtä hyvin antaa parametreiksi mitä tahansa muitakin
1628desimaalilukuja. Täytyy muistaa, että C#:ssa desimaalilukuvakioissa
1629käytetään pistettä erottamaan kokonaisosa desimaaliosasta.</p>
1630<p>Kokonaisuudessaan ohjelma näyttää nyt seuraavalta:</p>
1631<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1644desimaalilukuja. Täytyy muistaa, että C\#:ssa desimaalilukuvakioissa
1645käytetään pistettä erottamaan kokonaisosa desimaaliosasta.
1646
1647Kokonaisuudessaan ohjelma näyttää nyt seuraavalta:
1648
1649``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1632165001 using Jypeli;
1633165102
1634165203
1635165304 /// @author Antti-Jussi Lakanen, Vesa Lappalainen
1636165405 /// @version 22.8.2012
1637165506 ///
163807 /// &lt;summary&gt;
165607 /// <summary>
1639165708 /// Piirretään lumiukkoja ja harjoitellaan aliohjelman käyttöä.
164009 /// &lt;/summary&gt;
165809 /// </summary>
1641165910 public class Lumiukot : PhysicsGame
1642166011 {
164312 /// &lt;summary&gt;
166112 /// <summary>
1644166213 /// Pääohjelmassa laitetaan "peli" käyntiin.
164514 /// &lt;/summary&gt;
164615 /// &lt;param name="args"&gt;Ei käytössä&lt;/param&gt;
166314 /// </summary>
166415 /// <param name="args">Ei käytössä</param>
1647166516 public static void Main(string[] args)
1648166617 {
1649166718 using (Lumiukot peli = new Lumiukot())
1670167021 }
1671167122 }
1672167223
167324 /// &lt;summary&gt;
167324 /// <summary>
1674167425 /// Kutsutaan PiirraLumiukko-aliohjelmaa
1675167526 /// sopivilla parametreilla.
167627 /// &lt;/summary&gt;
167627 /// </summary>
1677167728 public override void Begin()
1678167829 {
1679167930 Camera.ZoomToLevel();
1683168334 PiirraLumiukko(this, 200.0, Level.Bottom + 300.0);
1684168435 }
1685168536
168637 /// &lt;summary&gt;
168637 /// <summary>
1687168738 /// Aliohjelma piirtää lumiukon
1688168839 /// annettuun paikkaan.
168940 /// &lt;/summary&gt;
169041 /// &lt;param name="peli"&gt;Peliluokka&lt;/param&gt;
169142 /// &lt;param name="x"&gt;Lumiukon alimman pallon x-koordinaatti.&lt;/param&gt;
169243 /// &lt;param name="y"&gt;Lumiukon alimman pallon y-koordinaatti.&lt;/param&gt;
168940 /// </summary>
169041 /// <param name="peli">Peliluokka</param>
169142 /// <param name="x">Lumiukon alimman pallon x-koordinaatti.</param>
169243 /// <param name="y">Lumiukon alimman pallon y-koordinaatti.</param>
1693169344 public static void PiirraLumiukko(Game peli, double x, double y)
1694169445 {
1695169546 PhysicsObject p1, p2, p3;
1708170859 p3.Y = p2.Y + 50 + 30;
1709170960 peli.Add(p3);
1710171061 }
171162 }</code></p>
1712<p>\
1713 \</p>
1714<p>Kutsuttaessa aliohjelmaa hyppää ohjelman suoritus välittömästi
171162 }
1712```
1713
1714\
1715 \
1716
1717Kutsuttaessa aliohjelmaa hyppää ohjelman suoritus välittömästi
17151718parametrien sijoitusten jälkeen kutsuttavan aliohjelman ensimmäiselle
17161719riville ja alkaa suorittamaan aliohjelmaa kutsussa määritellyillä
17171720parametreilla. Kun päästään aliohjelman koodin loppuun palataan
17181721jatkamaan kutsun jälkeisestä seuraavasta lausekkeesta. Esimerkissämme
17191722kun ensimmäinen lumiukko on piirretty, palataan tavallaan ensimmäisen
17201723kutsun puolipisteeseen ja sitten pääohjelma jatkuu kutsumalla toista
1721lumiukon piirtämistä.</p>
1722<p>Jos nyt haluaisimme piirtää lisää lumiukkoja, lisäisi jokainen uusi
1723lumiukko koodia vain yhden rivin.</p>
1724<p>Huomaa! Aliohjelmien käyttö selkeyttää ohjelmaa ja aliohjelmia kannattaa
1724lumiukon piirtämistä.
1725
1726Jos nyt haluaisimme piirtää lisää lumiukkoja, lisäisi jokainen uusi
1727lumiukko koodia vain yhden rivin.
1728
1729Huomaa! Aliohjelmien käyttö selkeyttää ohjelmaa ja aliohjelmia kannattaa
17251730kirjoittaa, vaikka niitä kutsuttaisiin vain yhden kerran. Hyvää
1726aliohjelmaa voidaan kutsua muustakin käyttöyhteydestä.</p>
1727<h2>6.3 Aliohjelmien dokumentointi</h2>
1728<p>Jokaisen aliohjelman tulisi sisältää dokumentaatiokommentti. Aliohjelman
1731aliohjelmaa voidaan kutsua muustakin käyttöyhteydestä.
1732
17336.3 Aliohjelmien dokumentointi
1734------------------------------
1735
1736Jokaisen aliohjelman tulisi sisältää dokumentaatiokommentti. Aliohjelman
17291737dokumentaatiokommentin tulee sisältää ainakin seuraavat asiat: Lyhyt
17301738kuvaus aliohjelman toiminnasta, selitys kaikista parametreista sekä
17311739selitys mahdollisesta paluuarvosta. Nämä asiat kuvataan tägien avulla
1732seuraavasti:</p>
1733<ul>
1734<li>
1735<p>Dokumentaatiokommentin alkuun laitetaan \&lt;summary>-tagien väliin
1736 lyhyt ja selkeä kuvaus aliohjelman toiminnasta.</p>
1737</li>
1738<li>
1739<p>Jokainen parametri selitetään omien \&lt;param>-tagien väliin ja</p>
1740</li>
1741<li>
1742<p>paluuarvo \&lt;returns>-tagien väliin.</p>
1743</li>
1744</ul>
1745<p>PiirraLumiukko-aliohjelman dokumentaatiokommentit on edellisessä
1746esimerkissämme riveillä 36-41.</p>
1747<p>\</p>
1748<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
174936 /// &lt;summary&gt;
1740seuraavasti:
1741
1742- Dokumentaatiokommentin alkuun laitetaan \<summary\>-tagien väliin
1743 lyhyt ja selkeä kuvaus aliohjelman toiminnasta.
1744
1745- Jokainen parametri selitetään omien \<param\>-tagien väliin ja
1746
1747- paluuarvo \<returns\>-tagien väliin.
1748
1749PiirraLumiukko-aliohjelman dokumentaatiokommentit on edellisessä
1750esimerkissämme riveillä 36-41.
1751
1752\
1753
1754``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
175536 /// <summary>
1750175637 /// Aliohjelma piirtää lumiukon
1751175738 /// annettuun paikkaan.
175239 /// &lt;/summary&gt;
175340 /// &lt;param name="g"&gt;Peliluokka&lt;/param&gt;
175441 /// &lt;param name="x"&gt;Lumiukon alimman pallon x-koordinaatti.&lt;/param&gt;
175542 /// &lt;param name="y"&gt;Lumiukon alimman pallon y-koordinaatti.&lt;/param&gt;</code></p>
1756<p><em>Doxygen</em>-työkalun (ks.
1757<a href="http://en.wikipedia.org/wiki/Doxygen">http://en.wikipedia.org/wiki/Doxygen</a>)
1758tuottama HTML-sivu tästä luokasta näyttäisi nyt seuraavalta:</p>
1759<p><img alt="\
175839 /// </summary>
175940 /// <param name="g">Peliluokka</param>
176041 /// <param name="x">Lumiukon alimman pallon x-koordinaatti.</param>
176142 /// <param name="y">Lumiukon alimman pallon y-koordinaatti.</param>
1762```
1763
1764*Doxygen*-työkalun (ks.
1765[http://en.wikipedia.org/wiki/Doxygen](http://en.wikipedia.org/wiki/Doxygen))
1766tuottama HTML-sivu tästä luokasta näyttäisi nyt seuraavalta:
1767
1768![\
17601769 Kuva 7: Osa Lumiukot-luokan
1761dokumentaatiosta" src="../src/luentomonistecsUusin_htm_5219b95e.png" /></p>
1762<p>\
1770dokumentaatiosta](../src/luentomonistecsUusin_htm_5219b95e.png)
1771
1772\
17631773 Dokumentaatiossa näkyy kaikki luokan aliohjelmat ja metodit. Huomaa,
17641774että Doxygen nimittää sekä aliohjelmia että metodeja jäsenfunktioiksi
17651775(member functions). Kuten sanottu, nimitykset vaihtelevat
17661776kirjallisuudessa, ja tässä kohtaa käytössä on hieman harvinaisempi
17671777nimeämistapa. Kysymys on kuitenkin samasta asiasta, josta me tällä
1768kurssilla käytämme nimeä aliohjelmat ja metodit.</p>
1769<p>Jokaisesta aliohjelmasta ja metodista löytyy lisäksi tarkemmat tiedot
1778kurssilla käytämme nimeä aliohjelmat ja metodit.
1779
1780Jokaisesta aliohjelmasta ja metodista löytyy lisäksi tarkemmat tiedot
17701781Detailed Description -kohdasta. Aliohjelman PiirraLumiukko dokumentaatio
1771parametreineen näkyy kuvan alaosassa.</p>
1772<h3>6.3.1 Huomautus</h3>
1773<p>Kaikki PiirraLumiukko-aliohjelmassa tarvittava tieto välitettiin
1782parametreineen näkyy kuvan alaosassa.
1783
1784### 6.3.1 Huomautus
1785
1786Kaikki PiirraLumiukko-aliohjelmassa tarvittava tieto välitettiin
17741787parametrien avulla, eikä aliohjelman suorituksen aikana tarvittu
17751788aliohjelman ulkopuolisia tietoja. Tämä on tyypillistä aliohjelmille, ja
1776usein lisäksi toivottava ominaisuus.</p>
1777<h2>6.4 Aliohjelmat, metodit ja funktiot</h2>
1778<p>Kuten ehkä huomasit, aliohjelmilla ja metodeilla on paljon yhteistä.
1789usein lisäksi toivottava ominaisuus.
1790
17916.4 Aliohjelmat, metodit ja funktiot
1792------------------------------------
1793
1794Kuten ehkä huomasit, aliohjelmilla ja metodeilla on paljon yhteistä.
17791795Monissa kirjoissa nimitetään myös aliohjelmia metodeiksi. Tällöin
17801796aliohjelmat erotetaan olioiden metodeista nimittämällä niitä
17811797staattisiksi metodeiksi. Tässä monisteessa metodeista puhutaan kuitenkin
17821798vain silloin, kun tarkoitetaan olioiden toimintoja. Jypelin
17831799dokumentaatiosta tutkit RandomGen-luokan staattisia metodeja, millä
17841800voidaan luoda esimerkiksi satunnaisia lukuja. Yksittäinen pallo
1785poistettiin metodilla Destroy, joka on olion toiminto.</p>
1786<p>Aliohjelmista puhutaan tällä kurssilla, koska sitä termiä käytetään
1801poistettiin metodilla Destroy, joka on olion toiminto.
1802
1803Aliohjelmista puhutaan tällä kurssilla, koska sitä termiä käytetään
17871804monissa muissa ohjelmointikielissä. Tämä kurssi onkin ensisijaisesti
1788ohjelmoinnin kurssi, jossa käytetään C#-kieltä. Päätavoitteena on siis
1789oppia ohjelmoimaan ja työkaluna meillä sen opettelussa on C#-kieli.</p>
1790<p>Aliohjelmamme PiirraLumiukko ei palauttanut mitään arvoa. Aliohjelmaa
1805ohjelmoinnin kurssi, jossa käytetään C\#-kieltä. Päätavoitteena on siis
1806oppia ohjelmoimaan ja työkaluna meillä sen opettelussa on C\#-kieli.
1807
1808Aliohjelmamme PiirraLumiukko ei palauttanut mitään arvoa. Aliohjelmaa
17911809(tai metodia) joka palauttaa jonkun arvon voidaan kutsua myös tarkemmin
1792<em>funktioksi</em> (function).</p>
1793<p>Aliohjelmia ja metodeja nimitetään eri tavoin eri kielissä. Esimerkiksi
1810*funktioksi* (function).
1811
1812Aliohjelmia ja metodeja nimitetään eri tavoin eri kielissä. Esimerkiksi
17941813C++-kielessä sekä aliohjelmia että metodeja sanotaan funktioiksi.
17951814Metodeita nimitetään C++-kielessä tarkemmin vielä jäsenfunktioiksi,
1796kuten Doxygen teki myös C#:n tapauksessa.</p>
1797<p>Kerrataan vielä lyhyesti aliohjelman, funktion ja metodin erot.</p>
1798<p><strong>Aliohjelma</strong>\
1815kuten Doxygen teki myös C\#:n tapauksessa.
1816
1817Kerrataan vielä lyhyesti aliohjelman, funktion ja metodin erot.
1818
1819**Aliohjelma**\
17991820 Osaohjelma, joka voi tehdä kaikki toimensa käyttäen hyväkseen vain
18001821parametrilistassa tuotua tietoa. Paluuarvon tyyppinä on void, jolloin
1801aliohjelma ei palauta mitään arvoa.</p>
1802<p><strong>Funktio\
1803</strong>Aliohjelma, joka palauttaa jonkin tuloksen, esimerkiksi kahden luvun
1822aliohjelma ei palauta mitään arvoa.
1823
1824**Funktio\
1825**Aliohjelma, joka palauttaa jonkin tuloksen, esimerkiksi kahden luvun
18041826keskiarvon. Tämän määritelmän mukaan funktiossa on aina return-lause
18051827jonka perässä on lauseke, esimerkiksi return (a+b)/2.0; Puhtaassa
18061828aliohjelmassakin (ks. edellinen kohta) voi olla return-lause, mutta sen
1807perässä ei ole lauseketta.</p>
1808<p><strong>Metodi\
1809</strong>Aliohjelma, joka tarvitsee tehtävän suorittamiseksi kohteena olevan
1829perässä ei ole lauseketta.
1830
1831**Metodi\
1832**Aliohjelma, joka tarvitsee tehtävän suorittamiseksi kohteena olevan
18101833olion omia tietoja. Näitä käytetään tällä kurssilla, mutta ei tehdä
18111834alkupään esimerkeissä itse. Lopullisessa pelissä voi tulla tehtäväksi
18121835myös metodeja, jotka tarvitsevat peliluokan-olion tietoja toimintansa
18131836toteuttamiseen. Joku voi myös mahdollisesti tehdä vaikka uuden
1814aseluokan, jolle kirjoitetaan omia metodeja.</p>
1815<p>Metodi voi myös funktion tapaan palauttaa arvon tai aliohjelman tapaan
1816olla palauttamatta. Emme erottele tätä enää eri nimillä.</p>
1817<h1>7. Muuttujat</h1>
1818<p>Muuttujat (variable) toimivat ohjelmassa tietovarastoina erilaisille
1837aseluokan, jolle kirjoitetaan omia metodeja.
1838
1839Metodi voi myös funktion tapaan palauttaa arvon tai aliohjelman tapaan
1840olla palauttamatta. Emme erottele tätä enää eri nimillä.
1841
18427. Muuttujat
1843============
1844
1845Muuttujat (variable) toimivat ohjelmassa tietovarastoina erilaisille
18191846asioille. Muuttuja on kuin pieni laatikko, johon voidaan varastoida
18201847asioita, esimerkiksi lukuja, sanoja, tietoa ohjelman käyttäjästä ja
18211848paljon muuta. Ilman muuttujia järkevä tiedon käsittely olisi oikeastaan
18501850Lumiukko-esimerkissä teimme PhysicsObject-tyyppisiä muuttujia p1, p2 ja
18511851p3. Vastaavasti Lumiukko-aliohjelman parametrit (Game peli, double x,
18521852double y) ovat myös muuttujia: Game-tyyppinen oliomuuttuja peli, sekä
1853double-alkeistietotyyppiset muuttujat x ja y.</p>
1854<p>Termi <em>muuttuja</em> on lainattu ohjelmointiin matematiikasta, mutta niitä
1853double-alkeistietotyyppiset muuttujat x ja y.
1854
1855Termi *muuttuja* on lainattu ohjelmointiin matematiikasta, mutta niitä
18551856ei tule kuitenkaan sekoittaa keskenään - muuttuja matematiikassa ja
18561857muuttuja ohjelmoinnissa tarkoittavat hieman eri asioita. Tulet
1857huomaamaan tämän seuraavien kappaleiden aikana.</p>
1858<p>Muuttujien arvot tallennetaan keskusmuistiin tai rekistereihin, mutta
1858huomaamaan tämän seuraavien kappaleiden aikana.
1859
1860Muuttujien arvot tallennetaan keskusmuistiin tai rekistereihin, mutta
18591861ohjelmointikielissä voimme antaa kullekin muuttujalle nimen
18601862(identifier), jotta muuttujan arvon käsittely olisi helpompaa. Muuttujan
18611863nimi onkin ohjelmointikielten helpotus, sillä näin ohjelmoijan ei
18621864tarvitse tietää tarvitsemansa tiedon keskusmuisti- tai
18631865rekisteriosoitetta, vaan riittää muistaa itse nimeämänsä muuttujan nimi.
1864[VES]</p>
1865<h2>7.1 Muuttujan määrittely</h2>
1866<p>Kun matemaatikko sanoo, että ”n on yhtäsuuri kuin 1”, tarkoittaa se,
1866[VES]
1867
18687.1 Muuttujan määrittely
1869------------------------
1870
1871Kun matemaatikko sanoo, että ”n on yhtäsuuri kuin 1”, tarkoittaa se,
18671872että tuo termi (eli muuttuja) n on jollain käsittämättömällä tavalla
18681873sama kuin luku 1. Matematiikassa muuttujia voidaan esitellä tällä
1869tavalla ”häthätää”.</p>
1870<p>Ohjelmoijan on kuitenkin tehtävä vastaava asia hieman tarkemmin.
1871C#-kielessä tämä tapahtuisi kirjoittamalla seuraavasti:</p>
1872<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1874tavalla ”häthätää”.
1875
1876Ohjelmoijan on kuitenkin tehtävä vastaava asia hieman tarkemmin.
1877C\#-kielessä tämä tapahtuisi kirjoittamalla seuraavasti:
1878
1879``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
18731880int n;
1874n = 1;</code></p>
1875<p>Ensimmäinen rivi tarkoittaa väljästi sanottuna, että ”lohkaise pieni
1881n = 1;
1882```
1883
1884Ensimmäinen rivi tarkoittaa väljästi sanottuna, että ”lohkaise pieni
18761885pala - johon mahtuu int-kokoinen arvo - säilytystilaa tietokoneen
18771886muistista, ja käytä siitä jatkossa nimeä n. Toisella rivillä
18781887julistetaan, että ”talleta arvo 1 muuttujaan, jonka nimi on n, siten
1879korvaten sen, mitä kyseisessä säilytystilassa mahdollisesti jo on”.</p>
1880<p>Mikä sitten on tuo edellisen esimerkin int?</p>
1881<p>C#:ssa jokaisella muuttujalla täytyy olla <em>tietotyyppi</em> (usein myös
1882lyhyesti <em>tyyppi</em>). Tietotyyppi on määriteltävä, jotta ohjelma tietäisi,
1888korvaten sen, mitä kyseisessä säilytystilassa mahdollisesti jo on”.
1889
1890Mikä sitten on tuo edellisen esimerkin int?
1891
1892C\#:ssa jokaisella muuttujalla täytyy olla *tietotyyppi* (usein myös
1893lyhyesti *tyyppi*). Tietotyyppi on määriteltävä, jotta ohjelma tietäisi,
18831894millaista tietoa muuttujaan tullaan tallentamaan. Toisaalta tietotyyppi
18841895on määriteltävä siksi, että ohjelma osaa varata muistista sopivan
18851896kokoisen lohkareen muuttujan sisältämää tietoa varten. Esimerkiksi
18861897int-tyypin tapauksessa tilantarve olisi 32 bittiä (4 tavua), byte-tyypin
18871898tapauksessa 8 bittiä (1 tavu) ja double-tyypin 64 bittiä (8 tavua).
18881899Muuttuja määritellään (declare) kirjoittamalla ensiksi tietotyyppi ja
1889sen perään muuttujan nimi. Muuttujan nimet aloitetaan C#ssa pienellä
1900sen perään muuttujan nimi. Muuttujan nimet aloitetaan C\#ssa pienellä
18901901kirjaimella, jonka jälkeen jokainen uusi sana alkaa aina isolla
18911902kirjaimella. Kuten aiemmin mainittiin, tämä nimeämistapa on nimeltään
1892camelCasing.</p>
1893<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1894muuttujanTietotyyppi muuttujanNimi;</code></p>
1895<p>Tuo mainitsemamme int on siis tietotyyppi, ja int-tyyppiseen muuttujaan
1903camelCasing.
1904
1905``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1906muuttujanTietotyyppi muuttujanNimi;
1907```
1908
1909Tuo mainitsemamme int on siis tietotyyppi, ja int-tyyppiseen muuttujaan
18961910voi tallentaa kokonaislukuja. Muuttujaan n voimme laittaa lukuja 1, 2,
189719113, samoin 0, -1, -2, ja niin edelleen, mutta emme lukua 0.1 tai sanaa
1898”Moi”.</p>
1899<p>Henkilön iän voisimme tallentaa seuraavaan muuttujaan:</p>
1900<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1901int henkilonIka;</code></p>
1902<p>Huomaa, että tässä emme aseta muuttujalle mitään arvoa, vain
1903määrittelemme muuttujan int-tyyppiseksi ja annamme sille nimen.</p>
1904<p>Samantyyppisiä muuttujia voidaan määritellä kerralla useampia
1912”Moi”.
1913
1914Henkilön iän voisimme tallentaa seuraavaan muuttujaan:
1915
1916``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1917int henkilonIka;
1918```
1919
1920Huomaa, että tässä emme aseta muuttujalle mitään arvoa, vain
1921määrittelemme muuttujan int-tyyppiseksi ja annamme sille nimen.
1922
1923Samantyyppisiä muuttujia voidaan määritellä kerralla useampia
19051924erottamalla muuttujien nimet pilkulla. Tietotyyppiä double käytetään,
1906kun halutaan tallentaa desimaalilukuja.</p>
1907<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1908double paino, pituus;</code></p>
1909<p>Määrittely onnistuu toki myös erikseen.</p>
1910<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
1925kun halutaan tallentaa desimaalilukuja.
1926
1927``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
1928double paino, pituus;
1929```
1930
1931Määrittely onnistuu toki myös erikseen.
1932
1933``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
19111934double paino;
1912double pituus;</code></p>
1913<h2>7.2 Alkeistietotyypit</h2>
1914<p>C#:n tietotyypit voidaan jakaa alkeistietotyyppeihin (primitive types)
1935double pituus;
1936```
1937
19387.2 Alkeistietotyypit
1939---------------------
1940
1941C\#:n tietotyypit voidaan jakaa alkeistietotyyppeihin (primitive types)
19151942ja oliotietotyyppeihin (reference types). Oliotietotyyppeihin kuuluu
19161943muun muassa käyttämämme PhysicsObject-tyyppi, jota pallot p1 jne.
19171944olivat, sekä merkkijonojen tallennukseen tarkoitettu String-olio.
1918Oliotyyppejä käsitellään myöhemmin luvussa 8.</p>
1919<p>Eri tietotyypit vaativat eri määrän kapasiteettia tietokoneen muistista.
1945Oliotyyppejä käsitellään myöhemmin luvussa 8.
1946
1947Eri tietotyypit vaativat eri määrän kapasiteettia tietokoneen muistista.
19201948Vaikka nykyajan koneissa on paljon muistia, on hyvin tärkeää valita
19211949oikean tyyppinen muuttuja kuhunkin tilanteeseen. Suurissa ohjelmissa
19221950ongelma korostuu hyvin nopeasti käytettäessä muuttujia, jotka kuluttavat
1923tilanteeseen nähden kohtuuttoman paljon muistikapasiteettia. C#:n
1924alkeistietotyypit on lueteltu alla.</p>
1925<p>Taulukko 1: C#:n alkeistietotyypit koon mukaan järjestettynä.</p>
1926<p>C#-merkki</p>
1927<p>Koko</p>
1928<p>Selitys</p>
1929<p>Arvoalue</p>
1930<p>bool</p>
1931<p>1 bitti</p>
1932<p>kaksiarvoinen tietotyyppi</p>
1933<p>true tai false</p>
1934<p>sbyte</p>
1935<p>8 bittiä</p>
1936<p>yksi tavu</p>
1937<p>-128..127</p>
1938<p>byte</p>
1939<p>8 bittiä</p>
1940<p>yksi tavu (etumerkitön)</p>
1941<p>0..255</p>
1942<p>char</p>
1943<p>16 bittiä</p>
1944<p>yksi merkki</p>
1945<p>kaikki merkit</p>
1946<p>short</p>
1947<p>16 bittiä</p>
1948<p>pieni kokonaisluku</p>
1949<p>-32,768..32,767</p>
1950<p>ushort</p>
1951<p>16 bittiä</p>
1952<p>pieni kokonaisluku (etumerkitön)</p>
1953<p>0..65,535</p>
1954<p>int</p>
1955<p>32 bittiä</p>
1956<p>kokonaisluku</p>
1957<p>-2,147,483,648..\
1958 2,147,483,647</p>
1959<p>uint</p>
1960<p>32 bittiä</p>
1961<p>kokonaisluku (etumerkitön)</p>
1962<p>0..4,294,967,295</p>
1963<p>float</p>
1964<p>32 bittiä</p>
1965<p>liukuluku</p>
1966<p>noin 7 desimaalin tarkkuus,</p>
1967<p>±1.5 × 10^-45^.. ±3.4 × 10^38^</p>
1968<p>long</p>
1969<p>64 bittiä</p>
1970<p>iso kokonaisluku</p>
1971<p>-2^63^..2^63^-1</p>
1972<p>ulong</p>
1973<p>64 bittiä</p>
1974<p>iso kokonaisluku (etumerkitön)</p>
1975<p>0..\
1976 18,446,744,073,709,615</p>
1977<p>double</p>
1978<p>64 bittiä</p>
1979<p>tarkka liukuluku</p>
1980<p>noin 15 desimaalin tarkkuus,</p>
1981<p>±5.0 × 10^-324^.. ±1.7 × 10^308^</p>
1982<p>decimal</p>
1983<p>128 bittiä</p>
1984<p>erittäin tarkka liukuluku</p>
1985<p>Noin 28 luvun tarkkuus</p>
1986<p>\</p>
1987<p>\</p>
1988<p>\</p>
1989<p>\</p>
1990<p>Tässä monisteessa suositellaan, että desimaalilukujen talletukseen
1951tilanteeseen nähden kohtuuttoman paljon muistikapasiteettia. C\#:n
1952alkeistietotyypit on lueteltu alla.
1953
1954Taulukko 1: C\#:n alkeistietotyypit koon mukaan järjestettynä.
1955
1956C\#-merkki
1957
1958Koko
1959
1960Selitys
1961
1962Arvoalue
1963
1964bool
1965
19661 bitti
1967
1968kaksiarvoinen tietotyyppi
1969
1970true tai false
1971
1972sbyte
1973
19748 bittiä
1975
1976yksi tavu
1977
1978-128..127
1979
1980byte
1981
19828 bittiä
1983
1984yksi tavu (etumerkitön)
1985
19860..255
1987
1988char
1989
199016 bittiä
1991
1992yksi merkki
1993
1994kaikki merkit
1995
1996short
1997
199816 bittiä
1999
2000pieni kokonaisluku
2001
2002-32,768..32,767
2003
2004ushort
2005
200616 bittiä
2007
2008pieni kokonaisluku (etumerkitön)
2009
20100..65,535
2011
2012int
2013
201432 bittiä
2015
2016kokonaisluku
2017
2018-2,147,483,648..\
2019 2,147,483,647
2020
2021uint
2022
202332 bittiä
2024
2025kokonaisluku (etumerkitön)
2026
20270..4,294,967,295
2028
2029float
2030
203132 bittiä
2032
2033liukuluku
2034
2035noin 7 desimaalin tarkkuus,
2036
2037±1.5 × 10^-45^.. ±3.4 × 10^38^
2038
2039long
2040
204164 bittiä
2042
2043iso kokonaisluku
2044
2045-2^63^..2^63^-1
2046
2047ulong
2048
204964 bittiä
2050
2051iso kokonaisluku (etumerkitön)
2052
20530..\
2054 18,446,744,073,709,615
2055
2056double
2057
205864 bittiä
2059
2060tarkka liukuluku
2061
2062noin 15 desimaalin tarkkuus,
2063
2064±5.0 × 10^-324^.. ±1.7 × 10^308^
2065
2066decimal
2067
2068128 bittiä
2069
2070erittäin tarkka liukuluku
2071
2072Noin 28 luvun tarkkuus
2073
2074\
2075
2076\
2077
2078\
2079
2080\
2081
2082Tässä monisteessa suositellaan, että desimaalilukujen talletukseen
19912083käytettäväksi aina double-tietotyyppiä (jossain tapauksissa jopa
19922084decimal-tyyppiä), vaikka monessa paikassa float-tietotyyppiä
19932085käytetäänkin. Tämä johtuu siitä, että liukuluvut, joina desimaaliluvut
19942086tietokoneessa käsitellään, ovat harvoin tarkkoja arvoja tietokoneessa.
19952087Itse asiassa ne ovat tarkkoja vain kun ne esittävät jotakin kahden
1996potenssin kombinaatiota, kuten esimerkiksi 2.0, 7.0, 0.5 tai 0.375.</p>
1997<p>Useimmiten liukuluvut ovat pelkkiä approksimaatioita oikeasta
2088potenssin kombinaatiota, kuten esimerkiksi 2.0, 7.0, 0.5 tai 0.375.
2089
2090Useimmiten liukuluvut ovat pelkkiä approksimaatioita oikeasta
19982091reaaliluvusta. Esimerkiksi lukua 0.1 ei pystytä tietokoneessa esittämään
19992092biteillä tarkasti. Tällöin laskujen määrän kasvaessa lukujen epätarkkuus
20002093vain lisääntyy. Tämän takia onkin turvallisempaa käyttää aina
20012094double-tietotyyppiä, koska se suuremman bittimääränsä takia pystyy
2002tallettamaan enemmän merkitseviä desimaaleja.</p>
2003<p>Tietyissä sovelluksissa, joissa mahdollisimman suuri tarkkuus on
2095tallettamaan enemmän merkitseviä desimaaleja.
2096
2097Tietyissä sovelluksissa, joissa mahdollisimman suuri tarkkuus on
20042098välttämätön (kuten pankki- tai nanotason fysiikkasovellukset), on
20052099suositeltavaa käyttää korkeimpaa mahdollista tarkkuutta tarjoavaa
20062100decimal-tyyppiä. Reaalilukujen esityksestä tietokoneessa puhutaan lisää
2007kohdassa <a href="#o246Liukuluku_floatingpoint">26.6</a>. [VES][KOS]</p>
2008<h2>7.3 Arvon asettaminen muuttujaan</h2>
2009<p>Muuttujaan asetetaan arvo sijoitusoperaattorilla (assignment operator)
2101kohdassa [26.6](#o246Liukuluku_floatingpoint). [VES][KOS]
2102
21037.3 Arvon asettaminen muuttujaan
2104--------------------------------
2105
2106Muuttujaan asetetaan arvo sijoitusoperaattorilla (assignment operator)
20102107"=". Lauseita, joilla asetetaan muuttujille arvoja sanotaan
20112108sijoituslauseiksi (assignment statement). On tärkeää huomata, että
20122109sijoitus tapahtuu aina oikealta vasemmalle: sijoitettava on
2013yhtäsuuruusmerkin oikealla puolella ja kohde merkin vasemmalla puolella.</p>
2014<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2110yhtäsuuruusmerkin oikealla puolella ja kohde merkin vasemmalla puolella.
2111
2112``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
20152113x = 20.0;
20162114henkilonIka = 23;
20172115paino = 80.5;
2018pituus = 183.5;</code></p>
2019<p>Muuttujaan voi asettaa arvon myös jo määrittelyn yhteydessä.</p>
2020<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2116pituus = 183.5;
2117```
2118
2119Muuttujaan voi asettaa arvon myös jo määrittelyn yhteydessä.
2120
2121``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
20212122bool onkoKalastaja = true;
20222123char merkki = 't';
20232124int kalojenLkm = 0;
2024double luku1 = 0, luku2 = 0, luku3 = 0;</code></p>
2025<p>Muuttuja täytyy olla määritelty tietyn tyyppiseksi ennen kuin siihen voi
2125double luku1 = 0, luku2 = 0, luku3 = 0;
2126```
2127
2128Muuttuja täytyy olla määritelty tietyn tyyppiseksi ennen kuin siihen voi
20262129asettaa arvoa. Muuttujaan voi asettaa vain määrittelyssä annetun
2027tietotyypin mukaisia arvoja tai sen kanssa <em>sijoitusyhteensopivia</em>
2130tietotyypin mukaisia arvoja tai sen kanssa *sijoitusyhteensopivia*
20282131arvoja. Esimerkiksi liukulukutyyppeihin (float ja double) voi sijoittaa
20292132myös kokonaislukutyyppisiä arvoja, sillä kokonaisluvut on reaalilukujen
20302133osajoukko. Alla sijoitamme arvon 4 muuttujaan nimeltä luku2, ja
20312134kolmannella rivillä luku2-muuttujan sisältämän arvon (4) muuttujaan,
2032jonka nimi on luku1.</p>
2033<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2135jonka nimi on luku1.
2136
2137``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
20342138double luku1;
20352139int luku2 = 4;
2036luku1 = luku2;</code></p>
2037<p>Toisinpäin tämä ei onnistu: double-tyyppistä arvoa ei voi sijoittaa
2038int-tyyppiseen muuttujaan. Alla oleva koodi ei kääntyisi:</p>
2039<p><code>{.huonoesimerkki-western lang="zxx" xml:lang="zxx"}
2140luku1 = luku2;
2141```
2142
2143Toisinpäin tämä ei onnistu: double-tyyppistä arvoa ei voi sijoittaa
2144int-tyyppiseen muuttujaan. Alla oleva koodi ei kääntyisi:
2145
2146``` {.huonoesimerkki-western lang="zxx" xml:lang="zxx"}
20402147//TÄMÄ KOODI EI KÄÄNNY!
20412148int luku1;
20422149double luku2 = 4.0;
2043luku1 = luku2;</code></p>
2044<p>Kun decimal-tyyppinen muuttuja alustetaan jollain luvulla, tulee luvun
2150luku1 = luku2;
2151```
2152
2153Kun decimal-tyyppinen muuttuja alustetaan jollain luvulla, tulee luvun
20452154perään (ennen puolipistettä) laittaa m (tai M)-merkki. Samoin
20462155float-tyyppisten muuttujien alustuksessa perään laitetaan f (tai
2047F)-merkki.</p>
2048<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2156F)-merkki.
2157
2158``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
20492159decimal tilinSaldo = 3498.98m;
2050float lampotila = -4.8f;</code></p>
2051<p>Huomaa, että char-tyyppiseen muuttujaan sijoitetaan arvo laittamalla
2052merkki heittomerkkien väliin, esimerkiksi näin.</p>
2053<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2054char ekaKirjain = 'k';</code></p>
2055<p>Näin sen erottaa myöhemmin käsiteltävästä String-tyyppiseen muuttujaan
2160float lampotila = -4.8f;
2161```
2162
2163Huomaa, että char-tyyppiseen muuttujaan sijoitetaan arvo laittamalla
2164merkki heittomerkkien väliin, esimerkiksi näin.
2165
2166``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2167char ekaKirjain = 'k';
2168```
2169
2170Näin sen erottaa myöhemmin käsiteltävästä String-tyyppiseen muuttujaan
20562171sijoittamisesta, jossa sijoitettava merkkijono laitetaan lainausmerkkien
2057väliin, esimerkiksi seuraavasti.</p>
2058<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2059String omaNimi = "Antti-Jussi";</code></p>
2060<p>Sijoituslause voi sisältää myös monimutkaisiakin lausekkeita,
2061esimerkiksi aritmeettisia operaatioita:</p>
2062<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2063double numeroidenKeskiarvo = (2 + 4 + 1 + 5 + 3 + 2) / 6.0;</code></p>
2064<p>Sijoituslause voi sisältää myös muuttujia.</p>
2065<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2172väliin, esimerkiksi seuraavasti.
2173
2174``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2175String omaNimi = "Antti-Jussi";
2176```
2177
2178Sijoituslause voi sisältää myös monimutkaisiakin lausekkeita,
2179esimerkiksi aritmeettisia operaatioita:
2180
2181``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2182double numeroidenKeskiarvo = (2 + 4 + 1 + 5 + 3 + 2) / 6.0;
2183```
2184
2185Sijoituslause voi sisältää myös muuttujia.
2186
2187``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
20662188double huoneenPituus = 540.0;
20672189double huoneenLeveys = huoneenPituus;
2068double huoneenAla = huoneenPituus * huoneenLeveys;</code></p>
2069<p>Eli sijoitettava voi olla mikä tahansa lauseke, joka tuottaa muuttujalle
2070kelpaavan arvon.</p>
2071<p>C#:ssa täytyy aina asettaa joku arvo muuttujaan <em>ennen</em> sen
2190double huoneenAla = huoneenPituus * huoneenLeveys;
2191```
2192
2193Eli sijoitettava voi olla mikä tahansa lauseke, joka tuottaa muuttujalle
2194kelpaavan arvon.
2195
2196C\#:ssa täytyy aina asettaa joku arvo muuttujaan *ennen* sen
20722197käyttämistä. Kääntäjä ei käännä koodia, jossa käytetään muuttujaa jolle
2073ei ole asetettu arvoa. Alla oleva ohjelma ei siis kääntyisi.</p>
2074<p><code>{.huonoesimerkki-western lang="zxx" xml:lang="zxx"}
2198ei ole asetettu arvoa. Alla oleva ohjelma ei siis kääntyisi.
2199
2200``` {.huonoesimerkki-western lang="zxx" xml:lang="zxx"}
20752201// TÄMÄ OHJELMA EI KÄÄNNY
20762202public class Esimerkki
20772203{
22062206 int ika;
22072207 System.Console.WriteLine(ika);
22082208 }
2209}</code></p>
2210<p>Virheilmoitus näyttää tältä:</p>
2211<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2209}
2210```
2211
2212Virheilmoitus näyttää tältä:
2213
2214``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
22122215Esimerkki.cs(4,40): error CS0165: Use of unassigned local variable
2213 'ika'</code></p>
2214<p>Kääntäjä kertoo, että ika-nimistä muuttuja yritetään käyttää, vaikka
2216 'ika'
2217```
2218
2219Kääntäjä kertoo, että ika-nimistä muuttuja yritetään käyttää, vaikka
22152220sille ei ole osoitettu mitään arvoa. Tämä ei ole sallittua, joten
2216ohjelman kääntämisyritys päättyy tähän.</p>
2217<h2>7.4 Muuttujan nimeäminen</h2>
2218<p>Muuttujan nimen täytyy olla siihen tallennettavaa tietoa kuvaava.
2221ohjelman kääntämisyritys päättyy tähän.
2222
22237.4 Muuttujan nimeäminen
2224------------------------
2225
2226Muuttujan nimen täytyy olla siihen tallennettavaa tietoa kuvaava.
22192227Yleensä pelkkä yksi kirjain on huono nimi muuttujalle, sillä se harvoin
22202228kuvaa kovin hyvin muuttujaa. Kuvaava muuttujan nimi selkeyttää koodia ja
22212229vähentää kommentoimisen tarvetta. Lyhyt muuttujan nimi ei ole
22322232käytettäessä tämä ei enää pidä paikkaansa, sillä editorit osaavat
22332233täydentää muuttujan nimen samalla kun koodia kirjoitetaan, joten niitä
22342234ei käytännössä koskaan tarvitse kirjoittaa kokonaan, paitsi tietysti
2235ensimmäisen kerran.</p>
2236<p>Yksikirjaimisia muuttujien nimiäkin voi perustellusti käyttää, jos
2235ensimmäisen kerran.
2236
2237Yksikirjaimisia muuttujien nimiäkin voi perustellusti käyttää, jos
22372238niillä on esimerkiksi jo matematiikasta tai fysiikasta ennestään tuttu
22382239merkitys. Nimet x ja y ovat hyviä kuvaamaan koordinaatteja. Nimi l (eng.
22392240length) viittaa pituuteen ja r (eng. radius) säteeseen. Fysikaalisessa
2240ohjelmassa s voi hyvin kuvata matkaa.</p>
2241<p>Huomaa! Muuttujan nimi ei voi C#:ssa alkaa numerolla.</p>
2242<p>C#:n koodauskäytänteiden mukaan muuttujan nimi alkaa pienellä
2241ohjelmassa s voi hyvin kuvata matkaa.
2242
2243Huomaa! Muuttujan nimi ei voi C\#:ssa alkaa numerolla.
2244
2245C\#:n koodauskäytänteiden mukaan muuttujan nimi alkaa pienellä
22432246kirjaimella ja jos muuttujan nimi koostuu useammasta sanasta aloitetaan
2244uusi sana aina isolla kirjaimella kuten alla.</p>
2245<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2246int polkupyoranRenkaanKoko;</code></p>
2247<p>C#:ssa muuttujan nimi voi sisältää ääkkösiä, mutta niiden käyttö ei
2247uusi sana aina isolla kirjaimella kuten alla.
2248
2249``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2250int polkupyoranRenkaanKoko;
2251```
2252
2253C\#:ssa muuttujan nimi voi sisältää ääkkösiä, mutta niiden käyttö ei
22482254suositella, koska siirtyminen koodistosta toiseen aiheuttaa usein
2249ylimääräisiä ongelmia.</p>
2250<p><em>Koodisto =</em> Määrittelee jokaiselle <em>merkistön</em> merkille yksikäsitteisen
2255ylimääräisiä ongelmia.
2256
2257*Koodisto =* Määrittelee jokaiselle *merkistön* merkille yksikäsitteisen
22512258koodinumeron. Merkin numeerinen esitys on usein välttämätön
22522259tietokoneissa. Merkistö määrittelee joukon merkkejä ja niille nimen,
22532260numeron ja jonkinnäköisen muodon kuvauksen. Merkistöllä ja koodistolla
22642264Koodistoissa syntyy ongelmia yleensä silloin, kun siirrytään jostain
22652265skandimerkkejä (ä,ö,å, ...) sisältävästä koodistosta seitsemänbittiseen
22662266ASCII-koodistoon, joka ei tue skandeja. ASCII-koodistosta puhutaan lisää
2267luvussa <a href="#o25_ASCIIkoodi">27</a>.</p>
2268<h3>7.4.1 C#:n varatut sanat</h3>
2269<p>Muuttujan nimi ei saa olla mikään ohjelmointikielen varatuista sanoista,
2270eli sanoista joilla on C#:ssa joku muu merkitys.</p>
2271<p>Taulukko 2: C#:n varatut sanat.</p>
2272<hr />
2273<p>abstract do in protected true
2267luvussa [27](#o25_ASCIIkoodi).
2268
2269### 7.4.1 C\#:n varatut sanat
2270
2271Muuttujan nimi ei saa olla mikään ohjelmointikielen varatuista sanoista,
2272eli sanoista joilla on C\#:ssa joku muu merkitys.
2273
2274Taulukko 2: C\#:n varatut sanat.
2275
2276 ---------- ---------- ----------- ------------ -----------
2277 abstract do in protected true
22742278 as double int public try
22752279 base else interface readonly typeof
22762280 bool enum internal ref uint
22872287 class float object static void
22882288 const for operator string volatile
22892289 continue foreach out struct while
2290 decimal goto override switch <br />
2291 default if params this <br />
2292 delegate implicit private throw </p>
2293<hr />
2294<p>\
2295 \</p>
2296<p>\
2297 \</p>
2298<h2>7.5 Muuttujien näkyvyys</h2>
2299<p>Muuttujaa voi käyttää (lukea ja asettaa arvoja) vain siinä lohkossa,
2290 decimal goto override switch
2291 default if params this
2292 delegate implicit private throw
2293 ---------- ---------- ----------- ------------ -----------
2294
2295\
2296 \
2297
2298\
2299 \
2300
23017.5 Muuttujien näkyvyys
2302-----------------------
2303
2304Muuttujaa voi käyttää (lukea ja asettaa arvoja) vain siinä lohkossa,
23002305missä se on määritelty. Muuttujan määrittelyn täytyy aina olla ennen
23012306(koodissa ylempänä), kun sitä ensimmäisen kerran käytetään. Jos muuttuja
2302on käytettävissä sanotaan, että muuttuja <em>näkyy</em>. Aliohjelman sisällä
2303määritelty muuttuja ei siis näy muissa aliohjelmissa.</p>
2304<p>Luokan sisällä muuttuja voidaan määritellä myös niin, että se näkyy
2307on käytettävissä sanotaan, että muuttuja *näkyy*. Aliohjelman sisällä
2308määritelty muuttuja ei siis näy muissa aliohjelmissa.
2309
2310Luokan sisällä muuttuja voidaan määritellä myös niin, että se näkyy
23052311kaikkialla, siis kaikille aliohjelmille. Kun muuttuja on näkyvissä
2306kaikille ohjelman osille, sanotaan sitä <em>globaaliksi muuttujaksi</em>
2312kaikille ohjelman osille, sanotaan sitä *globaaliksi muuttujaksi*
23072313(global variable). Globaaleja muuttujia tulee välttää aina kun
2308mahdollista.</p>
2309<p>Lisätietoa muuttujien näkyvyydestä löydät wikistä osoitteessa</p>
2310<p><a href="https://trac.cc.jyu.fi/projects/ohj1/wiki/MuuttujienNakyvyys">https://trac.cc.jyu.fi/projects/ohj1/wiki/MuuttujienNakyvyys</a>.</p>
2311<h2>7.6 Vakiot</h2>
2312<blockquote>
2313<p>One man's constant is another man's variable. -Alan Perlis</p>
2314</blockquote>
2315<p>Muuttujien lisäksi ohjelmointikielissä voidaan määritellä vakioita
2316(constant). Vakioiden arvoa ei voi muuttaa määrittelyn jälkeen. C#:ssa
2314mahdollista.
2315
2316Lisätietoa muuttujien näkyvyydestä löydät wikistä osoitteessa
2317
2318[https://trac.cc.jyu.fi/projects/ohj1/wiki/MuuttujienNakyvyys](https://trac.cc.jyu.fi/projects/ohj1/wiki/MuuttujienNakyvyys).
2319
23207.6 Vakiot
2321----------
2322
2323> One man's constant is another man's variable. -Alan Perlis
2324
2325Muuttujien lisäksi ohjelmointikielissä voidaan määritellä vakioita
2326(constant). Vakioiden arvoa ei voi muuttaa määrittelyn jälkeen. C\#:ssa
23172327vakio määritellään muuten kuten muuttuja, mutta muuttujan tyypin eteen
2318kirjoitetaan lisämääre const.</p>
2319<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2320const int KUUKAUSIEN_LKM = 12;</code></p>
2321<p>Tällä kurssilla vakiot kirjoitetaan suuraakkosin siten, että sanat
2322erotetaan alaviivalla (_). Näin ne erottaa helposti muuttujien nimistä,
2328kirjoitetaan lisämääre const.
2329
2330``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
2331const int KUUKAUSIEN_LKM = 12;
2332```
2333
2334Tällä kurssilla vakiot kirjoitetaan suuraakkosin siten, että sanat
2335erotetaan alaviivalla (\_). Näin ne erottaa helposti muuttujien nimistä,
23232336jotka alkavat pienellä kirjaimella. Muitakin kirjoitustapoja on,
23242337esimerkiksi Pascal Casing on toinen yleisesti käytetty vakioiden
2325kirjoitusohje.</p>
2326<h2>7.7 Operaattorit</h2>
2327<p>Usein meidän täytyy tallentaa muuttujiin erilaisten laskutoimitusten
2328tuloksia. C#:ssa laskutoimituksia voidaan tehdä aritmeettisilla
2338kirjoitusohje.
2339
23407.7 Operaattorit
2341----------------
2342
2343Usein meidän täytyy tallentaa muuttujiin erilaisten laskutoimitusten
2344tuloksia. C\#:ssa laskutoimituksia voidaan tehdä aritmeettisilla
23292345operaatioilla (arithmetic operation), joista mainittiin jo kun teimme
23302346lumiukkoesimerkkiä. Ohjelmassa olevia aritmeettisia laskutoimituksia
2331sanotaan aritmeettisiksi lausekkeiksi (arithmetic expression).</p>
2332<p>C#:ssa on myös vertailuoperaattoreita (comparison operators), loogisia
2347sanotaan aritmeettisiksi lausekkeiksi (arithmetic expression).
2348
2349C\#:ssa on myös vertailuoperaattoreita (comparison operators), loogisia
23332350operaattoreita, bittikohtaisia operaattoreita (bitwise operators),
23342351arvonmuunto-operaattoreita (shortcut operators), sijoitusoperaattori =,
23352352is-operaattori sekä ehto-operaattori ?. Tässä luvussa käsitellään näistä
2336tärkeimmät.</p>
2337<h3>7.7.1 Aritmeettiset operaatiot</h3>
2338<p>C#:ssa peruslaskutoimituksia suoritetaan aritmeettisilla operaatiolla,
2353tärkeimmät.
2354
2355### 7.7.1 Aritmeettiset operaatiot
2356
2357C\#:ssa peruslaskutoimituksia suoritetaan aritmeettisilla operaatiolla,
23392358joista + ja - tulivatkin esille aikaisemmissa esimerkeissä.
2340Aritmeettisia operaattoreita on viisi.</p>
2341<p>Taulukko 3: Aritmeettiset operaatiot.</p>
2342<p>Operaat-\
2343 tori</p>
2344<p>Toiminto</p>
2345<p>Esimerkki</p>
2346<p>+</p>
2347<p>yhteenlasku</p>
2348<p>System.Console.WriteLine(1+2); // tulostaa 3</p>
2349<p>-</p>
2350<p>vähennyslasku</p>
2351<p>System.Console.WriteLine(1-2); // tulostaa -1</p>
2352<p>*</p>
2353<p>kertolasku</p>
2354<p>System.Console.WriteLine(2*3); // tulostaa 6</p>
2355<p>/</p>
2356<p>jakolasku</p>
2357<p>System.Console.WriteLine(6 / 2); // tulostaa 3</p>
2358<p>System.Console.WriteLine(7 / 2); // Huom! 3</p>
2359<p>System.Console.WriteLine(7 / 2.0); // 3.5</p>
2360<p>System.Console.WriteLine(7.0 / 2); // 3.5</p>
2361<p>%</p>
2362<p>jakojäännös (modulo)</p>
2363<p>System.Console.WriteLine(18 % 7); // tulostaa 4</p>
2364<h3>7.7.2 Vertailuoperaattorit</h3>
2365<p>Vertailuoperaattoreiden avulla verrataan muuttujien arvoja keskenään.
2359Aritmeettisia operaattoreita on viisi.
2360
2361Taulukko 3: Aritmeettiset operaatiot.
2362
2363Operaat-\
2364 tori
2365
2366Toiminto
2367
2368Esimerkki
2369
2370+
2371
2372yhteenlasku
2373
2374System.Console.WriteLine(1+2); // tulostaa 3
2375
2376-
2377
2378vähennyslasku
2379
2380System.Console.WriteLine(1-2); // tulostaa -1
2381
2382\*
2383
2384kertolasku
2385
2386System.Console.WriteLine(2\*3); // tulostaa 6
2387
2388/
2389
2390jakolasku
2391
2392System.Console.WriteLine(6 / 2); // tulostaa 3
2393
2394System.Console.WriteLine(7 / 2); // Huom! 3
2395
2396System.Console.WriteLine(7 / 2.0); // 3.5
2397
2398System.Console.WriteLine(7.0 / 2); // 3.5
2399
2400%
2401
2402jakojäännös (modulo)
2403
2404System.Console.WriteLine(18 % 7); // tulostaa 4
2405
2406### 7.7.2 Vertailuoperaattorit
2407
2408Vertailuoperaattoreiden avulla verrataan muuttujien arvoja keskenään.
23662409Vertailuoperaattorit palauttavat totuusarvon (true tai false).
23672410Vertailuoperaattoreita on kuusi. Lisää vertailuoperaattoreista luvussa
236813.</p>
2369<h3>7.7.3 Arvonmuunto-operaattorit</h3>
2370<p>Arvonmuunto-operaattoreiden avulla laskutoimitukset voidaan esittää
241113.
2412
2413### 7.7.3 Arvonmuunto-operaattorit
2414
2415Arvonmuunto-operaattoreiden avulla laskutoimitukset voidaan esittää
23712416tiiviimmässä muodossa: esimerkiksi x++; (4 merkkiä) tarkoittaa samaa
23722417asiaa kuin x = x+1; (6 merkkiä). Niiden avulla voidaan myös alustaa
2373muuttujia.</p>
2374<p>\
2375 \</p>
2376<p>Taulukko 4: Arvonmuunto-operaattorit.</p>
2377<p>Ope-raattori</p>
2378<p>Toiminto</p>
2379<p>Esimerkki</p>
2380<p>++</p>
2381<p>Lisäysoperaattori. Lisää muuttujan arvoa yhdellä.</p>
2382<p>int luku = 0;</p>
2383<p>\</p>
2384<p>System.Console.WriteLine(luku++); //tulostaa 0</p>
2385<p>System.Console.WriteLine(luku++); //tulostaa 1</p>
2386<p>System.Console.WriteLine(luku); //tulostaa 2</p>
2387<p>System.Console.WriteLine(++luku); //tulostaa 3</p>
2388<p>--</p>
2389<p>Vähennysoperaattori. Vähentää muuttujan arvoa yhdellä.</p>
2390<p>int luku = 5;</p>
2391<p>System.Console.WriteLine(luku--); //tulostaa 5</p>
2392<p>System.Console.WriteLine(luku--); //tulostaa 4</p>
2393<p>System.Console.WriteLine(luku); //tulostaa 3</p>
2394<p>System.Console.WriteLine(--luku); //tulostaa 2</p>
2395<p>System.Console.WriteLine(luku); //tulostaa 2</p>
2396<p>+=</p>
2397<p>Lisäys-operaatio.</p>
2398<p>int luku = 0;</p>
2399<p>luku += 2; //luku muuttujan arvo on 2</p>
2400<p>luku += 3; //luku muuttujan arvo on 5</p>
2401<p>luku += -1; //luku muuttujan arvo on 4</p>
2402<p>-=</p>
2403<p>Vähennys-operaatio</p>
2404<p>int luku = 0;</p>
2405<p>luku -= 2; // luku muuttujan arvo on -2</p>
2406<p>luku -= 1 // luku muuttujan arvon -3</p>
2407<p>*=</p>
2408<p>Kertolasku-operaatio</p>
2409<p>int luku = 1;</p>
2410<p>luku *= 3; // luku-muuttujan arvo on 3</p>
2411<p>luku *= 2; //luku-muuttujan arvo on 6</p>
2412<p>/=</p>
2413<p>Jakolasku-operaatio</p>
2414<p>double luku = 27;</p>
2415<p>luku /= 3; //luku-muuttujan arvo on 9</p>
2416<p>luku /= 2.0; //luku-muuttujan arvo on 4.5</p>
2417<p>%=</p>
2418<p>Jakojäännös-operaatio</p>
2419<p>int luku = 9;</p>
2420<p>luku %= 5; //luku-muuttujan arvo on 4</p>
2421<p>luku %=2; //luku-muuttujan arvo on 0</p>
2422<p>\</p>
2423<p>\</p>
2424<p>\</p>
2425<p>Lisäysoperaattoria (++) ja vähennysoperaattoria (--) voidaan käyttää,
2418muuttujia.
2419
2420\
2421 \
2422
2423Taulukko 4: Arvonmuunto-operaattorit.
2424
2425Ope-raattori
2426
2427Toiminto
2428
2429Esimerkki
2430
2431++
2432
2433Lisäysoperaattori. Lisää muuttujan arvoa yhdellä.
2434
2435int luku = 0;
2436
2437\
2438
2439System.Console.WriteLine(luku++); //tulostaa 0
2440
2441System.Console.WriteLine(luku++); //tulostaa 1
2442
2443System.Console.WriteLine(luku); //tulostaa 2
2444
2445System.Console.WriteLine(++luku); //tulostaa 3
2446
2447--
2448
2449Vähennysoperaattori. Vähentää muuttujan arvoa yhdellä.
2450
2451int luku = 5;
2452
2453System.Console.WriteLine(luku--); //tulostaa 5
2454
2455System.Console.WriteLine(luku--); //tulostaa 4
2456
2457System.Console.WriteLine(luku); //tulostaa 3
2458
2459System.Console.WriteLine(--luku); //tulostaa 2
2460
2461System.Console.WriteLine(luku); //tulostaa 2
2462
2463+=
2464
2465Lisäys-operaatio.
2466
2467int luku = 0;
2468
2469luku += 2; //luku muuttujan arvo on 2
2470
2471luku += 3; //luku muuttujan arvo on 5
2472
2473luku += -1; //luku muuttujan arvo on 4
2474
2475-=
2476
2477Vähennys-operaatio
2478
2479int luku = 0;
2480
2481luku -= 2; // luku muuttujan arvo on -2
2482
2483luku -= 1 // luku muuttujan arvon -3
2484
2485\*=
2486
2487Kertolasku-operaatio
2488
2489int luku = 1;
2490
2491luku \*= 3; // luku-muuttujan arvo on 3
2492
2493luku \*= 2; //luku-muuttujan arvo on 6
2494
2495/=
2496
2497Jakolasku-operaatio
2498
2499double luku = 27;
2500
2501luku /= 3; //luku-muuttujan arvo on 9
2502
2503luku /= 2.0; //luku-muuttujan arvo on 4.5
2504
2505%=
2506
2507Jakojäännös-operaatio
2508
2509int luku = 9;
2510
2511luku %= 5; //luku-muuttujan arvo on 4
2512
2513luku %=2; //luku-muuttujan arvo on 0
2514
2515\
2516
2517\
2518
2519\
2520
2521Lisäysoperaattoria (++) ja vähennysoperaattoria (--) voidaan käyttää,
24262522ennen tai jälkeen muuttujan. Käytettäessä ennen muuttujaa, arvoa
24272523muutetaan ensin ja mahdollinen toiminto esimerkiksi tulostus, tehdään
24282524vasta sen jälkeen. Jos operaattori sen sijaan on muuttujan perässä,
2429toiminto tehdään ensiksi ja arvoa muutetaan vasta sen jälkeen.</p>
2430<p>Huomaa! Arvonmuunto-operaattorit ovat ns. sivuvaikutuksellisia
2525toiminto tehdään ensiksi ja arvoa muutetaan vasta sen jälkeen.
2526
2527Huomaa! Arvonmuunto-operaattorit ovat ns. sivuvaikutuksellisia
24312528operaattoreita. Toisin sanoen, operaatio muuttaa muuttujan arvoa toisin
24322529kuin esimerkiksi aritmeettiset operaatiot. Seuraava esimerkki
2433havainnollistaa asiaa.</p>
2434<p>\
2435 \</p>
2436<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2530havainnollistaa asiaa.
2531
2532\
2533 \
2534
2535``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
24372536int luku1 = 5;
24382537int luku2 = 5;
24392538System.Console.WriteLine(++luku1); // tulostaa 6;
24402539System.Console.WriteLine(luku2 + 1 ); // tulostaa 6;
24412540System.Console.WriteLine(luku1); // 6
2442System.Console.WriteLine(luku2); // 5</code></p>
2443<h3>7.7.4 Aritmeettisten operaatioiden suoritusjärjestys</h3>
2444<p>Aritmeettisten operaatioiden suoritusjärjestys on vastaava kuin
2541System.Console.WriteLine(luku2); // 5
2542```
2543
2544### 7.7.4 Aritmeettisten operaatioiden suoritusjärjestys
2545
2546Aritmeettisten operaatioiden suoritusjärjestys on vastaava kuin
24452547matematiikan laskujärjestys. Kerto- ja jakolaskut suoritetaan ennen
24462548yhteen- ja vähennyslaskua. Lisäksi sulkeiden sisällä olevat lausekkeet
2447suoritetaan ensin.</p>
2448<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2549suoritetaan ensin.
2550
2551``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
24492552System.Console.WriteLine(5 + 3 * 4 - 2); //tulostaa 15
2450System.Console.WriteLine((5 + 3) * (4 - 2)); //tulostaa 16</code></p>
2451<h2>7.8 Huomautuksia</h2>
2452<h3>7.8.1 Kokonaisluvun tallentaminen liukulukumuuttujaan</h3>
2453<p>Kun yritetään tallentaa kokonaislukujen jakolaskun tulosta
2553System.Console.WriteLine((5 + 3) * (4 - 2)); //tulostaa 16
2554```
2555
25567.8 Huomautuksia
2557----------------
2558
2559### 7.8.1 Kokonaisluvun tallentaminen liukulukumuuttujaan
2560
2561Kun yritetään tallentaa kokonaislukujen jakolaskun tulosta
24542562liukulukutyyppiseen (float tai double) muuttujaan, voi tulos tallettua
24552563kokonaislukuna, jos jakaja ja jaettava ovat molemmat ilmoitettu ilman
2456desimaaliosaa.</p>
2457<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2564desimaaliosaa.
2565
2566``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
24582567double laskunTulos = 5 / 2;
2459System.Console.WriteLine(laskunTulos); // tulostaa 2</code></p>
2460<p>Jos kuitenkin vähintään yksi jakolaskun luvuista on desimaalimuodossa,
2461niin laskun tulos tallentuu muuttujaan oikein.</p>
2462<p><code>{.esimerkki-western lang="zxx" xml:lang="zxx"}
2568System.Console.WriteLine(laskunTulos); // tulostaa 2
2569```
2570
2571Jos kuitenkin vähintään yksi jakolaskun luvuista on desimaalimuodossa,
2572niin laskun tulos tallentuu muuttujaan oikein.
2573
2574``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
24632575double laskunTulos = 5 / 2.0;
2464System.Console.WriteLine(laskunTulos); // tulostaa 2.5</code></p>
2465<p>Liukuluvuilla laskettaessa kannattaa pitää desimaalimuodossa myös luvut,
2576System.Console.WriteLine(laskunTulos); // tulostaa 2.5
2577```
2578
2579Liukuluvuilla laskettaessa kannattaa pitää desimaalimuodossa myös luvut,
24662580joilla ei ole desimaaliosaa, eli ilmoittaa esimerkiksi luku 5 muodossa
24675.0.</p>
2468<p>Kokonaisluvuilla laskettaessa kannattaa huomioida seuraava:</p>
2469<p>``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
25815.0.
2582
2583Kokonaisluvuilla laskettaessa kannattaa huomioida seuraava:
2584
2585``` {.esimerkki-western lang="zxx" xml:lang="zxx"}
24702586int laskunTulos = 5 / 4;
2471System.Console.WriteLine(laskunTulos); // tulostaa 1</p>
2472<p>laskunTulos = 5 / 6;
2473System.Console.WriteLine(laskunTulos); // tulostaa 0</p>
2474<p>laskunTulos = 7 / 3;
2587System.Console.WriteLine(laskunTulos); // tulostaa 1
2588