Diferència entre revisions de la pàgina «M3 - Programació estructurada / Continguts UF1: Estructura alternativa»

De wikiserver
Dreceres ràpides: navegació, cerca
(Exemple: endevina el nombre secret)
 
(Hi ha 30 revisions intermèdies del mateix usuari que no es mostren)
Línia 1: Línia 1:
 +
==Condicional if==
 +
 +
*Permet decidir si en funció d’una condició cal o no executar una o un conjunt d’instruccions.
 +
 +
<source lang="java">
 +
instruccions del programa
 +
  if (expressió booleana) {
 +
        Instruccions per executar si l’expressió avalua a true (cert)
 +
  }
 +
  resta d’instruccions del programa
 +
</source>
 +
 +
*La condició te dues respostes possibles: Certa o Falsa. Si és certa s’executarà el procediment i sinó no
 +
 +
*S’executarà i la execució continuarà amb les sentencies que hi hagi a continuació del bloc if.
 +
 +
Exemple:
 +
 +
<source lang="java">
 +
import java.util.Scanner;
 +
 +
public class MajorEdat {
 +
 +
  public static void main(String[] args) {
 +
    //Decidir si una persona es major de edat.
 +
    final int MAJOREDAT = 18;
 +
    int edat;
 +
    Scanner lector = new Scanner(System.in);
 +
    System.out.print("Quina edat tens? ");
 +
    edat = lector.nextInt();
 +
    if (edat >= 18){
 +
      System.out.println("Ets major d'edat");
 +
 +
    }
 +
    if (edat < 18){
 +
      System.out.println("Ets menor d'edat");
 +
    }
 +
  }
 +
}
 +
</source>
 +
 +
* Si entre els parèntesis es posa una expressió que no avalua un resultat de tipus booleà, hi haurà un error de compilació.
 +
 +
'''Condicionals else i else if'''
 +
 +
<source lang="java">
 +
import java.util.Scanner;
 +
 +
public class MajorEdat {
 +
 +
  public static void main(String[] args) {
 +
    //Decidir si una persona es major de edat.
 +
    final int MAJOREDAT = 18;
 +
    int edat;
 +
    Scanner lector = new Scanner(System.in);
 +
    System.out.print("Quina edat tens? ");
 +
    edat = lector.nextInt();
 +
    if (edat >= 18){                                // S'executa si la condició de l'if és falsa
 +
      System.out.println("Ets major d'edat"); 
 +
 +
    }
 +
    else{
 +
      System.out.println("Ets menor d'edat");
 +
    }
 +
  }
 +
}
 +
</source>
 +
 +
<source lang="java">
 +
// Si necessitem comprovar un altre valor de l'edat podem utilitzar elif
 +
 +
import java.util.Scanner;
 +
 +
public class MajorEdat {
 +
 +
  public static void main(String[] args) {
 +
    //Decidir si una persona es major de edat.
 +
    final int MAJOREDAT = 18;
 +
    int edat;
 +
    Scanner lector = new Scanner(System.in);
 +
    System.out.print("Quina edat tens? ");
 +
    edat = lector.nextInt();
 +
    if (edat >= 18){                              // S'executa si la condició de l'if és falsa
 +
      System.out.println("Ets major d'edat"); 
 +
 +
    }
 +
    else if (edat >= 16) {                        // es comprova només si la condició de l'if és falsa
 +
      System.out.println("Ets adolescent i menor d'edat");
 +
     
 +
    }
 +
    else{                                        // S'executa només si la condició de l'elif és falsa
 +
      System.out.println("Ets menor d'edat");
 +
    }
 +
  }
 +
}
 +
</source>
 +
 +
*Es poden posar tants else if com necessitem
 +
 +
==La sentència ”switch”==
 +
 +
*Quan l’avaluació d’una expressió és de tipus enter o caràcter.
 +
 +
*Millora la llegibilitat del codi
 +
 +
*Es poden executar de manera consecutiva més d'un bloc.
 +
 +
===Sintaxi i comportament===
 +
 +
*Es basa en una paraula clau seguida d’una condició entre parèntesis i un bloc de codi entre  claus
 +
 +
*La paraula clau '''case''' seguida del valor i de dos punts indica les instruccions assignats a cada cas.
 +
 +
*A paritr del case que avalua a cert s'executaran tots els blocs d'instruccions fins a trobar el delimitador '''break'''.
 +
 +
*Al final de tots els apartats se’n posa un d’especial (opcional), anomenat '''default'''.
 +
 +
<source lang="java">
 +
