Gyakorlati alapok

Dönteni kell! (switch)

 

A fejezet eredményes feldolgozásához mindenképpen olvassuk át és értsük meg az előző, Dönteni kell! (if - else) című fejezet összefüggéseit!

 

A switch tulajdonképpen a többszörös elágazás lehetősége...

 

www.informatika-programozas.hu

 

...amely során többféle (2-nél több) választási lehetőségből válogathatunk (némelyik programozási könyv összetett elágazásnak említi).

 

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

A switch-választás során szintén csak az egyik úton-ágon mehetünk tovább. Programozás-technikailag csakis az egyik ág kerül végrehajtásra, illetve ha semelyik ág nem teljesíti a feltételeket, akkor egy default nevű ág fut le. Egy switch-választás mindig helyettesíthető többszörös if else-ágakkal.

 

switch (bemeneti adat) {

    case (1. feltétel): 1.választási ág; break;

    case (2. feltétel): 2.választási ág; break;

    case (3. feltétel): 3.választási ág; break;

    case (4. feltétel): 4.választási ág; break;

   default: Ha egyetlen feltétel sem teljesül; break;

}

 

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

Az utasítássor végén lévő break azt jelenti, hogy a feltétel teljesülése esetén a belső ciklus futása megszakad, a program a belső ciklusból kilép.

 

A switch a következő egyszerű és összetett adattípusokat képes bemeneti paraméterként fogadni:

A switch-szerkezetet hosszú, azaz többszörös és viszonylag egynemű, egzakt adatoknál és választási kényszereknél érdemes használnunk. Az alábbi, futtatható Java-kód például megmondja a hónapok sorszámából (int sorSzam) a hónap neveit, bár láthatjuk, hogy a legfontosabb, az adatbevitel mindig 5. hónapot, májust fog mutatni. Ezt még nem kezeltük le, hiszen még nem foglalkoztunk adatbevitel-implementációval. Ebből természetesen az is következik, hogy int sorSzam < 1 vagy int sorSzam > 12 esetén a default ág fut le, amely lényegében hibás adatbevitelt fog jelenteni.

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int sorSzam = 5;
    switch(sorSzam){
        case 1: System.out.println("Január"); break;
        case 2: System.out.println("Február"); break;
        case 3: System.out.println("Március"); break;
        case 4: System.out.println("Április"); break;
        case 5: System.out.println("Május"); break;
        case 6: System.out.println("Június"); break;
        case 7: System.out.println("Július"); break;
        case 8: System.out.println("Augusztus"); break;
        case 9: System.out.println("Szeptember"); break;
        case 10: System.out.println("Október"); break;
        case 11: System.out.println("November"); break;
        case 12: System.out.println("December"); break;
        default: System.out.println("Rossz adatbevitel!"); break;
        }
    }
}

 

Végeredmény:

Május

 

A switch használatakor talán a legtipikusabb hiba, ha elfelejtjük kitenni a sorok végén lévő break utasítást. A hiba detektálása azonban egyszerű lesz, mert ekkor a kiválasztott ág, valamint az összes alatti lévő ág le fog futni:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    int sorSzam = 5;
    switch(sorSzam){
        case 1: System.out.println("Január");
        case 2: System.out.println("Február");
        case 3: System.out.println("Március");
        case 4: System.out.println("Április");
        case 5: System.out.println("Május");
        case 6: System.out.println("Június");
        case 7: System.out.println("Július");
        case 8: System.out.println("Augusztus");
        case 9: System.out.println("Szeptember");
        case 10: System.out.println("Október");
        case 11: System.out.println("November");
        case 12: System.out.println("December");
        default: System.out.println("Rossz adatbevitel!");
        }
    }
}

 

Végeredmény:

Május
Június
Július
Augusztus
Szeptember
Október
November
December
Rossz adatbevitel!

 

