A ciklus

A ciklus egy olyan nyelvi formula, amivel dolgokat meg tudunk ismételni. A kottában is van ismétlésjel, amivel még egyszer meg kell ismételni azt, amit már egyszer elénekeltünk.

Az A-star persze nem csak egyszer tudja megismételni, hanem bárhányszor, vagy bármeddig.

A for-ciklus

A for-ciklus a C nyelvben egy svájci bicska: mindenre jó, de igazából egyáltalán nem kényelmes használni. A legtöbb esetben arra használjuk, hogy egy utasításblokkot megismételjünk:

for (int i=0;i<500;i++) {
    // amit ide írunk, azt ismétli 500-szor
}

Ahogy ígértem, kissé kényelmetlen, pontosvesszők vannak benne, meg valaki integet is... de nézzük csak!

Ha meg akarod fejteni, akkor ez benne a logika:

for (változótípus változónév=kezdőérték;ciklusbanMaradásiFeltétel;változóNövelése) {
    // amit ide írunk, azt ismétli amíg a ciklusbanMaradásiFeltétel teljesül
}

Azt csinálja, hogy van egy változó, a ciklusváltozó. Jelen esetben ezt i-nek neveztük. A ciklusváltozó kezdeti értéke 0 lesz - ez a kezdőérték. Utána végrehajtja a ciklus magját, azaz a kapcsos zárójelek közé írt utasításokat. Ezután az i értékét növel 1-el, az i++ kifejezés ezt jelenti. Majd megnézi, hogy i értéke kisebb-e mint 500. Ha még kisebb, akkor újra végrehajtja a ciklus magját, stb... de ha elérte az 500-at, akkor a ciklusból kilép - azaz a záró kapcsos zárójel után folytatja a programot.

De ha nem akarod megfejteni, akkor elég használni!

Na szóval, akkor sziréna mehet?

void setup() {
    pinMode(9, OUTPUT);
}

void loop() {
    // felfelé
    for (int freq=220;freq<440;freq++) {
        tone(9,freq);
        delay(10);
    }   
}

Majdnem olyan, amit ígértem. Épp csak hogy:

Visszafelé is megy?

Vajon tudunk lefelé is menni? Persze hogy tudunk! Csak okosan kell megválasztani a for ciklus megadását: a kezdőérték a nagyobb, addig kell menni amíg a ciklusváltozó nagyobb, mint a végérték, és minden körben csökkenteni kell a ciklusváltozó értékét. Szóvak minden pont fordítva!

void setup() {
    pinMode(9, OUTPUT);
}

void loop() {
    // felfelé
    for (int freq=220;freq<440;freq++) {
        tone(9,freq);
        delay(10);
    }   

    // lefelé
    for (int freq=440;freq>220;freq--) {
        tone(9,freq);
        delay(10);
    }   
}

Gyorsabban is megy?

Ha a delay értéke kisebb, akkor persze gyorsabb a szirénázás! Csináljunk egy sziréna függvényt:

void setup() {
    pinMode(9, OUTPUT);
}

void alarm(int speed) {
    // felfelé
    for (int freq=220;freq<440;freq++) {
        tone(9,freq);
        delay(speed);
    }   

    // lefelé
    for (int freq=440;freq>220;freq--) {
        tone(9,freq);
        delay(speed);
    }     
}

void loop() {
    alarm(10);
    alarm(1);
    alarm(1);
    alarm(1);
}

Ahogy látod, a loop-ban egy lassabb szirénázás van (10-es delay-al), és aztán három gyorsabb. A három gyorsabbat is lehet ám ciklusba tenni:

void setup() {
    pinMode(9, OUTPUT);
}

void alarm(int speed) {
    // felfelé
    for (int freq=220;freq<440;freq++) {
        tone(9,freq);
        delay(speed);
    }   

    // lefelé
    for (int freq=440;freq>220;freq--) {
        tone(9,freq);
        delay(speed);
    }   

}

void loop() {
    alarm(10);
    for (int i=0;i<3;i++) {
        // ez haromszor
        alarm(1);
    }
}

Abba is tudja hagyni?

Ha mindent kipróbáltál, akkor mostanra már elég idegesítő a sziréna hangja. A tone() úgy működik, hogy elindít egy hanglejátszást - és az innentől folyamatosan sípol. Ahhoz hogy kikapcsold, a noTone() kell, aminek a paramétere az a port, amin a csipogó van.

void setup() {
    pinMode(9, OUTPUT);
}

void beepAlarm(int speed) {
    for (int i=0;i<5;i++) {
        tone(9,440);
        delay(speed);
        noTone(9);
        delay(speed);  
    }
}

void loop() {
    beepAlarm(500);
    beepAlarm(100);
}

Mit is csináltam? Van egy beepAlarm függvény, ami 5-ször megismétli azt, hogy tone(), meg várunk kicsit a sípolás közben, meg noTone(), aztán csendben ismét várunk egy kicsit.

A loop-ban pedig ezt a függvényt használom, először egy lassabb csipogásos szirénának 500-as delay-el, majd egy gyorsabbnak 100-as delay-el.

Feladat

Készíts különféle sziréna-függvényeket! Az egyik lehet ez a folyamatosan változó hangú sziréna, mint az alarm(), a másik lehet az előző oldalon lévő kétféle hangú sziréna. Használd a szaggatott szirénát is, mint a beepAlarm().

Ezekből for-ciklusokkal építs egy teljesen rémisztően összetett sziréna-előadást!

Mit tanultunk ebből?

A for-ciklus arra való, hogy dolgokat megismételjünk valamennyiszer. Eközben egy változó értéke változik, és ha akarjuk, a ciklusban felhasználhatjuk ezt az értéket.