switch(expressió de tipus enter, caràcter o text) {
 +
    case valor1:
 +
          instruccions si l’expressió avalua a valor1
 +
          (opcionalment) break;
 +
    case valor2:
 +
          instruccions si l’expressió avalua a valor2
 +
          (opcionalment) break;
 +
    ...
 +
    case valorN:
 +
          instruccions si l’expressió avalua a valorN
 +
          (opcionalment) break;
 +
    (opcionalment ) default:
 +
          instruccions si l’expressió avalua a algun valor que no és valor1...valorN
 +
          (opcionalment) break;
 +
}
 +
</source>
 +
 +
*Els valors no han de seguir cap ordre concret.
 +
 +
*Quan s'arriba a una sentencia '''break''': el programa se salta la resta d’apartats i continua amb la instrucció posterior a la sentència '''switch'''
 +
 +
*Si no hi ha instrucció '''break''' al final d'un bloc s'executaran les instruccions dels següents blocs fins trobar-ne algun bloc que acabi en '''break'''. La figura següent mostra aquest comportament tan particular.
 +
 +
[[Imatge:m3uf1_switch.png |600px|center| Switch]]
 +
 +
:*A partir de la versió 7 de Java es pot fer servir un String (text) per a avaluar l’expressió
 +
 +
:'''Exemple:''' Traduir un número de mes a text'''
 +
<source lang="java">
 +
public class TraduccioMes {
 +
 +
  public static void main(String[] args) {
 +
      int mes;
 +
      Scanner teclat = new Scanner(System.in);
 +
      System.out.println("Introdueixi el número de mes a traduir: ");
 +
      mes = teclat.nextInt();
 +
      switch (mes) {
 +
        case 1:
 +
            System.out.println("Traducció: Gener\n");
 +
            break;
 +
        case 2:
 +
            System.out.println("Traducció: Febrer\n");
 +
            break;
 +
        case 3:
 +
            System.out.println("Traducció: Març\n");
 +
            break;
 +
        case 4:
 +
            System.out.println("Traducció: Abril\n");
 +
            break;
 +
        case 5:
 +
            System.out.println("Traducció: Maig\n");
 +
            break;
 +
        case 6:
 +
            System.out.println("Traducció: Juny\n");
 +
            break;
 +
        case 7:
 +
            System.out.println("Traducció: Juliol\n");
 +
            break;
 +
        case 8:
 +
            System.out.println("Traducció: Agost\n");
 +
            break;
 +
        case 9:
 +
            System.out.println("Traducció: Setembre\n");
 +
            break;
 +
        case 10:
 +
            System.out.println("Traducció: Octubre\n");
 +
            break;
 +
        case 11:
 +
            System.out.println("Traducció: Novembre\n");
 +
            break;
 +
        case 12:
 +
            System.out.println("Traducció: Desembre\n");
 +
            break;
 +
        default:
 +
            System.out.println("No existeix un mes amb número: " + mes);
 +
      }
 +
  }
 +
}
 +
</source>
 +
<!--
 +
 +
 
==Estructures de selecció==
 
==Estructures de selecció==
  
Línia 139: Línia 339:
 
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.
 
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.
  
<source code="java">
+
<source lang="java">
 
import java.util.Scanner;
 
import java.util.Scanner;
 
//Un programa en què cal endevinar un nombre.
 
//Un programa en què cal endevinar un nombre.
 
public class Endevina {
 
public class Endevina {
public static void main(String[] args) {
+
 
//El nombre per endevinar serà el 4.
+
  public static void main(String[] args) {
final int VALOR_SECRET = 4;
+
  //El nombre per endevinar serà el 4.
Scanner lector = new Scanner(System.in);
+
    final int VALOR_SECRET = 4;
System.out.print("Endevina el valor enter, entre 0 i 10: ");
+
    Scanner lector = new Scanner(System.in);
int valorUsuari = lector.nextInt();
+
    System.out.print("Endevina el valor enter, entre 0 i 10: ");
lector.nextLine();
+
    int valorUsuari = lector.nextInt();
//Estructura de selecció doble. O s’endevina o es falla.
+
    lector.nextLine();
if (VALOR_SECRET == valorUsuari) {
+
        //Estructura de selecció doble. O s’endevina o es falla.
System.out.println("Exacte! Era " + VALOR_SECRET + ".");
+
    if (VALOR_SECRET == valorUsuari) {
} else {
+
        System.out.println("Exacte! Era " + VALOR_SECRET + ".");
System.out.println("T’has equivocat!");
+
    } else {
}
+
        System.out.println("T’has equivocat!");
System.out.println("Hem acabat el joc.");
+
    }
}
+
    System.out.println("Hem acabat el joc.");
 +
  }
 
}
 
}
 
</source>
 
</source>
  
 
==Diversos camins: la sentència ”if/else if/else”==
 
==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===
 
===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.
 +
 +
[[Imatge:m3uf1_bloc_if_else_if_else.png |500px|center| Bloc if else if else]]
 +
 +
