Java vezérlő szerkezetek

Kategória: Standard Java.

A vezérlő utasítások a számítógép két alapvető lényegének programozási megvalósulásai.

Feltételkezelés

if

A Java nyelvben az alap feltételkezelés a következőképpen néz ki:

if ([feltétel]) [utasítás];

A gyakorlatban az utasítás nem egy utasítás, hanem több, és ezeket kapcsos zárójelek közé tesszük. Jó programozási gyakorlat akkor is új kapcsos zárójelek közé tenni és új sorba írni az utasítást, ha csak egy van belőle:

if ([feltétel]) {
    [utasítás];
}

else

A feltételkezelésnek a továbbgondolása az, hogy akkor is történjen valami, ha a feltétel nem teljesül, és ne kelljen megismételni a feltételt, immáron tagadva, és ez az else ág:

if ([feltétel]) {
    [utasítások 1];
} else {
    [utasítások 2];
}

Lássunk erre egy példát!

// Main.java
public class Main {
    public static void main(String[] args) {
        int x = 5;
        if (x % 2 == 1) {
            System.out.println("páratlan");
        } else {
            System.out.println("páros");
        }
    }
}

switch

Persze az else is folytatódhat rögtön egy újabb if utasítással, majd a következő is stb.:

if ([feltétel 1]) {
    [utasítások 1];
} else if ([feltétel 2]) {
    [utasítások 2];
} else if ([feltétel 3]) {
    [utasítások 3];
} else {
    [utasítások 4];
}

Ez a struktúra leginkább akkor fordul elő, ha van egy változó, ami jól felsorolható értékeket vehet fel (pl. a hét napjai; a felsorolás típusról később még lesz szó), és mindegyik érték esetén mást és mást kell végrehajtani. Ebben az esetben a fenti struktúra ugyan működhet, de kissé áttekinthetetlen; jobb megoldás a switch … case … default struktúra:

switch (változó) {
case [érték 1]:
    [utasítások 1];
    break;
 
case [érték 2]:
    [utasítások 2];
    break;
 
case [érték 3]:
    [utasítások 3];
    break;
 
default:
    [utasítások 4];
}

A struktúra értelmezése: a változó értékétől függően fut le az első, a második, a harmadik vagy a negyedik utasításblokk; ez utóbbi akkor, ha a változó pillanatnyi értéke egyik felsorolt értéket sem veszi fel. Az egyes esetek végén álló break utasítás azt jelenti, hogy a lefutás ne folytatódjon ott, hanem éjen véget. Ha nem tennénk oda, akkor a következő értékre vonatkozó utasítások is lefutnának, és jó eséllyel ezt nem szeretnénk. (Valójában előfordulhatnak olyan esetek, hogy szeretnénk végrehajtani, de ez olyan nehezen észrevehető problémákhoz vezethet, hogy még a kódismétlés is jobb, mint a break szándékos lehagyása.)

Erre is lássunk egy példát!

// Main.java
public class Main {
    public static void main(String[] args) {
        int x = 2;
        switch (x) {
        case 1:
            System.out.println("egy");
            break;
        case 2:
            System.out.println("kettő");
            break;
        default:
            System.out.println("se nem egy, se nem kettő");
        }
    }
}

Ciklus

Számláló for

A számláló ciklus szintaxisa a Java-van az alábbi:

for ([inicializálás]; [feltétel]; [változás]) {
    [utasítások];
}

Először a rendszer végrehajtja az inicializálást (egyszer), majd megvizsgálja a feltételt, ha teljesül, végrehajtja az utasításokat, a végén végrehajtja a változást, ismét megvizsgálja a feltételt, és így tovább. Ha a feltétel nem teljesül, akkor véget ér a ciklus.

Ezt a módszert leggyakrabban arra használjuk, hogy a ciklusmagot (a cikluson belüli utasításokat) adott számszor hajtsuk végre, az alábbi példában 10-szer:

// Main.java
public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
        }
    }
}

