Cél és előfeltétel

Ha tíz nap bevételét összesíted, nem szeretnél tízszer majdnem ugyanazt a sort leírni. A ciklus egy műveletsor ismétlését fejezi ki, az akkumulátor pedig az addigi feldolgozás eredményét őrzi. Ebben a leckében nem a legrövidebb megoldást keressük: azt szeretnénk pontosan látni, mi történik az első, a következő és az utolsó elemnél.

Előfeltétel a döntések és logikai feltételek ismerete. A példákat külön edition 2024 főprogramként futtasd. Mielőtt végrehajtod őket, írj egy kis táblázatot a feldolgozott értékről és az összeg vagy számláló új állapotáról. A papíron végigkövetett három lépés gyakran többet segít, mint a ciklus sokszori újraolvasása.

Mit jelent az addigi eredmény?

Összegzésnél az akkumulátor kezdőértéke nulla. Minden lépésben hozzáadjuk az aktuális számot; így a változó mindig a már feldolgozott elemek összegét jelenti. Ez az állítás a ciklus előtt is igaz: még semmit nem dolgoztunk fel, és az üres összeg nulla. Az ilyen végig megmaradó jelentés jó kapaszkodó a ciklus megírásakor.

Számlálásnál szintén nulla a kezdőérték, de nem az elemet adjuk hozzá. Akkor növeljük eggyel, ha az elem megfelel a feltételnek. A kettő összekeverése gyakori kezdő hiba: három magas érték összege és a magas értékek darabszáma más kérdés. A változónév mondja ki, melyik eredményt őrzöd, az állítás pedig konkrét adatokkal különböztesse meg őket.

Tartományok és feldolgozási határok

A kezdőponttól a végpont előttig tartó tartomány nem tartalmazza a felső határt. A két pont és egyenlőségjel együtt viszont bevonja a végpontot. Ha egytől ötig akarsz összegezni, ezt a különbséget tudatosan válaszd meg. Ne az első teszt után találgasd, kell-e még egyet hozzáadni a végén; előbb döntsd el, mely értékek legyenek a bemenetben.

A for ciklus egy tartomány vagy más bejárható érték elemeit veszi sorra. A lecke későbbi feladataiban rögzített tömböket is bejárunk; a részletes tömbműveletek a következő leckében jönnek. Most elegendő annyi, hogy a szögletes zárójelek közötti számok sorrendben érkeznek. A ciklusváltozó minden lépésben az aktuális elemet nevezi meg.

Megállás és kihagyás

A break lezárja a legbelső ciklust. Ez eltér attól, amikor csak az aktuális elemet nem számoljuk bele az eredménybe, és a következővel folytatjuk. Egy lezáró jel előtti bevételek összegzésénél valóban megállás kell; egy alacsony mérés kihagyásánál viszont folytatni szeretnénk. A szabály megfogalmazásában a „többit már ne vizsgáld” és a „ezt ne számold” külön mondat.

A while akkor hasznos, ha az ismétlés végét logikai feltétel szabja meg. A feltételt befolyásoló állapotnak változnia kell, különben végtelen ciklust készíthetsz. Most a véges, ismert adatsorhoz for ciklust választunk, mert a bejárás határa ebből közvetlenül látszik. Nem kell minden feladatot minden ciklusfajtával átírnod ahhoz, hogy a szabályt megértsd.

1. feladat: zárt tartomány összege

Számold ki az egytől ötig terjedő egész számok összegét, az ötöt is beleértve. Ne írd le az öt szám külön összeadását: használj tartományt és módosítható akkumulátort. Ugyanebben a ciklusban számold meg, hány elem érkezett. Az eredmény így a számolást és a bejárás határát is ellenőrzi.

Megoldás
fn main() {
    let mut osszeg: u32 = 0;
    let mut darab: u32 = 0;
    for szam in 1..=5 {
        osszeg += szam;
        darab += 1;
    }
    assert_eq!(osszeg, 15);
    assert_eq!(darab, 5);
    let mut ures_darab = 0;
    for _ in 0..0 { ures_darab += 1; }
    assert_eq!(ures_darab, 0);
}

A nulla hosszú tartomány egyetlen iterációt sem végez, így az akkumulátor kezdőértéke változatlan marad. Ez segít megérteni, miért fontos a megfelelő kezdőérték kiválasztása.

2. feladat: küszöböt elérő mérések

A megadott mérések közül számold meg a legalább húszasakat. A pontosan húszas érték is számítson, az alatta lévő ne. A feladat darabszámot kér, nem összeget. A második, csupa alacsony adatot tartalmazó sorozatot is dolgozd fel, hogy a nulla eredmény ne csak feltételezés maradjon.

Megoldás
fn main() {
    let mut magas = 0;
    for meres in [19, 20, 25, 10] {
        if meres >= 20 { magas += 1; }
    }
    assert_eq!(magas, 2);
    let mut alacsonyak_kozott = 0;
    for meres in [0, 8, 19] {
        if meres >= 20 { alacsonyak_kozott += 1; }
    }
    assert_eq!(alacsonyak_kozott, 0);
}

A tizenkilences és húszas szomszédos bemenet a feltétel határát ellenőrzi. A huszonötös miatt az is látszik, hogy nem kizárólag a pontosan húszas értékeket számoljuk.

3. feladat: összegzés a lezáró jelig

A nem negatív napi bevételek adatsorát mínusz egy zárja. Az első lezáró jel utáni értékeket már ne számold bele. A példákban más negatív szám nem fordul elő. Vizsgáld meg a középen álló és az első helyen álló lezárást is, mert ezek az összegzés másik két szélső viselkedését mutatják.

Megoldás
fn main() {
    let mut osszeg = 0;
    for bevetel in [10, 20, -1, 999] {
        if bevetel == -1 { break; }
        osszeg += bevetel;
    }
    assert_eq!(osszeg, 30);
    let mut azonnali = 0;
    for bevetel in [-1, 50] {
        if bevetel == -1 { break; }
        azonnali += bevetel;
    }
    assert_eq!(azonnali, 0);
}

A lezáró jel ellenőrzése az összeadás előtt történik. Ha ezt a sorrendet megfordítanád, maga a jel is csökkentené az összeget, ami ellentmondana a szerződésnek.

Elfogadási feltételek

  • Az egytől ötig tartó összeg 15, a feldolgozott elemek száma öt, az üres tartományé nulla.
  • A négy mérés közül pontosan kettő éri el a húszas küszöböt; a második sorozatból egy sem.
  • A lezáró jelet és minden utána következő értéket kihagyjuk; az azonnal lezárt összeg nulla.

Továbblépés

A ciklus jelentését már lépésről lépésre tudod követni. A tömbök és indexelés leckében a sorrend mellé az elemek helyét is megvizsgálod, és biztonságosan kezelsz egy nem létező pozíciót.