El punt important d’aquesta sentència és que només s’executarà un únic bloc de tots els possibles. Fins i tot en el cas que més d’una de les expressions booleanes pugui avaluar a cert, només s’executarà el bloc associat a la primera d’aquestes expressions dins de l’ordre establert en la sentència.
 +
 +
També és destacable el fet que el bloc else és opcional. Si no volem, no cal posar-lo. En aquest cas, si no es compleix cap de les condicions, no s’executa cap instrucció entre les incloses dins de la sentència.
  
 
===Exemple: transformar avaluació numèrica a text===
 
===Exemple: transformar avaluació numèrica a text===
 +
 +
La manera d’usar la sentència if/else if/else es pot veure millor mitjançant el codi de l’exemple proposat anteriorment. Un cop més, abans de veure el codi es repassaran els passos que ha de fer el programa per dur a terme el seu objectiu i l’ordre que cal seguir.
 +
<pre>
 +
1. Demanar que s’introdueixi la nota pel teclat.
 +
2. Llegir-la.
 +
3. Mostrar un text o un altre segons el rang de valors dins del qual es troba la nota:
 +
    (a) Si és major o igual que 9 i menor o igual que 10, la nota és “Excel·lent”.
 +
    (b) Si és major i igual que 6,5 però estrictament menor que 9, la nota és “Notable”.
 +
    (c) Si és major i igual que 5 però estrictament menor que 6,5, la nota és “Suficient”.
 +
    (d) Si no és cap dels casos anteriors, la nota és de “Suspès”.
 +
</pre>
 +
Aquest cop és el pas 3 el que presenta diferents possibilitats segons si es compleixen certes condicions. En aquest cas, però, hi ha més de d’un camí (n’hi ha quatre). A més a més, cal decidir si es compleix una condició diferent per decidir quin és el camí que cal seguir entre totes les opcions. El darrer es du a terme simplement quan no es compleix cap dels anteriors. Per tant, es tracta d’una selecció múltiple.
 +
 +
Un fet destacat en aquesta descripció de les tasques que ha de dur a terme el programa, com a mínim respecte als exemples anteriors, és que per a cada pas possible s’han de complir dues condicions alhora. El valor de la nota ha d’estar per sota de cert valor i per sobre d’un altre. L’expressió de tipus booleà que cal avaluar per veure quin camí cal seguir ha de comprovar totes dues coses: que es compleix una cosa i l’altra. O sigui, cal una expressió lògica basada en la conjunció de dues comparacions. Un cop més, observeu quines instruccions es corresponen a cadascun dels passos descrits. Fixeu-vos en particular en com són les condicions lògiques per a cada cas.
 +
 +
Compileu i executeu el programa següent per veure com la nota mostrada depèn del valor introduït:
 +
 +
<source lang="java">
 +
import java.util.Scanner;
 +
//Un programa que indica la nota en text a partir de la numèrica.
 +
public class Avaluacio {
 +
 +
  public static void main(String[] args) {
 +
 +
    Scanner lector = new Scanner(System.in);
 +
    System.out.print("Quina nota has tret? ");
 +
    float nota = lector.nextFloat();
 +
    lector.nextLine();
 +
    //Estructura de selecció múltiple.
 +
    //S’entra al bloc on la condició lògica avaluï a true.
 +
    //Si cap no ho fa, s’entra al bloc else.
 +
    System.out.print("La teva nota final és ");
 +
    if ((nota >= 9) && (nota <= 10)) {
 +
      System.out.println("·Excellent.");
 +
    } else if ((nota >= 6.5) && (nota < 9)) {
 +
      System.out.println("Notable.");
 +
    } else if ((nota >= 5) && (nota < 6.5)) {
 +
      System.out.println("Aprovat.");
 +
    } else {
 +
      System.out.println("Suspès.");
 +
    }
 +
    System.out.println("Espero que hagi anat bé...");
 +
  }
 +
}
 +
</source>
 +
El diagrama de flux per a aquest programa en concret es mostra tot seguit, a la figura següent. En aquest cas, el codi seguirà un entre cinc camins possibles, tots disjunts.
 +
 +
[[Imatge:m3uf1_diagrama_flux.png |500px|center| Diagrama de flux]]
 +
 +
'''Una altra possibilitat'''
 +
 +
El programa que tot just s’ha exposat analitza totes les possibilitats a l’hora d’avaluar les notes de manera molt estricta. Totes les condicions possibles són absolutament disjuntes. Mai no es pot donar el cas que dues avaluïn cert, ja que la nota introduïda pertanyerà a un i només a un dels rangs establerts. Ara bé, la selecció múltiple accepta que les condicions no ho siguin. En cas que se’n compleixi més d’una, el bloc d’instruccions que s’executarà serà el de la primera condició que ha avaluat com a true, per ordre d’escriptura en el codi.
 +
 +
