7.4 Arvon palauttava funktio
Yhteenveto
Tehdään kaksi aliohjelmaa. Toinen laskee suorakulmion pinta-ala ja toinen laskee suorakulmion piirin. Kun aliohjelmaa kutsutaan pääohjelmassa komennolla: piiri(3,4), niin aliohjelma palauttaa laskemansa suorakulmion piirin arvon takaisin eli 14.0, joka sijoitetaan pääohjelmassa muuttujalle p. Vastaavasti kun aliohjelmaa kutsutaan pääohjelmassa komennolla: pinta_ala(3,4), niin aliohjelma palauttaa laskemansa suorakulmion pinta-alan arvon takaisin eli 12, joka sijoitetaan pääohjelmassa muuttujalle A.
Funktio, joka palauttaa arvon
Jos aliohjelma laskee laskuja, niin voisiko aliohjelma palauttaa laskemansa arvon takaisin pääohjelmaan? Kyllä voi. Tämä johtaa funktioon eli aliohjelmaan, joka palauttaa jonkin arvon. Palautetun arvon voimme sijoittaa esimerkiksi muuttujalle pääohjelmassa. Arvon palauttaminen aliohjelmassa tapahtuu return komennolla. Funktio, joka palauttaa jonkin arvon voidaan määritellä yleisesti.
tietotyyppi aliohjelman nimi (aliohjelmaan välitettävät muuttujat) {
Komennot;
return muuttuja;
}
Huomaa, että palauttavassa funktiossa ei käytetä void määrettä, vaan funktion eteen lisätään tietotyyppi. Käytännössä funktion tietotyyppi on sama kuin palautettavan muuttujan tietotyyppi. Esimerkiksi funktio, joka laskee suorakulmion pinta-alan, voidaan kirjoittaa seuraavasti.
- Pääohjelmassa kutsutaan aliohjelmaa nimeltä: pinta_ala(6,8);
- Aliohjelmassa muuttuja a saa arvon 6 ja muuttuja b saa arvon 8.
- Aliohjelma laskee paikalliselle muuttujalle: ala, arvon 6*8 = 48.
- Aliohjelma palauttaa takaisin pääohjelmalle aliohjelman ala-muuttujan arvon, joka on 48.
- Pääohjelmassa on oma paikallinen muuttuja ala, joka saa arvokseen aliohjelman palauttaman arvon eli 48. Huomaa, että voit käyttää aliohjelmassa ja pääohjelmassa samannimisiä muuttujia, koska muuttujat ovat paikallisia.
- Tämän jälkeen pääohjelman suoritus jatkuu ja voit vaikka tulostaa muuttujien arvot.
Kokonainen ohjelma voisi olla esimerkiksi seuraavanlainen
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup () {
size(600,200); // ikkunan koko
background(255); // Taustaväri valkoinen
textSize(30); // Tekstin koko
fill(0); // Tekstin väri
}
void draw() {
int kanta = 6;
int korkeus = 8;
int ala = pinta_ala(kanta,korkeus);
text("Suorakulmion kanta = "+kanta,10,50);
text("Suorakulmion korkeus = "+korkeus,10,100);
text("Suorakulmion pinta-ala = "+ala,10,150);
}
int pinta_ala(int a, int b) {
int ala = a*b;
return ala;
}
Kun ajat ohjelman, niin se näyttää tältä.

Ohjelman suoritusta voidaan havainnollistaa seuraavasti:

