Enrera
Mòdul 2
Iniciació a la programació en Java
  Pràctica
1
2
3
4
4
   
Exercicis
Exercicis
 
 
  Control del flux
   

A trvés d'aquesta pràctica revisarem les eines de control per a programar en Java. Aprendrem a utilitzar estructures de control d'execució. També aprendrem a configurar JCreator per tal que accepti programes amb paràmetres.

   
Desenvolupament de la pràctica
   
 

En primer lloc veurem com són les estructures de control al llenguatge Java. Després, escriurem un petit programa d'exemple i per a executar-lo configurarem JCreator amb la finalitat que accepti programes amb paràmetres.

Java utilitza totes les sentències de control d'execució de C. Es va dissenyar així per tal de fer fàcil als programadors la transició d'un llenguatge a l'altre. Si ja heu programat en C o C++, els continguts d'aquest apartat us seran absolutament familiars.

   
Atenció ! Les estructures de control de flux.
   
 

Tots els llenguatges utilitzen algun tipus de sentència de control i, gairebé sempre, són molt semblants d'un llenguatge a un altre. Aquestes sentències són les que el llenguatge utilitza per tal d'aconseguir que el flux del programa avanci i prengui el camí adequat en funció dels canvis d'estat de les dades.

Java utilitza les sentències  while,  if-else,  for,  do-while,  switch,  break, continue, return  i  try-catch-throw. Les dividirem en sentències de salt, sentències d'iteració i sentències de control general del flux.

   