Un cop es té una mica d’experiència programant, es pot jugar amb aquest fet, per plantejar aquest programa d’una altra manera:
 +
<pre>
 +
1. Demanar que s’introdueixi la nota pel teclat.
 +
2. Llegir-la.
 +
3. Mostrar un text o un altre segons dins de quin rang de valors es troba la nota:
 +
    (a) Si és major o igual que 9, la nota és “Excel·lent”.
 +
    (b) Si és major o igual que 6,5, la nota és “Notable”.
 +
    (c) Si és major o igual que 5, la nota és “Suficient
 +
    (d) Si no és cap dels casos anteriors, la nota és “Suspès”.
 +
</pre>
 +
En aquest plantejament, l’ordre d’avaluació de les condicions és molt més important.
 +
 +
er a una nota de 9,5 es compleixen totes i cadascuna de les condicions. Però només es durà a terme l’acció relativa a la primera de les enumerades (en aquest cas, la I).
 +
 +
El codi font associat seria el següent, pràcticament idèntic a l’anterior. Compileu-lo i executeu-lo per comprovar que el comportament és el mateix.
 +
 +
<source lang="java">
 +
import java.util.Scanner;
 +
 +
public class AvaluacioSimplificat {
 +
 +
  public static void main(String[] args) {
 +
    Scanner lector = new Scanner(System.in);
 +
    System.out.print("Quina nota has tret? ");
 +
    float nota = lector.nextFloat();
 +
    lector.nextLine();
 +
    //Estructura de selecció múltiple.
 +
    //S’entra al bloc on la condició lògica avaluï a true.
 +
    //Les condicions s’avaluen per ordre d’aparició.
 +
    //Si cap no ho fa, s’entra al bloc else.
 +
    System.out.print("La teva nota final és ");
 +
    if ((nota >= 9) && (nota <= 10)) {
 +
      System.out.println("Excellent.");
 +
    } else if (nota >= 6.5) {
 +
      System.out.println("Notable.");
 +
    } else if (nota >= 5) {
 +
      System.out.println("Aprovat.");
 +
    } else {
 +
      System.out.println("Suspès.");
 +
    }
 +
    System.out.println("Espero que hagi anat bé...");
 +
  }
 +
}
 +
</source>
  
 
==Combinació d’estructures de selecció==
 
==Combinació d’estructures de selecció==
 +
 +
Les sentències que defineixen estructures de selecció són instruccions com qualsevol altre dins d’un programa, si bé amb una sintaxi una mica més complicada.
 +
 +
Per tant, res no impedeix que tornin a aparèixer dins de blocs d’instruccions d’altres estructures de selecció. Això permet crear una disposició de bifurcacions dins el flux de control per tal de dotar al programa d’un comportament complex, per comprovar si es compleixen diferents condicions d’acord amb cada situació.
  
 
===Exemple: descompte màxim i control d’errors===
 
===Exemple: descompte màxim i control d’errors===
 +
 +
Per veure un exemple en què resulta útil la combinació d’estructures de selecció, imagineu que voleu fer un parell de modificacions a l’exemple del càlcul d’un descompte. D’una banda, que hi hagi un valor màxim de descompte, de manera que si
 +
per algun motiu correspon fer un descompte per sobre d’aquest valor, només s’apliqui el màxim establert. D’altra banda, estaria bé corregir un comportament una mica estrany que ara mateix té el programa: que és capaç d’acceptar preus negatius. En aquest cas, com que és evident que l’usuari s’ha equivocat, estaria bé avisar-lo amb algun missatge.
 +
 +
Ara el programa hauria de fer el següent:
 +
<pre>
 +
1. Decidir quin és el valor mínim per optar al descompte, quant es descomptarà i el valor màxim possible.
 +
 +
2. Demanar que s’introdueixi el preu inicial, en euros, pel teclat.
 +
 +
3. Llegir-lo.
 +
 +
4. Comprovar que el preu és correcte i no és negatiu:
 +
 +
  (a) Si es compleix, veure si el preu introduït és igual o superior al valor mínim per optar al descompte:
 +
 +
        i. Si és així, calcular el descompte.
 +
        ii. Comprovar si el descompte supera el màxim permissible:
 +
            A. Si és així, el descompte es redueix al màxim permissible.
 +
        iii. Aplicar el descompte sobre el preu inicial.
 +
 +
  (b) Mostrar el preu final.
 +
 +
  (c) Si el preu era negatiu, mostrar un missatge d’error.
 +
</pre>
 +