Ha a switch-szerkezetben nem jelölünk ki minden ágat, akkor csak a megadott választási ág valamelyike fog lefutni. Adott például egy testsúlyminősítő algoritmus, amelyik nem mindegyik esetet minősít: int atlagSuly = 30 esetén a 40-hez tartozó minősítés egyaránt "Sovány".

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {

public static void main(String[] args) {

int atlagSuly = 30;

switch(atlagSuly){

    case 30:

    case 40: System.out.println("Sovány"); break;

    case 50:

    case 60: System.out.println("Átlagos"); break;

    case 70: System.out.println("Túlsúlyos"); break;

    case 80:

    case 90:

    case 100: System.out.println("Kórosan túlsúlyos"); break;

    default: System.out.println("Rossz adatbevitel!"); break;

        }

    }

}

 

Végeredmény:

Sovány

 

Tanítványi kérdés: Mi történik, ha átlagsúlynak nem 10-zel osztható számot írok be, például 36 (int atlagSuly = 36)?

 

A default ág fog lefutni, hiszen a case esetekben az nem szerepel. Természetesen kis trükközéssel elérhetjük, hogy a switch-szerkezetbe csakis 10-zel osztható számok kerüljenek (10, 20, 30, 40, stb.). A kód bemeneti pontja a bemenetiAdat nevű változó, ennek értéke van úgy manipulálva, hogy az atlagSuly változó már csak 10-zel osztható számokat kapjon. Mindeközben megpróbálom a switch-szerkezet eredeti struktúráját megtartani:

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

public class Main {
public static void main(String[] args) {
    String szamString = "";
    int atlagSuly = 0;
    int bemenetiAdat = 43;
    if(bemenetiAdat < 10 && bemenetiAdat > 0){
        bemenetiAdat = 10;
        atlagSuly = bemenetiAdat;
    }
    else if(bemenetiAdat > 100){
        bemenetiAdat = 100;
        atlagSuly = bemenetiAdat;
    }
    else
        atlagSuly = bemenetiAdat;
        szamString = Integer.toString(bemenetiAdat);
        int masodikDigit = Integer.parseInt(szamString.substring(1));
        atlagSuly -= masodikDigit;
        switch(atlagSuly){
            case 10:
            case 20:
            case 30:
            case 40: System.out.println("Sovány"); break;
            case 50:
            case 60: System.out.println("Átlagos"); break;
            case 70: System.out.println("Túlsúlyos"); break;
            case 80:
            case 90:
            case 100: System.out.println("Kórosan túlsúlyos"); break;
            default: System.out.println("Rossz adatbevitel!"); break;
        }
    }
}

 

Végeredmény:

Sovány

 

A switch-szerkezetnek vannak további mikrobeállítási szabályai.

 

Nyilvánvalóan nem adhatunk meg olyan típusú bemeneti vagy értékelő adatot, amelyet alapértelmezésben nem fogad el, például:

 

case 1,5: System.out.println(); break;

(lebegőpontos számot nem tud fogadni)

 

Kiértékelési értékben (case) csakis konstans, nem változó értékek adhatók meg. Az alábbi példában az 1. case nem konstans értékeket fogad (int a és b), a 2. már igen:

 

int a = 1;

int b = 2;

int c = 3;

 

switch(c){

    case a + b: System.out.println(c); break; //Végeredmény: hiba, nem fog lefutni

    case 1 + 2: System.out.println(c); break; //Végeredmény: 3

 

Megoldás a final szó használata, amely a változóértékeket konstanssá, nem változtathatóvá teszi (Ami a változót (és a többieket) változatlanná teszi: a final című fejezet). Programozási konvenció a konstans változók nagybetűs jelölése (például PI), ettől most az érthetőség kedvéért eltekintek.

 

final int a = 1;

final int b = 2;

int c = 3;

 

switch(c){

    case a + b: System.out.println(c); break; //Végeredmény: 3

 

Egyes programozói vélekedések szerint a default ág mögé nem kell kitenni a break utasítást, hiszen ott egyébként is véget ér a kiértékelés. Ez igaz, a kód ilyen módon sem veszít funkcionalitásából. Ám az is igaz, hogy a hivatalos Java-dokumentáció ennek ellenére folyamatosan kiteszi.

 

Összefoglalva: ha a switch-szerkezet megengedett, egzakt, jól értelmezhető bemeneti adatot kap (és ez azt jelenti, hogy a lehetséges hibákat még a switch előtt le kell kezelnünk), akkor gyorsan és zökkenőmentesen képes a döntési mechanizmust lefuttatni. A szerkezet pontosan erre lett tervezve.