6.3 For-silmukka
Yhteenveto
for (alkuarvo; ehto; laskuri) {
Komennot;
}
Esimerkin koodi on seuraava.
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup() {
size(400,200); // Ikkunan koko
background(255); // Taustaväri valkoinen
fill(0); // Tekstin väri musta
textSize(20); // Tekstin koko 20
}
void draw () {
for (int a = 1; a <= 12; a++) { // a = 1,2,3,4,5,...,12
text(a,30*a,50); // Tulosta muuttuja a
}
for (int b = 10; b > 0; b--) { // b = 10,9,8,7,...,1
text(b,300-30*b,100);
}
}
Toisen esimerkin koodi on seuraava.
|
void setup() {
size(400,400); // Ikkunan koko
background(255); // Taustaväri valkoinen
fill(255,0,0); // Täyttöväri punainen
noLoop(); // Vain yksi toisto void draw ()-lohkossa
}
void draw () {
translate(200,200); // Origo ikkunan keskelle
for (int a=0; a < 360; a=a+90) { // a = 0, 90, 180, 270
rotate(radians(90)); // Pyöritä koordinaatistoa 90° myötäpäivään
ellipse(100,0,100,100); // Piirrä ympyrä
}
}
For-silmukka
for (alkuarvo; ehto; laskuri) {
komennot;
}
Kaaviokuvana silmukan voisi kuvata seuraavasti.
https://peda.net/id/879fe3b6897
Esimerkiksi ohjelma, joka tulostaa kymmenen kertaa hei-sanan, voidaan kirjoittaa muodossa:
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup () {
size(400,400); // Ikkunan koko
background(255,255,0); // Taustaväri keltainen
fill(0); // Tekstin väri musta
textSize(28); // Tekstin koko 28
}
void draw () {
for (int a = 1; a<=10; a++) {
text("Hei",100,a*30);
}
}
Kuten huomataan, for-silmukassa on kokonaislukumuuttujan alkuarvon asettaminen, ehto ja laskuri kaikki samassa lauseessa samalla rivillä. For-lause on tarkoitettu tilanteisiin, jossa toistoja on tietty vakiomäärä. For-silmukan voisi suomentaa: Toista silmukkaa, niin kauan kun a on pienempi tai yhtä suuri kuin kymmenen. Koska a:n alkuarvo on 1, käytännössä a saa arvoja: 1,2,3,4,... Kun a saa arvon 11, ehto ei enää ole voimassa ja toisto loppuu. Ohjelman suoritus näyttää hidastettuna tältä.
For-silmukan toimivuutta voidaan tutkia sijoittamalla taulukkoon a:n arvoja.
a | EHTO: (a <= 10) | text("Hei",100,a*30); |
1 | (1 <= 10), tosi | text("Hei,100,30); |
2 | (2 <= 10), tosi | text("Hei,100,60); |
3 | (3 <= 10), tosi | text("Hei,100,90); |
4 | (4 <= 10), tosi | text("Hei,100,120); |
5 | (5 <= 10), tosi | text("Hei,100,150); |
6 | (6 <= 10), tosi | text("Hei,100,180); |
7 | (7 <= 10), tosi | text("Hei,100,210); |
8 | (8 <= 10), tosi | text("Hei,100,240); |
9 | (9 <= 10), tosi | text("Hei,100,280); |
10 | (10 <= 10), tosi | text("Hei,100,300); |
11 | (11 <= 10), epätosi | - |
Alussa a saa arvon 1, jota kasvatetaan joka kierroksella yhdellä. Kun a saa arvon 11, niin ehto a <= 10 ei enää ole voimassa ja silmukan toisto loppuu. Kun toisto loppuu, niin silloin emme tulosta mitään.
Kuinka for-lause kirjoitetaan, jos haluamme tulostaa tekstin: "Hei" kahdeksan kertaa?
for (int a = 1; a<=8; a++) {
text("Hei",100,a*30);
}
Yksinkertaisesti muutamme ehtoon luvun 8 eli a <=8. Silmukkaan toistetaan niin kauan kunnes a on pienempi tai yhtä suuri kuin kahdeksan. Kun a saa arvon yhdeksän, niin toisto lopetetaan.
Kuinka tehdään for-silmukka, joka tulostaa luvut 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 ja 25 allekkain?
for (int a = 15; a<=25; a++) {
text(a,100,a*30-400);
}
For-silmukassa alkuarvo on 15 ja ehdossa sanotaan, että silmukkaan toistetaan niin kauan, kunnes a on pienempi tai yhtä suuri kuin 25. Toisto siis loppuu, kun a on 26. Huomaa, että tulostuslauseessa y-koordinaatit voidaan tulostaa arvolla: -400+a*30. Pelkkä a*30 vie liian alas, koska 15 * 30 = 450. Teemme siis korjauksen tähän vähentämällä tästä arvosta 400, jolloin y-koordinaatin aloitusarvo on 50. Laskutoimitus a*30 tulostaa y-koordinaatit 30 askeleen välein.
Esimerkki: Laskurin ja for-silmukan vertailua

Tutkitaan, mitä eroavuuksia on, kun toisto tehdään laskurin avulla tai for-silmukan avulla. Tehdään ohjelma, joka tulostaa luvut ykkösestä kymmeneen.
Tehdään aluksi ohjelma käyttäen laskuria ja if-lausetta.
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
int a = 0;
void setup () {
size(400,200); // ikkunan koko
textSize(30); // Tekstin koko 30
background(255); // Tyhjennä tausta
fill(0); // Täyttöväri musta
}
void draw() {
a++; // Laskuri 1,2,3,4,5,6,...
if (a <= 10) { // Jos laskuri alle tai yhtäsuuri kuin 10, niin
text(a,a*30,100); // Tulosta laskuri
}
}
Tehdään sama ohjelma uudestaan käyttäen for-silmukkaa.
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup () {
size(400,200); // ikkunan koko
textSize(30); // Tekstin koko 30
background(255); // Tyhjennä tausta
fill(0); // Täyttöväri musta
}
void draw() {
for (int a = 1; a<=10; a++) {
text(a,a*30,100);
}
}
Eroavuuksia
- For-silmukassa laskurille alkuarvo annetaan silmukassa, mutta pelkkää laskuria käyttäen alkuarvo on annettava jo heti ohjelman alussa.
- Pelkkää laskuria käyttäen toistojen määrä voidaan rajoittaa if-lauseella. For-silmukassa toistojen määrä rajoitetaan ehdolla, joka on silmukassa.
- Pelkkää laskuria käyttäen laskuri (a++) laitetaan void draw ()-lohkoon. Koska void draw ()-lohko on ikuisessa silmukassa, niin siksi laskuri kasvaa. For-silmukassa laskuri on itse lausekkeessa. Jos laitat void setup ()-lohkoon komennon: noLoop(); niin ylemmässä esimerkissä tulostuu vain ensimmäinen numero, mutta alemassa esimerkissä tulostuu kaikki numerot. For-silmukka toimii kuin oma alilohko, joka suoritetaan kerralla loppuun asti.
Tekstiä voi myös liikutella translate(x,y); komennolla. Muuta edellinen ohjelma tällöin muotoon.
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup () {
size(400,200); // ikkunan koko
textSize(30); // Tekstin koko 30
background(255); // Tyhjennä tausta
fill(0); // Täyttöväri musta
}
void draw() {
for (int a = 1; a<=10; a++) {
pushMatrix(); // Koordinaatisto muistiin
translate(a*30,100); // Liikuta koordinaatistoa
text(a,0,0); // Muuttujan a arvo tulostetaan paikkaan (0,0)
popMatrix(); // Palautetaan koordinaatisto muistista
}
}
Sinulla on vielä kolmaskin vaihtoehto käytettävissä eli while-lause. While-lausetta käytettäessä laskuri on laitettava lauseen sisälle. While-lausetta toistetaan niin kauan kuin ehto on voimassa. Jossain vaiheessa, kun laskurin arvo kasvaa tarpeeksi suureksi, ehto ei enää ole voimassa while-lauseessa ja while-lausetta ei enää suoriteta. Laskuri-muuttuja on ns. globaalimuuttuja ja laskurin alkuarvo on annettava heti ohjelman alussa. Ohjelma, joka tulostaa luvut yhdestä kymmeneen while-lausen avulla on seuraavanlainen.
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
int a = 1;
void setup () {
size(400,200); // ikkunan koko
textSize(30); // Tekstin koko 30
background(255); // Tyhjennä tausta
fill(0); // Täyttöväri musta
}
void draw() {
while ( a <= 10) {
text(a,a*30,100);
a++;
}
}
Esimerkki: Pyörivä neliö
|
// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
void setup () {
size(400,400); // Ikkunan koko
background(0); // Taustaväri musta
strokeWeight(3); // Reunaviivan paksuus
noFill(); // Ei täyttöä
noLoop(); // Lohko void draw () suoritetaan vain kerran
}
void draw () {
translate(200,200); // Origo ikkunan keskelle
for (int a = 0; a < 30; a++) {
rotate(radians(12)); // Pyöritä koordinaatistoa
stroke(random(255),random(255),random(255)); // Arvotaan reunaviivan väri
rect(-100,-100,200,200); // Piirrä neliö
}
}
Ohjelman tulostus on seuraava.
Koska void setup ()-lohkossa oli komento: noLoop(), niin for-silmukka suoritetaan vain kerran. Ja lopputuloksena on staattinen kuvio, mutta ota pois komento noLoop() ja kuviosta tuleekin välkkyvä. Välkkyminen johtuu siitä, että void draw ()-lohko on ikuisessa silmukassa. For-silmukan avulla tehdään aina tietty määrä toistoja ja se sopii vaikka emme päivitä void draw ()-lohkoa.
Tässä kulmaa muutetaan 12 astetta 30 kertaa, niin tällöin kuviota pyöritetään täysi ympyrä eli 12°∙30 = 360°.
Kaksi for-silmukkaa
|
// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
void setup() {
size(400,400); // Ikkunan koko
background(255); // Taustaväri valkoinen
fill(0,0,255); // Täyttöväri sininen
noStroke(); // Ei reunaviivaa
}
void draw () {
for (int b=1; b <= 60; b++) { // b=1,2,3,...,60
for (int a=1; a <= 30; a++) { // a = 1,2,3,...,30
ellipse(a*6,b*6,3,3);
// Piirrä ympyrä paikkaan (a*6,b*6)
}
}
}
Ohjelman tulostus on seuraava.

Kun käytämme piirtokomennossa samoja muuttujia kuin for-silmukoissa, niin jokainen piste voidaan piirtää eri paikkaan. Sisemmällä silmukalla saamme määrättyä pisteen vaakasuuntaisen paikan ja ulommalla silmukalla saamme määrättyä pisteen pystysuuntaisen paikan. Koska ulointa silmukkaa toistetaan 60 kertaa, niin myös sisintä silmukkaa, jossa on 30 toistoa, toistetaan 60 kertaa. Voit kokeilla muuttaa toistojen määrää.
Laskuri ja for-silmukka yhdessä
Tehdään ohjelma, jossa for-silmukan avulla piirretään 13 kappaletta sinisiä ympyröitä ja laskurin avulla laitetaan tämä ympyrä jono pyörimään.
|
// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
int b=0; // Laskurin alkuarvo
void setup () {
size(400,400); // Ikkunan koko
fill(0,0,255); // Täyttöväri sininen
frameRate(60); // Pyörimisnopeus
}
void draw () {
background(0); // Taustaväri musta
translate(200,200); // Origo ikkunan keskelle
b++; // Kasvata laskuria yhdellä
rotate(radians(b)); // Pyöritä koordinaatistoa
for (int a = -6; a <= 6; a++) { // a = -6,-5,-4,...,6
ellipse(a*30,0,20,20); // 13 kpl ympyröitä
}
}
Kokeile siirtää background(0); komento void setup () lohkoon. Kuinka muuttaisit pyörimissuunnan?
Esimerkki: 1000 ympyrää
|
// Ohjelman tehnyt e-Oppi Oy
// 30.8.2017
void setup () {
size(300,300); // ikkunan koko
background(255); // Taustaväri valkoinen
noLoop(); // Ei silmukkaa
}
void draw () {
for (int a = 1; a <= 1000; a++) { // Toista 1000-kertaa
int x = round(random(300)); // ympyrän satunnainen paikka
int y = round(random(300)); // ympyrän satunnainen paikka
int R = round(random(255)); // Punainen
int G = round(random(255)); // Vihreä
int B = round(random(255)); // Sininen
fill(R,G,B); // Satunnainen täyttöväri
ellipse(x,y,20,20); // Ympyrä satunnaiseen paikkaan
}
}
1000 toistoa saadaan for-silmukalla. Alussa a muuttuja saa arvon 1, jota kasvatetaan yhdellä jokaisella kierroksella. Kun a saa arvon 1001, niin ehto ei enää ole voimassa ja toisto lopetetaan. Lisäksi on laitettava komento: noLoop(); joka toistaa vain void draw()-lohkon vain kerran. Mikäli poistat noLoop() komennon, niin toistoja on ääretön määrä. Ohjelman esimerkkiajo voi näyttää esimerkiksi tältä.
Esimerkki: Suoran yhtälö y = kx + b
|
// Ohjelman tehnyt e-Oppi Oy
// 30.9.2017
void setup () {
size(400,400); // Ikkunan koko
background(255); // Taustaväri valkoinen
strokeWeight(3); // Viivan paksuus 3
}
void draw () {
stroke(0); // Viivanväri musta
translate(200,200); // Origo ikkunan keskelle
scale(1,-1); // Peilaa y-akseli eli muodosta xy-koordinaatisto
line(-200,0,200,0); // x-akseli
line(0,200,0,-200); // y-akseli
float k = -1; // Kulmakerroin (kokeile muuttaa tämä)
float b = 0; // Vakiotermi, Voit antaa arvoja väliltä [-200,200]
stroke(255,0,0); // Viivanväri punainen
for (int x = -200; x < 200; x++) {
float y = k*x+b;
ellipse(x,y,1,1);
}
}

Kokeile muuttaa kulmakeroimen k arvoa, esimerkiksi: k = 2; k = 0.5; k = -0.1; tai k = -3; Mitä havaitset?