Així, doncs, apareixen dues noves condicions. Abans de fer res cal veure si el preu és positiu i, immediatament després de calcular el descompte, cal veure si es compleix la nova condició de si el valor és superior al màxim o no. La articularitat és que ara les diferents condicions del programa només es comproven si les anteriors es van complint,
 +
una darrere de l’altra.
 +
 +
El codi següent fa ús d’una combinació d’estructures de selecció per dur a terme aquesta modificació. Compileu-lo i executeu-lo.
 +
 +
<source lang="java">
 +
public class DescompteControlErrors {
 +
 +
  public static void main(String[] args) {
 +
    // Es fa un descompte del 8%.
 +
    final float DESCOMPTE = 8;
 +
    //Es fa descompte per compres de 100 euros o més.
 +
    final float COMPRA_MIN = 100;
 +
    //Valor del descompte màxim: 20 euros.
 +
    final float DESC_MAXIM = 20;
 +
    Scanner lector = new Scanner(System.in);
 +
    System.out.print("Quin és el preu del producte, en euros? ");
 +
    float preu = lector.nextFloat();
 +
    lector.nextLine();
 +
    // El preu és positiu?
 +
    if (preu > 0) {
 +
      if (preu >= COMPRA_MIN) {
 +
          float descompteFet = preu * DESCOMPTE / 100;
 +
          if (descompteFet > DESC_MAXIM) {
 +
            descompteFet = DESC_MAXIM;
 +
          }
 +
          preu = preu - descompteFet;
 +
      }
 +
      System.out.println("El preu final per pagar és de " + preu + " euros.");
 +
    } else {
 +
          System.out.println("Preu incorrecte. És negatiu.");
 +
    }
 +
  }
 +
}
 +
</source>
 +
 +
Un dels aspectes més importants d’aquest exemple és que el programa ha de ser capaç de comprovar si les dades que ha introduït l’usuari compleixen certes condicions i així avisar-lo de possibles errors. Moltes vegades, per aconseguir-ho cal combinar diferents estructures de selecció, de manera que només se segueix pel camí que processa les dades si es pot garantir que són correctes. De fet, tant en l’exemple d’endevinar un nombre com en el de transformar les notes també valdria la pena fer aquesta comprovació, i veure si el valor introduït està realment entre els valors permissibles (0 i
 +
10).
 +
 +
::*Les estructures de selecció són fonamentals per poder comprovar si les dades que introdueix l’usuari són correctes abans de processar-les.
 +
 +
::*Si una variable es declara dins d’un bloc ( { }) només és visible dintre d’aquest bloc i dels seus blocs “fills”. Per tant fora d’aquests blocs no es podrà utilitzar.
  
 
==La sentència ”switch”==
 
==La sentència ”switch”==
 +
 +
Hi ha una estructura de selecció una mica especial, motiu pel qual s’ha deixat per al final. El que la fa especial és que no es basa a avaluar una condició lògica composta per una expressió booleana, sinó que estableix el flux de control a partir de l’avaluació d’una expressió de tipus enter o caràcter.
 +
 +
La sentència switch enumera, un per un, un conjunt de valors discrets que es volen tractar, i assigna les instruccions que cal executar si l’expressió avalua en cada valor diferent. Finalment, especifica què cal fer si l’expressió no ha avaluat en cap dels valors enumerats. És com un commutador o una palanca de canvis, en què s’assigna un codi per a cada valor possible que cal tractar. Aquest comportament seria equivalent a una estructura de selecció múltiple en què, implícitament, totes les condicions són comparar si una expressió és igual a cert valor. Cada branca controlaria un valor diferent. El cas final és equivalent a l'else. De fet, en la majoria de casos, aquesta sentència no aporta res des del punt de vista del flux de control que no es pugui fer amb una selecció múltiple. Però és molt útil amb vista a millorar la llegibilitat del codi o facilitar la generació del codi del programa. Ara bé, sí que hi ha un petit detall en què aquesta sentència aporta alguna cosa que la resta d’estructures de selecció no poden fer directament: executar de manera consecutiva més d’un bloc de codi relatiu a diferents condicions.
  
 
===Sintaxi i comportament===
 
===Sintaxi i comportament===
 +
 +
La sintaxi de la sentència '''switch''' s’ajusta al format descrit tot seguit. Novament, es basa en una paraula clau seguida d’una condició entre parèntesis i un bloc de codi entre  claus. Ara bé, la diferència respecte de les sentències vistes fins ara és que els conjunts d’instruccions assignats a cada cas independent no es distingeixen entre si per claus. Aquests es van enumerant com un conjunt d’apartats etiquetats per la paraula clau '''case''', seguida del valor que es vol tractar i de dos punts. De manera opcional, es pot posar una instrucció especial que serveix de delimitador de final d’apartat, nomenada '''break'''. Al final de tots els apartats se’n posa un d’especial (opcional), anomenat '''default'''.
 +
 +
