M3 - Programació estructurada / Continguts UF1: Estructura alternativa

De wikiserver
La revisió el 21:25, 18 nov 2019 per Rsort (Discussió | contribucions) (Diversos camins: la sentència ”if/else if/else”)
Dreceres ràpides: navegació, cerca

Estructures de selecció

Les estructures de selecció permeten prendre decisions sobre quin conjunt d’instruccions cal executar en un punt del programa.

Tota estructura de selecció es basa en l’avaluació d’una expressió que ha de donar un resultat booleà: true (cert) o false (fals). Aquesta expressió s’anomena la condició lògica de l’estructura.

El conjunt d’instruccions que s’executarà dependrà del resultat de la condició lògica, i actuarà com una mena d’interruptor que marca el flux que cal seguir dins del programa.

Una desviació temporal del camí: selecció simple

L’estructura de selecció simple permet controlar el fet que s’executi un conjunt d’instruccions si i només si es compleix la condició lògica (és a dir, el resultat d’avaluar la condició lògica és igual a true). En cas contrari, no s’executen.

Un exemple seria el programa d’una botiga virtual que aplica un descompte al preu final d’acord amb un cert criteri (per exemple, si la compra total és com a mínim de 100 €). En aquest cas, hi ha un conjunt d’instruccions, les que apliquen el descompte, que només s’executen quan es compleix la condició. En cas contrari, s’ignoren i el preu final és el mateix que l’original.

Sintaxi i comportament

Per dur a terme aquest tipus de control sobre les instruccions del programa, cal usar una sentència if (si...). En el cas del Java, la sintaxi és la següent:

  instruccions del programa
  if (expressió booleana) {
        Instruccions per executar si l’expressió avalua a true (cert)
  }
  resta d’instruccions del programa

Si entre els parèntesis es posa una expressió que no avalua un resultat de tipus booleà, hi haurà un error de compilació.

Exemple: calcular un descompte

Es vol fer un programa que apliqui un descompte a un preu depenent del seu valor. Per veure clarament que hi ha diferents camins dins de les instruccions, primer de tot establirem quines són les tasques que ha de fer el programa i en quin ordre.

El programa hauria de fer:

1. Decidir quin és el valor mínim per optar al descompte i quant es descomptarà.
2. Demanar que s’introdueixi el preu inicial, en euros, pel teclat.
3. Llegir-lo.
4. Veure si el preu introduït és igual o major que el valor mínim per optar al descompte.
(a) Si és així, s’aplica el descompte sobre el preu inicial.
5. Mostrar el preu final.

En el pas 4 es pot observar que cal prendre una decisió d’acord amb una condició i que alguna de les tasques només es fa si aquesta es compleix (el pas 1). Per tant, queda establert que cal una estructura de selecció simple. Partint d’aquí, un possible codi font que correspondria a aquest esquema seria el següent. Observeu quines instruccions es corresponen a cadascuna de les passes escrites.

Tot seguit es mostra el codi font que du a terme aquestes tasques. Compileu-lo, executeu-lo i observeu com el resultat final mostrat per pantalla és diferent segons el valor que introduïu pel teclat.

import java.util.Scanner;

//Un programa que calcula descomptes.

public class Descompte {

  public static void main(String[] args) {
    //Es fa un descompte del 8%.
    final double DESCOMPTE = 0.08;
    //Es fa descompte per compres d’un mínim de 100 euros.
    final float COMPRA_MIN = 100;
    Scanner lector = new Scanner(System.in);
    double preu, descompteFet;
    System.out.print("Quin és el preu del producte, en euros? ");
    preu = lector.nextFloat();
    lector.nextLine();
    if (preu >= COMPRA_MIN) {
       descompteFet = preu * DESCOMPTE;
       preu = preu - descompteFet;
    }
    System.out.println("El preu final per pagar és de " + preu + " euros.");
  }
}

Aspectes importants de la selecció simple

  • L’expressió booleana que denota la condició lògica pot ser tan complexa com es vulgui, però ha d’estar sempre entre parèntesis.
  • Les instruccions que cal executar si la condició és certa estan englobades entre dues claus ({, }). Aquest conjunt es considera un bloc d’instruccions associat a la sentència if (bloc if ).
  • La línia on hi ha les claus o la condició no acaba mai en punt i coma (;), al contrari que altres instruccions.
  • Tot i que no és imprescindible, és un bon costum que les instruccions del bloc estiguin sagnades.

Amb la introducció d’estructures de selecció simple també apareix per primer cop codi font amb diferents blocs d’instruccions: el del mètode principal i els associats a la sentència if. La principal característica d’aquest fet és que la relació entre blocs és jeràrquica: tots els nous blocs d’instruccions són subblocs del mètode principal.

A mode de resum, la taula següent mostra una petita llista d’errors típics que es poden cometre en usar una sentència if.