A ciklus változót (a példában i) használhatjuk a ciklusmagon belül, viszont az értékét ne változtassuk meg, mert az nehezen felderíthető nem várt problémákhoz vezethet. A gyakorlatban a ciklusváltozók elnevezései i, j, k (egymásba ágyazott ciklusok esetén). Az is gyakran előfordul, hogy a szám, ahányszor a ciklusmagot végre kell hajtani, egy változó aktuális értéke; ez esetben a fenti példában a feltétel nem az lesz, hogy i < 10, hanem i < n.

Iteráló for

A for ciklusnak van egy olyan változata is, amely kezdetben nem létezett: adott tömb elemein való végigiterálás:

// Main.java
public class Main {
    public static void main(String[] args) {
        int[] array = {3, 5, 7, 4};
        for (int element : array) {
            System.out.println(element);
        }
    }
}

A példában a ciklusmagon belül az element változó tartalmazza az adott lefutáskor a tömb aktuális elemét.

while

A for ciklusok közös jellemzője az, hogy előre tudjuk, hányszor fut le a ciklusmag. Ellenben a while ciklus esetén ezt nem tudjuk, ez esetben addig fut a ciklusmag, amíg a feltétel igaz:

while ([feltétel]) {
    [utasítások];
}

A fenti példa ezzel a módszerrel, ami kiírja a számokat 0-tól 9-ig az alábbi:

// Main.java
public class Main {
    public static void main(String[] args) {
        int i = 0;
        while (i < 10) {
            System.out.println(i);
            i++;
        }
    }
}

Ennek egy speciális esete a végtelen ciklus (amit egyébként a for (;;) szintaxissal is el tudunk érni):

while (true) {
    [utasítások];
}

Ez utóbbinál felvetődhet, hogy egy végtelen ciklus hogyan érhet véget. Van két utasítás, ami a ciklus utasításokat vezérli.

break

Erről már volt szó; ennek hatására a program kilép a legbelső ciklusból, és az azt követő első utasításra ugrik. Ezt tipikusan valamilyen feltétel hatására hajtja végre, tehát többnyire egy if utasításon belül található.

Lássuk a fenti példát végtelen ciklussal és break; utasítással!

// Main.java
public class Main {
    public static void main(String[] args) {
        int i = 0;
        while (true) {
            System.out.println(i);
            i++;
            if (i == 10) {
                break;
            }
        }
    }
}

Megjegyzés: feltétel nélküli ugró utasítás, azaz goto nincs a Java-ban, ez viszont egy olyan pont, ahol valóban hasznát lehetne venni: teljesen kiugrani egy egybe ágyazott ciklusból. Noha megvalósítható lenne változókkal és feltételkezelésekkel, a nyelv megalkotói mégis beletettek egy lehetőséget: tetszőleges blokk elé helyezhetünk címkét, kettősponttal elválasztva a blokktól, és a break utasításnak megadhatjuk, hogy melyik ciklusra vonatkozik, pl.:

outer : for (...) {
    inner : while (...) {
        ...
        if (...) {
            break outer;
        }
        ...
    }
}

Egy példa:

// Main.java
public class Main {
    public static void main(String[] args) {
        int x = 0;
        outer: for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                x++;
                if (x == 15) {
                    break outer;
                }
                System.out.println("(" + i + "," + j + ")");
            }
        }
    }
}

continue

A ciklusmag következő iterációját hajtja végre. Azaz végrehajtja a növekményt (ha van), a feltételvizsgálatot (ha van), és ha a feltétel teljesül, akkor lefuttatja a ciklusmagot.

Egy példa:

// Main.java
public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            if (i % 2 == 1) {
                continue;
            }
            System.out.println(i);
        }
    }
}

Megjegyzés: más programozási nyelvekben létezik még a do … while struktúra is, ami annyiban tér el a while-tól, hogy a ciklusmag legalább egyszer mindig lefut; ilyen a Java-ban nincs.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License