<source lang="java">
 +
switch(expressió de tipus enter, caràcter o text) {
 +
    case valor1:
 +
          instruccions si l’expressió avalua a valor1
 +
          (opcionalment) break;
 +
    case valor2:
 +
          instruccions si l’expressió avalua a valor2
 +
          (opcionalment) break;
 +
    ...
 +
    case valorN:
 +
          instruccions si l’expressió avalua a valorN
 +
          (opcionalment) break;
 +
    (opcionalment ) default:
 +
          instruccions si l’expressió avalua a algun valor que no és valor1...valorN
 +
          (opcionalment) break;
 +
}
 +
</source>
 +
 +
En executar la sentència switch s’avalua l’expressió entre parèntesis i immediatament s’executa el conjunt d’instruccions assignat a aquell valor entre els diferents apartats '''case'''. Si no n’hi ha cap amb aquest valor entre els disponibles, llavors s’executa l’apartat etiquetat com a '''default''' (per defecte).
 +
 +
Cal dir que els valors no han de seguir cap ordre en concret per definir cada apartat. Si bé pot ser més polit enumerar-los per ordre creixent, això no té cap efecte sobre el comportament del programa.
 +
 +
La particularitat especial d’aquesta sentència la tenim en l’ús de la instrucció '''break'''. Aquesta indica què cal fer un cop executades les instruccions de l’apartat.
 +
 +
Si apareix la instrucció, el programa se salta la resta d’apartats i continua amb la instrucció posterior a la sentència '''switch''' (després de la clau que tanca el bloc). En aquest aspecte, si tots els apartats acaben en '''break''', el funcionament de switch és equivalent a fer:
 +
 +
<source lang="java">
 +
if (expressió == valor 2) {
 +
      instruccions si l’expressió avalua a valor1
 +
} else if (expressió == valor2) {
 +
      instruccions si l’expressió avalua a valor2
 +
...
 +
} else if (expressió == valorN) {
 +
      instruccions si l’expressió avalua a valorN
 +
} else {
 +
      instruccions si l’expressió avalua a algun valor que no és valor1...valorN
 +
}
 +
</source>
 +
 +
Ara bé, si algun dels apartats no acaba en break, en executar la darrera instrucció, en lloc de saltar la resta d’apartats, el que es fa és seguir executant les instruccions de l’apartat que ve immediatament després. Així anirà fent, apartat per apartat, fins trobar-ne algun que acabi en break. La figura següent mostra aquest comportament tan particular.
 +
 +
[[Imatge:m3uf1_switch.png |600px|center| Switch]]
 +
 +
::*A partir de la versió 7 de Java es pot fer servir un String (text) per a avaluar l’expressió
 +
'''
 +
:Exemple: Traduir un número de mes a text'''
 +
<source lang="java">
 +
public class TraduccioMes {
 +
 +
  public static void main(String[] args) {
 +
      int mes;
 +
      Scanner teclat = new Scanner(System.in);
 +
      System.out.println("Introdueixi el número de mes a traduir: ");
 +
      mes = teclat.nextInt();
 +
      switch (mes) {
 +
        case 1:
 +
            System.out.println("Traducció: Gener\n");
 +
            break;
 +
        case 2:
 +
            System.out.println("Traducció: Febrer\n");
 +
            break;
 +
        case 3:
 +
            System.out.println("Traducció: Març\n");
 +
            break;
 +
        case 4:
 +
            System.out.println("Traducció: Abril\n");
 +
            break;
 +
        case 5:
 +
            System.out.println("Traducció: Maig\n");
 +
            break;
 +
        case 6:
 +
            System.out.println("Traducció: Juny\n");
 +
            break;
 +
        case 7:
 +
            System.out.println("Traducció: Juliol\n");
 +
            break;
 +
        case 8:
 +
            System.out.println("Traducció: Agost\n");
 +
            break;
 +
        case 9:
 +
            System.out.println("Traducció: Setembre\n");
 +
            break;
 +
        case 10:
 +
            System.out.println("Traducció: Octubre\n");
 +
            break;
 +
        case 11:
 +
            System.out.println("Traducció: Novembre\n");
 +
            break;
 +
        case 12:
 +
            System.out.println("Traducció: Desembre\n");
 +
            break;
 +
        default:
 +
            System.out.println("No existeix un mes amb número: " + mes);
 +
      }
 +
  }
 +
}
 +
</source>
  
 
==Control d’errors en l’entrada bàsica mitjançant estructures de selecció==
 
==Control d’errors en l’entrada bàsica mitjançant estructures de selecció==
 +
 +
