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.