Missatge d'error en compilar Error comès Exemple
'(' expected Expressió no envoltada de parèntesis if preu>=COMPRA_MIN){
';'expected Falta ; en alguna instrucció del bloc if preu = preu - descompteFet
Sempre executa bloc if S'ha posat ; a la sentència if if (preu>=COMPRA_MIN); {
Només fa condicionalment la primera instrucció del bloc if, la resta la fa sempre Falten les claus que han d'envoltar el bloc, {...} if (preu>=COMPRA_MIN)
  • Quan el bloc if només té una única instrucció, l’ús de claus és opcional. De totes maneres, és molt recomanable usar-les sempre, independentment d’aquest fet. Això facilita la identificació del bloc de codi associat a la sentència if quan s’està llegint el codi font.

Dos camins alternatius: la sentència ”if/else”

Suposeu que ara voleu fer un programa en què s’ha d’intentar endevinar un nombre entre 1 i 10. En aquest cas, i a diferència de l’anterior, ara hi ha dos escenaris excloents: o s’ha endevinat el nombre, o no s’ha endevinat. Segons de quin cas es tracti, la resposta del programa ha de ser diferent. Per tant, a més a més de codi comú per a qualsevol cas i d’un bloc que especifiqui les accions per dur a terme si es compleix la condició, ara en cal un altre que indiqui què cal fer només en cas contrari. Per poder fer això tenim l’estructura de selecció doble, la sentència if/else (si... si no...).

L’estructura de selecció doble permet controlar el fet que s’executi un conjunt d’instruccions, només si es compleix la condició lògica, i que se n’executi un altre, només si no es compleix la condició lògica.

És important recordar que els dos blocs de codi són excloents. Mai no pot passar que tots dos s’acabin executant.

Sintaxi i comportament

Per dur a terme aquest tipus de control sobre les instruccions del programa, cal usar una sentència if/else (si... si no...). En el llenguatge Java, la sintaxi és la següent:

  if (expressió booleana) {
     Instruccions per executar si l’expressió l’avalua a true - Bloc if
  } else {
     Instruccions alternatives per executar si l’expressió l’avalua a false - Bloc else
  }

El bloc if té exactament les mateixes característiques que quan s’usa en una estructura de selecció simple. Aquestes es compleixen també per al cas del bloc else, amb la particularitat que no té cap expressió assignada. Simplement, quan la condició lògica de la sentència if no es compleix s’executen les instruccions del bloc else.

Bloc if else

Si per algun motiu no es posa cap instrucció dins del bloc else i es deixa un espai buit entre les dues claus, la selecció doble es comporta igual que la selecció simple. En aquest cas, és millor usar només la sentència if en lloc de if/else.

Exemple: endevina el nombre secret

Un possible codi d’un programa en què s’intenta endevinar un nombre serveix per mostrar amb més claredat com es pot usar una sentència if/else. Novament, abans de veure’l val la pena reflexionar sobre quines són les tasques que hauria de fer el programa i en quin ordre.

Bàsicament, el programa ha de fer:

1. Decidir quin serà el nombre per endevinar.
2. Demanar que s’introdueixi un nombre pel teclat.
3. Llegir-lo.
4. Veure si el nombre introduït és igual al valor secret:
     (a) Si és igual que el nombre pensat, informa que s’ha encertat.
     (b) Si no, informa que s’ha fallat.

Queda clar que en el pas 4 cal prendre una decisió d’acord amb una condició.

El programa haurà d’emprendre dues vies d’acció diferents segons si la condició es compleix o no. Per tant, cal una estructura de selecció doble. Partint d’aquí, un possible codi font que correspondria a aquest esquema seria el següent. De nou, observeu quines instruccions es corresponen a cadascun dels passos descrits. Compileu-lo i executeu-lo per veure com funciona.

import java.util.Scanner;
//Un programa en què cal endevinar un nombre.
public class Endevina {

  public static void main(String[] args) {
  //El nombre per endevinar serà el 4.
     final int VALOR_SECRET = 4;
     Scanner lector = new Scanner(System.in);
     System.out.print("Endevina el valor enter, entre 0 i 10: ");
     int valorUsuari = lector.nextInt();
     lector.nextLine();
        //Estructura de selecció doble. O s’endevina o es falla.
     if (VALOR_SECRET == valorUsuari) {
        System.out.println("Exacte! Era " + VALOR_SECRET + ".");
     } else {
        System.out.println("T’has equivocat!");
     }
     System.out.println("Hem acabat el joc.");
  }
}

Diversos camins: la sentència ”if/else if/else”

Finalment, a l’hora d’establir el flux de control d’un programa, també hi ha la possibilitat que hi hagi un nombre arbitrari de camins alternatius, no solament dos. Per exemple, imagineu un programa que, a partir de la nota numèrica d’un examen, ha d’establir quina és la qualificació de l’alumne. Per això caldrà veure dins de quin rang es troba el nombre. En qualsevol cas, els resultats possibles són més de dos.

L’estructura de selecció múltiple permet controlar el fet que en complir-se un cas entre un conjunt finit de casos s’executi el conjunt d’instruccions corresponent.

Sintaxi i comportament

Aquest tipus de control sobre les instruccions del programa té associada la sentència if/else if/else (si és el cas, en aquest altre cas, si no és cap cas). Bàsicament, es tracta de la mateixa estructura que la sentència if/else, però amb un nombre arbitrari de blocs if (després del primer bloc, anomenats else if).

La figura següent mostra un esquema del flux d’execució, d’acord amb el resultat d’anar avaluant cadascuna de les condicions lògiques. En aquest cas és una mica més complicat, ja que, com es pot veure, hi ha més d’una condició lògica dins de la sentència. Cada condició es va avaluant ordenadament, des de la primera fins a la darrera, i s’executarà el codi del primer cas en què l’expressió avaluï com a cert. Un cop fet això, ja no es torna a avaluar cap altra condició restant i s’ignora la resta de blocs. Si en aquest procés es dóna el cas que cap de les expressions avalua a cert, s’executaran les instruccions del bloc else.

Exemple: transformar avaluació numèrica a text

Combinació d’estructures de selecció

Exemple: descompte màxim i control d’errors

La sentència ”switch”

Sintaxi i comportament

Control d’errors en l’entrada bàsica mitjançant estructures de selecció