Aliohjelma pinta_ala(a,b) saa syötteenä arvot 6 ja 8 ja aliohjelma tulostaa tulosteena arvon 48, joka sijoitetaan pääohjelmassa muuttujalle ala.
Esimerkki: Desimaaliluvuilla laskeminen
Tehdään ohjelma, joka laskee suorakulmio piirin. Piiri lasketaan kaavalla: piiri = 2*kanta + 2*korkeus. Haluamme, että aliohjelma laskee desimaalilukuja. Kokonainen ohjelma on seuraava.
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup () {
size(600,200); // ikkunan koko
background(255); // Taustaväri valkoinen
textSize(30); // Tekstin koko
fill(0); // Tekstin väri
}
void draw() {
float kanta = 2.5;
float korkeus = 3.2;
float p = piiri(kanta,korkeus);
text("Suorakulmion kanta = "+kanta,10,50);
text("Suorakulmion korkeus = "+korkeus,10,100);
text("Suorakulmion piiri = "+p,10,150);
}
float piiri(float a, float b) {
float p = 2*a+2*b;
return p;
}
Kun katsotaan aliohjelmaa, huomataan, että aliohjelma alkaa sanalla float eli aliohjelma palauttaa desimaalilukuarvon pääohjelmalle. Myös kaikki muuttujat on määritelty desimaalilukumuuttujiksi. Ohjelma tulostaa seuraavaa.

Aliohjelman toimintaa voidaan havainnollistaa seuraavasti.

