|
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.
|
|
|
 |
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");
} |
|
 |
- 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:
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.
|
|
|
 |
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?
|
|
|
 |
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ó.
|
|
|
|
|
|
|
 |
|
|
|
|