Annexos

Altres sentències de control de bucles

Alguns llenguatges de programació ofereixen sentències que permeten un control directe sobre el comportament de les iteracions del bucle, més enllà del seu mecanisme natural basat en variables de control. El motiu pel qual s’inclouen en format d’annex dins d’aquests materials és pel fet que usar-ne no és imprescindible. Tot allò que es pot assolir amb aquestes sentències sempre es pot dur a terme triant una expressió booleana correcta per a la condició lògica de sortida del bucle. Tot i així, són útils, ja que poden simplificar aquesta condició quan és molt complexa o una part està orientada a controlar casos que passaran poc sovint.

En el cas del Java, es disposa de les sentències break i continue.

Cal tenir en compte que quan hi ha imbricació de diferents bucles, les sentències de control operen únicament sobre el bucle dins del qual s’han executat.

La sentència ''break''

Aquesta sentència no és nova per a vosaltres, ja que es tracta exactament de la mateixa que s’usa a la sentència switch. La seva funció en el context d’una estructura de repetició és molt semblant a la que té en una de selecció.

La sentència break, aplicada en el context d’una estructura de repetició, interromp immediatament la iteració en curs i fa que el flux de control surti del bucle. En fer-ho, no s’avalua la condició lògica de nou.

Normalment, usar una sentència break és una manera d’estalviar-vos l’ús d’una variable de control de tipus semàfor. Tan bon punt sabeu que s’ha complert la condició adient, deixeu d’executar el bucle immediatament.

Per exemple, si s’aplica a la versió 2 del programa per endevinar un nombre, es pot sortir del bucle tan bon punt se sap que s’ha encertat el valor. Per tant, es podria fer de la manera que veureu. Compileu, executeu i proveu aquest programa.

  1. import java.util.Scanner;
  2.  
  3. //Un programa en què cal endevinar un nombre.
  4. public class EndevinaBreak {
  5.  
  6. //PAS 1
  7. public static final int VALOR_SECRET = 4;
  8.  
  9. public static final int MAX_INTENTS = 3;
  10.  
  11. public static void main (String[] args) {
  12. Scanner lector = new Scanner(System.in);
  13.  
  14. System.out.println("Comencem el joc.");
  15. System.out.println("Endevina el valor enter entre 0 i 10 en tres intents.");
  16.  
  17. //Cal definir el comptador aquí, ja que s'usa dins aquest bloc d'instruccions, al final.
  18. int intents = 0;
  19. //Com que ara només es controla el comptador d'intents, es pot usar 'for'.
  20. for (intents = MAX_INTENTS; intents > 0; intents--) {
  21. System.out.print("Quin valor creus que és? ");
  22. int valorUsuari = lector.nextInt();
  23. lector.nextLine();
  24. if (valorUsuari == VALOR_SECRET) {
  25. //Valor encertat. Ja es pot felicitar l'usuari i deixar d'iterar.
  26. System.out.println("Enhorabona. Has encertat!");
  27. break;
  28. }
  29. }
  30. //El bucle ha acabat a causa de l'esgotament del comptador?
  31. if (intents <= 0) {
  32. System.out.println("Intents esgotats. Has perdut!");
  33. }
  34.  
  35. }
  36.  
  37. }

La figura mostra un esquema del flux de control de l’estructura de repetició quan es compleix que valorUsuari == VALOR_SECRET i s’executa la sentència break.

Figura Flux de control en una estructura de repetició en què s’usa la sentència break

Fixeu-vos que el codi és lleugerament més senzill que l’original. Un cop se sap que s’ha encertat el valor secret, es pot felicitar l’usuari i sortir del bucle immediatament. No cal la variable haEncertat com a semàfor. Tanmateix, com que ara l’única cosa que cal controlar en la condició lògica és el nombre d’intents, un comptador, es pot usar una sentència for com a estructura de repetició. Ara bé, com passa en el programa original, al final cal controlar per què s’ha sortit del bucle: perquè s’han esgotat els intents o perquè s’ha encertat. Però en aquest cas, l’execució de les instruccions relatives a guanyar el joc, com mostrar el missatge d’enhorabona, ja s’ha fet abans, per la qual cosa n’hi ha prou amb una estructura de selecció simple.

La sentència ''continue''

Aquesta sentència sí que és nova i només s’aplica en el context de les estructures de repetició.

La sentència continue fa que la iteració en curs es consideri immediatament finalitzada i en comenci una de nova d’acord amb l’avaluació de la condició lògica.