Funktio eli aliohjelma piiri(a,b) on kuin kone, johon syötetään kannan ja korkeuden arvot, jonka jälkeen funktiokone tulostaa ulos piirin arvon, joka sitten voidaan sijoittaa pääohjelmassa muuttujalle p.
Tärkeintä on huomata, että palautettavan arvon tietotyyppi eli aliohjelman tietotyyppi on oltava sama kuin pääohjelmassa olevan muuttujan tietotyyppi, johon arvo sijoitetaan. Eli seuraava määrittely ei toimi, koska tietotyyppi on eri.
void draw() {
int kanta = 2;
int korkeus = 3;
int p = piiri(kanta,korkeus);
}
float piiri(int a, int b) {
int p = 2*a+2*b;
return p;
}
Mutta seuraava sitä vastoin toimii, koska tietotyypit ovat samat.
void draw() {
int kanta = 2;
int korkeus = 3;
float p = piiri(kanta,korkeus);
}
float piiri(int a, int b) {
int p = 2*a+2*b;
return float(p);
}
Vaikka alkuarvot ovat kokonaislukuja, niin aliohjelma voi palauttaa toisen tietotyypin muuttujan. Palautettava desimaaliluku pitää pääohjelmassa myös sijoittaa float-tyyppiselle muuttujalle.
Esimerkki: Viikonpäivä
VIIKONPÄIVÄ | TULOSTUS |
---|---|
maanantai | Maanantaina makkaraa |
tiistai | Tiistaina tikkaria |
keskiviikko | Keskiviikkona keksejä |
torstai | Torstaina torttuja |
perjantai | Perjantaina pekonia |
lauantai | Lauantaina lakritsia |
sunnuntai | Sunnuntaina suklaata |
Ohjelman ratkaisu on seuraavanlainen.
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup () {
size(600,300); // Ikkunan koko
background(255); // Taustaväri valkoinen
fill(0); // Tekstin väri musta
textSize(30); // Tekstin koko 30
}
void draw () {
String nyt= "lauantai";
String kommentti = viikonpaiva(nyt);
text("Tänään on: "+nyt,10,50);
text(kommentti,10,100);
}
String viikonpaiva(String paiva){
String vastaus;
if (paiva == "maanantai") {
vastaus = "Maanantaina makkaraa";
} else if (paiva == "tiistai") {
vastaus = "Tiistaina tikkaria";
} else if (paiva == "keskiviikko") {
vastaus = "Keskiviikkona keksejä";
} else if (paiva == "torstai") {
vastaus = "Torstaina torttuja";
} else if (paiva == "perjantai") {
vastaus = "Perjantaina pekonia";
} else if (paiva == "lauantai") {
vastaus = "Lauantaina lakritsia";
} else if (paiva == "sunnuntai") {
vastaus = "Sunnuntaina suklaata";
} else {
vastaus = "Ei ole viikonpäivä";
}
return vastaus;
}
Ohjelma tulostaa seuraavaa:
Ohjelman suoritusta voidaan havainnollistaa seuraavasti.
Funktio eli aliohjelma viikonpaiva saa syötteenä arvon "lauantai" ja tulostaa ulos kommentin: "Lauantaina lakritsia". Tämä arvo sijoitetaan pääohjelmassa muuttujalle kommentti.
Toimintaperiaate samanlainen kuin aikaisemmin. Koska nyt tietona välitetään merkkijonoja, niin välitettävä tieto on laitettava lainausmerkkien (" ") sisään. Aliohjelman tietotyyppi on myös String, joka pitää laittaa heti aliohjelman alkuun. Palautettava vastaus-muuttujan arvo sijoitetaan pääohjelmassa kommentti-muuttujalle, jossa pitää olla sama tietotyyppi, kuin aliohjelmassa eli String.
Esimerkki: Arvo kirjain
Ohjelman koodi on seuraava.
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup () {
size(600,200); // Ikkunan koko
fill(0); // Tekstin väri musta
textSize(30); // Tekstin koko 32
noLoop(); // Vain yksi toisto
}
void draw () {
background(255); // Tyhjennä tausta
char mika_merkki = arvo_kirjain(97,122); // Kutsutaan aliohjelmaa
text("Arvottu merkki on "+mika_merkki,10,100); // Tulostetaan merkki
}
char arvo_kirjain(int a, int b) {
int numero = round(random(a,b)); // Arvotaan kokonaisluku väliltä a…b
char merkki = char(numero); // Muuttaa numeron merkiksi
return merkki; // Palautetaan merkki
}
Kun ajat ohjelman, niin ensin pääohjelma kutsuu aliohjelmaa: arvo_kirjain(a,b), missä a:lle ja b:lle välitetään kokonaislukuarvo. Aliohjelma arpoo kokonaisluvun väliltä [a,b] ja muuttaa arvotun luvun merkiksi. Tämä merkki palautetaan takaisin pääohjelmaan, siksi aliohjelman tietotyyppi on char. Sama tietotyyppi on pääohjelmassa mika_merkki-muuttujalla. Ohjelman tulostus näyttää esimerkiksi tältä.
Ohjelman suoritusta voidaan havainnollistaa seuraavasti.
Aliohjelma arvo_kirjain(a,b) saa syötteenä luvut 97 ja 122, jonka jälkeen aliohjelma arpoo luvun tältä väliltä ja muuttaa luvun sitä vastaavaksi merkiksi ascii-taulukossa. Aliohjelma tulostaa esimerkiksi merkin 'k' ulos, joka sijoitetaan pääohjelmassa mika_merkki-nimiselle muuttujalle.
Rekursio
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup() {
size(400, 400); // Ikkunan koko
background(255); // Taustaväri valkoinen
noFill(); // Ei täyttöä
noLoop(); // Pääohjelma toisetaan vain kerran
}
void draw() {
ympyra(200,200,200); // Kutsutaan aliohjelmaa
}
void ympyra(float x, float y, float r) {
ellipse(x, y, r*2, r*2);
}
Ohjelma tulostaa nyt yhden ympyrän. Ympyrän keskipiste on (200, 200) ja säde on 200.

Lisätään aliohjelmaan kutsu, joka kutsuu itseään. Jotta ohjelma ei joudu ikuiseen silmukkaan, niin lisätään ohjelmaan laskuri, jonka avulla voimme määrätä kutsujen määrän.
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
int a = 1;
void setup() {
size(400, 400); // Ikkunan koko
background(255); // Taustaväri valkea
noFill(); // Ei täyttöä
noLoop(); // Ei toistoa
}
void draw() {
ympyra(200, 200, 200);
}
void ympyra(float x, float y, float r) {
a++;
ellipse(x, y, r*2, r*2);
if (a <= 100) { // Sata toistoa
ympyra(x, y,r*0.9); // Aliohjelma kutsuu itseään
}
}

Koska aliohjelman kutsussa on r*0.9, kutsuttavan ympyrän säde kutistuu 10 % eli menee 0,9-kertaiseksi. Laskuri pitää huolen siitä, että piirrettäviä ympyröitä on 100 kappaletta. Jos laskuria ei olisi, niin todennäköisesti ohjelma joutuisi ikuiseen silmukkaan ja ohjelman suoritustilan jumittumiseen.