Sentències de salt:

  • Sentència if/else

    Aquest és el control bàsic de flux de programes. El tancament else és opcional.

    if ( <expressió lògica> ) {
        <el que sigui>;
    } [ else {
        <el que sigui>;
    } ]

    Com hem dit, l'expressió condicional ha de produir un resultat lògic, és a dir, true o false. La sentència pot ser simple, acabada en un punt i coma, o pot ser composta i tan llarga com interessi, sempre que estigui tancada per un parell de claus:

    if (a!=0) demanaUnAltreValor(); // Això és correcte


    if (a!=0) { demanaUnAltreValor(); } // Això també és correcte


    if (a!=0) {
        demanaUnAltreValor();
    } else {
        executaUnaAccio();
    } // Això també és correcte

  • Sentència switch

    switch( <expressió> ) {
        case valor1:
            <el que sigui>;
            break;
        case valor2:
            <el que sigui>;
            break;
        [default:
            <el que sigui>;]
    }

    Amb aquesta sentència trametem l'execució del programa a parts diferents de codi en funció del valor d'una variable o expressió. Aquesta variable o expressió de control es diu la variable de control del switch, i ha de ser necessàriament del tipus int o char - no pot ser una cadena -. Si hem de ramificar a partir de variables de cadena (string) o de nombres amb coma flotant, hem d'utilitzar una sèrie de sentències if.

    Observem que cada
    case acaba amb un break. Això fa que l'execució salti fins al final del switch. Aquesta és la construcció habitual d'aquesta sentència, però el break no és obligatori. Si no el posem s'executa el codi de les sentències case següents fins que el programa no troba un break. Atenció amb aquesta característica!. És relativament freqüent oblidar el break al construir una sentència switch i el compilador no ens donarà error.

    A la part final del switch podem posar la sentència default. El codi que contingui s'executarà si el programa no ha trobat cap case per la variable de control. Si no posem sentència default i el programa no troba cap coincidència entre variable de control i case, el programa no fa res.

    switch és una sentència molt més eficaç i ràpida que if. L'hem d'utilitzar sempre que sigui possible.

    Aquí en tenim algun exemple:

    int control;

        switch(control) {
            case 0: System.out.println("Commutem a acció 0");
                     break;
            case 1: System.out.println("Commutem a acció 1");
                     break;
            default: System.out.println("Número de control
                                         desconegut");
    }

    En aquest cas, aprofitem l'absència de breaks.

    char lletres;

        switch(char) {
            case 'a': // Continuem
            case 'e': // Continuem
            case 'i': // Continuem
            case 'o': // Continuem
            case 'u': System.out.println("el caràcter triat és una
                                          vocal");
                      break;
            default: System.out.println("el caràcter triat és una
                                         consonant");
    }
Atenció !
  • Sun ens recomana que utilitzem sempre les claus en les sentències Java, encara que
    es tracti de sentències simples. Aquest costum fa el codi més fàcil de llegir.
  Sentències d'iteració
   
 
  • Sentència for

    for ( <inicialització>; <acabament>; <iteració> ) {
        <el que sigui>;
    }

    Les sentències d'iteració executen repetidament les sentències que contenen, en un cicle que només acaba quan les variables de control contenen algun valor determinat.

    El cicle (loop) for habitualment fa tres accions en el moment que s'executa: s'inicialitzen les variables de control, es verifiquen les variables de control i se n'actualitzen els valors:

    for ( int i=0; i<10; i++) {
        System.out.println("Valor de i: "+i);
    }

    Aquesta estructura inicialitza la variable "i" amb el valor 0, comprova que "i" sigui menor que 10 i actualitza el seu valor sumant-li una unitat a cada volta del cicle.

    Les variables de control poden ser més d'una. Aquesta sentència seria correcta:

    for (int i=0, n=500; i < 10; i++,n-=10) {
        System.out.println("Valor de n: "+n);
    }

    La sentència for inicialitza els enters "i" i "n" (  sempre d'esquerra a dreta, primer "i", després "n"). Òbviament, aquesta acció d'inicialització només es fa a la primera vegada que executem la sentència for.

    La segona part ha de ser de tipus lògic. Quan s'avalua a false, se surt del cicle. Aquesta secció s'executa a l'inicialitzar i a cada pas de la sentència.

    La darrera clàusula se situa a la capçalera de la sentència, però no s'executa al primer pas. Ho fa la segona vegada que es passa pel començament del cicle. En aquest cas a "i" se li suma una unitat a cada pas i a "n" se li'n resten 10.

    De les tres clàusules, només és obligatòria la segona. Inicialització i comptador poden no ser-hi presents:

    for (;n<10;) {
        System.out.println("Aquesta sentència és vàlida, però el
                            cicle és infinit sinó modifico 'n' en
                            algun lloc");
    }

  • Sentència while

    [ <inicialització>; ]
        while ( <expressió condicional> ) {
            <el que sigui>;
            <iteració>;
        }

    Aquesta estructura executa repetidament una o vàries sentències mentre no canvïi la condició d'entrada. L'expressió condicional es verifica des del primer pas del cicle. Si aquesta expressió és inicialment false, el cicle no s'executa.

    int n = 0;

    n = 10; // Si n és igual a 10, el bucle no s'executa.

        while ( n < 10 ) {
            System.out.println("Valor de n: "+n);
            n++;
        }


  • Sentència do - while:

    A vegades ens interessa que s'executi el
    cos d'un cicle sense considerar l'estat de les variables de control. En aquests casos treballarem amb sentències do while:

    [<inicialització>;]

        do {
            <el que sigui>;
            [ <iteració>; ]
        } while ( <expressió condicional> );

    "while" queda al final del cos del cicle i s'executa quan s'acaben les sentències del cos. Per exemple:

    int n=100;

        do {
                if (n%2==0) {
                    System.out.println("Valor de n: "+n);
                   
    // Imprimim els parells
                }
            n--;
        } while ( n>0 );

   
  Sentències de Control General
   
 
  • Sentències  break  i  continue

    La sentència "break", que ja hem vist en tractar la sentència "switch", pot anar també a l'interior d'un cicle. Quan el programa es troba amb un "break", surt del cicle sense executar res més. Si troba una sentència "continue", llavors salta al començament del cicle.

    Les sentències "break" i "continue" es poden etiquetar i llavors, obliguen el programa a saltar al lloc on hem situat l'etiqueta. Es tracta d'un mecanisme similar al de la sentència "goto" dels llenguatges antics.

    Aquí tenim un exemple de l'ús de break i continue:

    for (int i=0; i< 1000; i++) {
            if ( i == 836) break; // A l'arribar a 836, acaba el
                                  // cicle
            if (i % 3 != 0) continue; // Si el número no és divisible
                                      // entre 3 torna al for. Només
                                      // s'imprimiran els valors
                                      // divisibles entre 3

        System.out.println("El valor de i és: "+i);
    }


  • Sentència return:

    return expressió;


    La sentència return es fa servir per acabar un mètode o funció i retornar un valor al mètode que l'ha cridat. Si hem definit un mètode amb tipus, hem d'escriure un "return" d'aquest tipus. Per exemple:

    boolean esZero(int unnumero) {
        return (unnumero==0);
    // retorna true si un número és
                              // igual a 0

    }


  Excepcions:
   
 

Tractarem les excepcions amb tot detall més endavant. Ara només cal ser capaç de reconéixer l'estructura d'una sentència de control d'excepcions:

try {
    <el que sigui>;
} catch (Exception e) {
    <el que sigui>;
}

El programa intenta executar les sentències interiors al "try". Si es produeix qualsevol error, el programa llança una excepció. Aquesta excepció la captura el "catch" i podem recuperar-nos executant les sentències del seu interior:

double aixonopotser;

    try {
        aixonopotser = 25 / 0;
    } catch( Exception e) {
/* Com que no podem dividir, ens recuperem assignant
* a aixonopotser el valor 0.
*/

        aixonopotser = 0;
        System.out.println("ep, no podem fer divisions per zero!");
    }

Ja veurem que a Java hi tenim moltes excepcions predefinides que ens faciliten la gestió dels errors.

   
Pràctica

Ara un programa amb un " if ":

  Ara escriurem un petit programa amb JCreator:

/**
* Demostració de la utilització del control "if" i d'algunes
* conversions
*
*
* @author Carles Romero
* @author Angel Solans
* @version 0.1
* @since java 1.3.1_04
*
*/


public class AreaCercle {

/* El mètode static main() recull paràmetres de la consola i els
* passa a la matriu de cadenes "args"
*/

    public static void main(String args[]) {
/* la matriu args té un mètode públic de la classe array, length(),
* el qual, en cridar-lo, ens proporciona la longitud, és a dir, el
* nombre d'elements, buits o no, que hi ha a la matriu (array).
*
* System.exit(1) tanca el programa
*
* Per tant, si no hem entrat paràmetres, sortirem del programa.
*/

            if (args.length != 1) {
                System.out.println("Paràmetre: radi en                                     centímetres)");
                                    System.exit(1);
            
}

/* La variable PI la declarem final, això vol dir que no podrà
* canviar mai de valor. L'escrivim en majúscules
* De fet, és com les constants d'altres llenguatges
*/

        final double PI = 3.14;

/* El radi el recollim d'un paràmetre d'entrada.
* args és una matriu de cadenes, no de nombres.
* Hem de convertir la cadena a "double" o a "int"
*/
        double radi = Double.parseDouble(args[0]);

/* El símbol + concatena una cadena amb el resultat de l'operació
* PI*radi*radi * el resultat és una cadena
*/

        String out = "L'àrea del cercle és " + PI*radi*radi;         System.out.println(out + " centímetres");
    }
}

Repassem la utilització de la sentència if al programa. Estudieu el codi i intenteu descobrir com Java tracta la conversió entre tipus i com construeix les "constants".

Si intentem executar el programa amb JCreator, la resposta del programa serà sempre com aquesta:

Com que no hem introduït cap paràmetre, el programa ens informa d'aquesta circumstància i surt.

Com ho hem de fer perquè JCreator accepti paràmetres?

   
Pràctica

Executar amb JCreator programes que necessiten paràmetres d'entrada:

   

JCreator disposa de l'eina "Runtime configuration" que ens permet variar les condicions en què s'executa el nostre projecte. Quan necessitem introduir paràmetres, quan hem de provar els nostres applets en diferents navegadors o quan el projecte conté més d'un fitxer executable -com és el cas del projecte modul1- hem de configurar JCreator.

  • Obrim el desplegable del botó d'execució de projecte i obrim la finestra de configuració:

  • Piquem sobre "New" per a donar d'alta una nova entrada de configuració en temps d'execució.

  • Omplim les dades de la forma següent:


  • Posem l'etiqueta identificadora del programa que volem executar. A "Run", escrivim el nom del programa i a "Main" el paràmetre o paràmetres que ha de tenir el programa. Acceptem els canvis.

  • Ara ja podem executar el programa amb paràmetres picant sobre el desplegable d'execució de projecte "Programa Àrea d'un Cercle":

  • Quan estem en fase de desenvolupament d'un projecte, podem anar afegint entrades al menú de "Runtime Configuration" amb diferents paràmetres. És un instrument ràpid per a provar els programes amb diferents condicions d'execució.
   
   
 
Amunt