En finalitzar una iteració usant continue, el flux de control farà el mateix que correspondria a finalitzar-la de manera habitual, en arribar a la darrera instrucció: avançar fins a l’avaluació de la condició lògica per decidir si cal fer una nova iteració o no, incrementar el comptador en el cas de la sentència for, etc.

Normalment, usar una sentència continue és una manera de descartar ràpidament el tractament de certs valors i evitar que hi hagi una estructura de selecció molt gran dins del bucle.

Un exemple simple és el mostrat tot seguit, en què se sumen un seguit de valors, sempre que aquests compleixin certes condicions (no siguin múltiples de tres ni de cinc). Si reflexioneu una mica, veureu clar que la sentència continue no és imprescindible, però fa que les instruccions que fan la feina important no estiguin dins d’una estructura de selecció. La seva utilitat és merament de millora (potser discutible) de la llegibilitat del codi.

Compileu i executeu el programa.

  1. import java.util.Scanner;
  2.  
  3. //Anem a sumar un seguit de valors NO múltiples de tres ni de cinc.
  4. public class NoSumarMultiplesTresCinc {
  5.  
  6. public static void main (String[] args) {
  7. Scanner lector = new Scanner(System.in);
  8.  
  9. System.out.print("Fins a quin valor vols sumar? ");'
  10. int limit = lector.nextInt();
  11. lector.nextLine();
  12.  
  13. int resultat = 0;
  14. for (int i = 1; i <= limit; i++ ) {
  15. if ((i%5 == 0)||(i%3 == 0)) {
  16. continue;
  17. }
  18. resultat = resultat + i;
  19. System.out.println("S'ha sumat el valor " + i);
  20. }
  21. System.out.println("El resultat final és " + resultat + ".");
  22.  
  23. }
  24.  
  25. }

La figura mostra un esquema del flux de control de l’estructura de repetició quan es compleix que el valor és múltiple de 3 o de 5 i s’executa la sentència continue.

Figura Flux de control en una estructura de repetició en què s’usa la sentència continue

Una sentència controvertida: salt incondicional

Només per completesa, val la pena presentar una de les sentències més controvertides en el món de la programació.

Si el que volem és poder establir de manera lliure el flux de control d’un programa per poder tornar enrere en qualsevol moment a repetir instruccions executades, podria ser útil disposar d’alguna sentència que permeti fer salts dins el codi font en lloc d’usar estructures de repetició. Poder decidir en tot moment exactament a partir d’on es continuarà executant el programa. Aquesta sentència existeix en molts llenguatges de programació, en forma de salt incondicional, normalment expressat amb la sentència goto.

Una sentència de salt incondicional interromp el procés seqüencial d’execució d’instruccions i indica exactament, entre totes les del codi font, sigui quina sigui la seva ubicació, a partir de quina es continuarà executant el programa.

Figura El salt incondicional transporta el flux d’execució cap un lloc arbitrari desitjat

Si bé en els primers llenguatges de programació usar-la era molt habitual, quan no imprescindible, a partir dels anys seixanta i setanta fer-ne ús va passar a ser molt censurat, en considerar-se que atempta directament contra tots els principis d’una programació acurada i polida. Concretament, l’any 1968, el reputat científic i informàtic Edgar Disjktra va publicar la carta ”Go To Statement Considered Harmful” (“La sentència ‘goto’ es considera danyosa”), en què en criticava molt durament l’ús en els llenguatges d’alt nivell. La principal crítica que en feia era la dificultat que representa entendre un programa complex en què l’ordre d’execució de les seves instruccions no segueix cap mena d’estructura ni lògica, amb salts arbitraris en qualsevol moment. Simplement, imagineu com costaria d’entendre un llibre que tingués les pàgines desordenades.

Com en qualsevol tema, hi ha seguidors i detractors d’aquest punt de vista, però, en qualsevol cas, hi ha consens a considerar que, fins i tot en els pocs casos en què se’n pot justificar l’ús, cal anar amb molt de compte en usar-la, i si hi ha la possibilitat d’evitar usar-la, és millor fer-ho. En els llenguatges d’alt nivell gairebé sempre es pot substituir per una utilització correcta de les estructures de selecció o repetició.

Afortunadament, en llenguatge Java el salt incondicional no està disponible. Si bé la instrucció goto és a la seva llista de paraules clau reservada, i en molts IDE es ressalta en escriure-la com si fos reconeguda, no pot ser usada; una bona prova que els dissenyadors de Java són uns estrictes defensors de la programació estructurada.

Anar a la pàgina anterior:
Exercicis d'autoavaluació
Anar a la pàgina següent:
Índex general