Les estructures de selecció són especialment útils com a mecanisme per controlar si les dades que ha introduït un usuari són correctes abans d’usar-les dins del programa. Un cop ja sabeu com funcionen, és un bon moment per ampliar les explicacions sobre l’entrada bàsica de dades per teclat, de manera que sigui possible controlar si el valor que s’ha introduït encaixa amb el tipus de dada esperat per a cada instrucció de lectura.
 +
 +
Si es parteix que l’extensió per llegir dades de teclat s’ha inicialitzat anteriorment com sempre:
 +
<pre>
 +
  Scanner lector = new Scanner(System.in);
 +
</pre>
 +
 +
Abans de llegir qualsevol dada introduïda pel teclat, és possible usar les instruccions de la taula següent per establir si la dada que tot just s’ha escrit pel teclat és d’un tipus concret o no. Quan s’usen, l’usuari pot introduir dades pel teclat (el programa s’atura) i s’avalua si el que ha escrit pertany a un tipus de dada o un altre. Aquestes instruccions es consideren expressions booleanes que avaluen com a true si el tipus concorda i com a false si no és el cas. Un cop usada aquesta instrucció, només es podran llegir les dades correctament usant la instrucció lector.next... corresponent al mateix tipus si ha avaluat com a true. Si s’intenta després que hagi avaluat false, l’error d’execució està garantit.
 +
 +
{|border="2" cellpadding="4" cellspacing="0" style="margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse; font-size: 95%;"
 +
! align="left" width="150 px"; color:Black"|Instrucció
 +
! align="left" width="100 px"; color:Black"|Tipus de dada controlada
 +
|-
 +
|lector.hasNextByte()||byte
 +
|-
 +
|lector.hasNextShort()||short
 +
|-
 +
|lector.hasNextInt()||int
 +
|-
 +
|lector.hasNextLong()||long
 +
|-
 +
|lector.hasNextFloat()||float
 +
|-
 +
|lector.hasNextDouble()||double
 +
|-
 +
|lector.hasNextBoolean()||boolean
 +
|}
 +
 +
La instrucció associada a una cadena de text no existeix, ja que qualsevol dada escrita pel teclat sempre es pot interpretar com a text. Per tant, la lectura mai no pot donar error.
 +
 +
L’exemple anterior amb control d’errors ens quedaria així :
 +
<source lang="java">
 +
public class TraduccioMes {
 +
 +
  public static void main(String[] args) {
 +
      int mes;
 +
      Scanner teclat = new Scanner(System.in);
 +
      System.out.println("Introdueixi el número de mes a traduir: ");
 +
      if (teclat.hasNextInt()) {
 +
        mes = teclat.nextInt();
 +
        switch (mes) {
 +
            case 1:
 +
              System.out.println("Traducció: Gener\n");
 +
              break;
 +
            case 2:
 +
              System.out.println("Traducció: Febrer\n");
 +
              break;
 +
            case 3:
 +
              System.out.println("Traducció: Març\n");
 +
              break;
 +
            case 4:
 +
              System.out.println("Traducció: Abril\n");
 +
              break;
 +
            case 5:
 +
              System.out.println("Traducció: Maig\n");
 +
              break;
 +
            case 6:
 +
              System.out.println("Traducció: Juny\n");
 +
              break;
 +
            case 7:
 +
              System.out.println("Traducció: Juliol\n");
 +
              break;
 +
            case 8:
 +
              System.out.println("Traducció: Agost\n");
 +
              break;
 +
            case 9:
 +
              System.out.println("Traducció: Setembre\n");
 +
              break;
 +
            case 10:
 +
              System.out.println("Traducció: Octubre\n");
 +
              break;
 +
            case 11:
 +
              System.out.println("Traducció: Novembre\n");
 +
              break;
 +
            case 12:
 +
              System.out.println("Traducció: Desembre\n");
 +
              break;
 +
            default:
 +
              System.out.println("No existeix un mes amb número: " + mes);
 +
        }
 +
      } else {
 +
            System.out.println("Introdueix un número enter, inutil!!!");
 +
      }
 +
  }
 +
}
 +
</source>
 +
-->

Revisió de 18:35, 6 oct 2020

Condicional if

  • Permet decidir si en funció d’una condició cal o no executar una o un conjunt d’instruccions.
instruccions del programa
  if (expressió booleana) {
        Instruccions per executar si l’expressió avalua a true (cert)
  }
  resta d’instruccions del programa
  • La condició te dues respostes possibles: Certa o Falsa. Si és certa s’executarà el procediment i sinó no
  • S’executarà i la execució continuarà amb les sentencies que hi hagi a continuació del bloc if.

Exemple:

import java.util.Scanner;

public class MajorEdat {

