Instrucțiuni etichetate

În principiu, orice instrucțiune în limbajul Java poate purta o etichetă. Instrucțiunile etichetate au forma
        etichetă : instrucțiune
unde
   etichetă este un identificator;
   instrucțiuneeste o instrucțiune simplă sau structurată.

Exemplu
    alpha: x=2*a+b;

Se permite să se folosească drept etichete chiar și identificatori care mai sunt folosiți în acelasi program ca nume de variabile, clase, metode etc., fară a se crea prin aceasta confuzii, deoarece compilatorul face distincție între etichete și nume în funcție de contextul în care acestea sunt utilizate.

Terminarea abruptă a execuției instrucțiunilor structurate

În secțiunile anterioare, s-a arătat că limbajul Java respectă principiile programării structurate. În consecință, instrucțiunile de control au fost concepute în conformitate cu aceste principii, iar instrucțiunea  goto nu există. Chiar dacă, din precauție, cuvântul cheie  gotoa fost menținut în limbaj, el nu este încă efectiv folosit. Cu toate acestea, având în vedere experiența practică și pentru a veni în ajutorul programatorilor, autorii limbajului Java au admis și anumite abateri de la structurile de control fundamentale acceptate de teoria programării structurate, fără a încălca însă principiul de bază al acesteia, conform căruia fiecare asemenea structură trebuie sa aibă un singur punct de intrare și un singur punct de ieșire. Am arătat deja, că astfel de excepții sunt instructiunile switch,do..while și for.  Ne vom ocupa acum de o alta abatere de la programarea structurată pură, care constă în folosirea instrucțiunilor  break ș continue și a instrucțiunilor etichetate.

Folosirea instrucțiunilor break și continue

Instructiunile  break și continue au forma generală următoare:

    break [etichetă];
    continue [etichetă];

unde  etichetăeste eticheta unei instrucțiuni și este un identificator. Eticheta este opțională (de aceea a fost scrisă de noi între paranteze drepte).

Instructiunea break se poate folosi în corpul  unei instrucțiuni  switch, while, do..while sau for și are ca efect ieșirea forțată (abruptă)  din structura de control în care se găsește instrucțiunea respectivă.

S-a arătat deja cum se folosește instrucțiunea break în corpul unei instrucțiuni  switch. Iată acum un exemplu de folosire într-un ciclu cu test inițial:

    k=1; S=0;
    while(S+t!=S) {
        t*=a/k;
        S+=t;
        if(t<1.0e-10*S) break;
        k++;
    }

În acest caz, în momentul în care este satisfacută condiția  (t<1.0e-10*S) din instructiunea if se iese forțat din ciclu, chiar dacă condiția principală de continuare a ciclului (S+t!=S) este încă satisfacută.

Iată și un exemplu similar, în care se iese forțat din instrucțiunea for:

    k=1; S=0;
    for(;;) {
        t*=a/k;
        if(S+t==S) break;
        S+=t;
        k++;
    }

Întrucât inițializarea ciclului s-a făcut înainte de instructiunea for, iar condiția de ieșire din ciclu și pregatirea continuarii ciclului se găsesc în corpul acestuia, în paranteza lui for toate cele trei zone au ramas vide.

Instrucțiunea continue se poate folosi numai în corpul ciclurilor (while, do..while, for). Dacă instrucțiunea continue nu are etichetă, efectul este că se trece peste restul instrucțiunilor din corpul ciclului, începând din punctul în care se găsește instrucțiunea  continue până la sfârșitul acestuia, dar se continuă executarea ciclului, adică se reia executarea corpului acestuia cât timp este satisfacută condiția de continuare.

Să considerăm, de exemplu, următorul fragment de program:

    s=0;
    for(k=0; k<20; k++) {
       x*=a;
       s+=x;
       if(k<16) continue;
       System.out.println("k="+k+" x="+x+" s="+s);
    }

În acest caz, corpul ciclului se va repeta pentru valori ale lui k de la 0 la 19, dar instrucțiunea System.out.println(...) va fi "sărită" pentru valori ale lui k mai mici decât 16, trecându-se direct la acolada de închidere a corpului ciclului, astfel că afișările se vor face numai începand cu k=16.

Folosirea etichetei în instrucțiunea break

Necesitatea utilizării unei etichete apare atunci când există două astfel de structuri imbricate una în alta, iar noi dorim ca prin  break să se  iasa forțat din cea exterioară, ca în exemplul urmator:

    ciclu1: while(w>0.05){
               w/=a;
               for(int k=0; k<n; k++) {
                  s+=w;
                  if(s>b) break ciclu1;
                  y+=w*s
               }
            }

Instrucțiunea break se găsește, în acest exemplu, în corpul ciclului interior. Dacă nu ar fi conținut eticheta ciclu1,această instrucțiune ar fi provocat numai ieșirea dim ciclul interior (for), dar s-ar fi reluat execuția ciclului exterior (while), implicand, desigur, și reluarea ciclului interior continut de acesta. Dacă însă este prezenta eticheta din break, se va ieși forțat din instrucțiunea de control care poartă această etichetă, în cazul de față din ciclul exterior. Remarcam, deci, că eticheta conținută în instrucțiunea break indică faptul ca se va ieși forțat din structura de control care poartă aceeași etichetă. Aceasta înseamnă că instrucțiunea break cu etichetă constituie o abatere locală de la principiul de bază al programării structurate, conform căruia fiecare structură de control trebuie sa aibă un singur punct de intrare și un singur punct de ieșire. În ultimul exemplu, ciclul interior are două puncte de ieșire: unul este ieșirea normală din ciclul for, iar celalalt este ieșirea prin break. Daca luam însă în considerație ciclul exterior, constatăm ca acesta respectă principiul menționat. Desigur că pot să existe mai multe instrucțiuni de control cuprinse una în alta și fiecare dintre ele poate avea o etichetă, care poate fi utilizată într-o instrucțiune break.

Testarea a diferite situații de utilizare a instructiunii  breakse face în programul din fișierul TestBreak.java.

Folosirea etichetei în instrucțiunea continue

Să considerăm acum următorul fragment de program:

    ciclu1: for (int i=0; i<6; i++) {
                System.out.println("Control 1: i="+i);
                for(int j=3; j>0; j--) {
                   System.out.println("Control 2: i="+i+" j="+j);
                   if(i>1 && i<5) continue ciclu1;
                   System.out.println("Control 3: i="+i+" j="+j);
                } // Sfarsitul ciclului interior
                System.out.println("Control 4: i="+i);
            }  // Sfarsitul ciclului exterior

Instrucțiunea  conținue eticheta ciclu1, care aparține ciclului exterior. În consecință, pentru valori ale variabilei i cuprinse între 1 și 5, se va trece forțat la sfârșitul corpului ciclului exterior, deci nu se vor mai executa instrucțiunile de afișare "Control 3" și "Control 4".

Programul de testare pentru instrucțiunea  continue se găsește în fișierul  TestCont.java.



© Copyright 2000 - Severin BUMBARU, Universitatea "Dunărea de Jos" din Galați