  public static void main(String[] args) {
    //Decidir si una persona es major de edat.
    final int MAJOREDAT = 18;
    int edat;
    Scanner lector = new Scanner(System.in);
    System.out.print("Quina edat tens? ");
    edat = lector.nextInt();
    if (edat >= 18){
      System.out.println("Ets major d'edat");

    }
    if (edat < 18){
      System.out.println("Ets menor d'edat");
    }
  }
}
  • Si entre els parèntesis es posa una expressió que no avalua un resultat de tipus booleà, hi haurà un error de compilació.

Condicionals else i else if

import java.util.Scanner;

public class MajorEdat {

  public static void main(String[] args) {
    //Decidir si una persona es major de edat.
    final int MAJOREDAT = 18;
    int edat;
    Scanner lector = new Scanner(System.in);
    System.out.print("Quina edat tens? ");
    edat = lector.nextInt();
    if (edat >= 18){                                // S'executa si la condició de l'if és falsa
      System.out.println("Ets major d'edat");  

    }
    else{
      System.out.println("Ets menor d'edat");
    }
  }
}
// Si necessitem comprovar un altre valor de l'edat podem utilitzar elif

import java.util.Scanner;

public class MajorEdat {

  public static void main(String[] args) {
    //Decidir si una persona es major de edat.
    final int MAJOREDAT = 18;
    int edat;
    Scanner lector = new Scanner(System.in);
    System.out.print("Quina edat tens? ");
    edat = lector.nextInt();
    if (edat >= 18){                              // S'executa si la condició de l'if és falsa
      System.out.println("Ets major d'edat");  

    }
    else if (edat >= 16) {                        // es comprova només si la condició de l'if és falsa
      System.out.println("Ets adolescent i menor d'edat");
      
    }
    else{                                         // S'executa només si la condició de l'elif és falsa
      System.out.println("Ets menor d'edat");
    }
  }
}
  • Es poden posar tants else if com necessitem

La sentència ”switch”

  • Quan l’avaluació d’una expressió és de tipus enter o caràcter.
  • Millora la llegibilitat del codi
  • Es poden executar de manera consecutiva més d'un bloc.

Sintaxi i comportament

  • Es basa en una paraula clau seguida d’una condició entre parèntesis i un bloc de codi entre claus
  • La paraula clau case seguida del valor i de dos punts indica les instruccions assignats a cada cas.
  • A paritr del case que avalua a cert s'executaran tots els blocs d'instruccions fins a trobar el delimitador break.
  • Al final de tots els apartats se’n posa un d’especial (opcional), anomenat default.
switch(expressió de tipus enter, caràcter o text) {
     case valor1:
          instruccions si l’expressió avalua a valor1
          (opcionalment) break;
     case valor2:
          instruccions si l’expressió avalua a valor2
          (opcionalment) break;
     ...
     case valorN:
          instruccions si l’expressió avalua a valorN
          (opcionalment) break;
    (opcionalment ) default:
          instruccions si l’expressió avalua a algun valor que no és valor1...valorN
          (opcionalment) break;
}
  • Els valors no han de seguir cap ordre concret.
  • Quan s'arriba a una sentencia break: el programa se salta la resta d’apartats i continua amb la instrucció posterior a la sentència switch
  • Si no hi ha instrucció break al final d'un bloc s'executaran les instruccions dels següents blocs fins trobar-ne algun bloc que acabi en break. La figura següent mostra aquest comportament tan particular.
Switch
  • A partir de la versió 7 de Java es pot fer servir un String (text) per a avaluar l’expressió
Exemple: Traduir un número de mes a text
public class TraduccioMes {

   public static void main(String[] args) {
      int mes;
      Scanner teclat = new Scanner(System.in);
      System.out.println("Introdueixi el número de mes a traduir: ");
      mes = teclat.nextInt();
      switch (mes) {
         case 1:
            System.out.println("Traducció: Gener\n");
            break;
         case 2:
            System.out.println("Traducció: Febrer\n");
            break;
         case 3:
            System.out.println("Traducció: Març\n");
            break;
         case 4:
            System.out.println("Traducció: Abril\n");
            break;
         case 5:
            System.out.println("Traducció: Maig\n");
            break;
         case 6:
            System.out.println("Traducció: Juny\n");
            break;
         case 7:
            System.out.println("Traducció: Juliol\n");
            break;
         case 8:
            System.out.println("Traducció: Agost\n");
            break;
         case 9:
            System.out.println("Traducció: Setembre\n");
            break;
         case 10:
            System.out.println("Traducció: Octubre\n");
            break;
         case 11:
            System.out.println("Traducció: Novembre\n");
            break;
         case 12:
            System.out.println("Traducció: Desembre\n");
            break;
        default:
            System.out.println("No existeix un mes amb número: " + mes);
      }
   }
}