Escolar Documentos
Profissional Documentos
Cultura Documentos
TEMA 5: INSTRUCCIONES Y MATRICES
1. INTRODUCCIÓN.
En el presente tema se verá, en primer lugar, cómo se programan las instrucciones, destacando
las instrucciones de control de flujo. Se han incluido también las matrices, describiéndose la forma
de declarar, crear y manipular matrices en Java.
Todos estos contenidos se supone que ya son conocidos por el alumno, por lo que nos
centraremos en describir cómo se implementan en Java.
En el siguiente tema, en el que se verán los paquetes de Java, se estudiará la clase Arrays, la
cual incluye métodos que facilitan en trabajo con matrices.
2. INSTRUCCIONES
Los siguientes tipos de expresiones dan lugar a instrucciones simplemente añadiendo un punto
y coma tras ella:
● expresiones de asignación,
● expresiones de incremento o decremento (++ ó −− ),
● llamadas a métodos, y
● expresiones de creación de objetos.
A este tipo de instrucciones se las conoce habitualmente como instrucciones de expresión.
Hay otros dos tipos de instrucciones —las instrucciones de declaración de variables y las
instrucciones de control— que se estudiarán a continuación, pero antes introduciremos la noción de
bloque.
Un bloque es un grupo de cero o más instrucciones, encerradas entre llaves, dando lugar a una
instrucción compuesta.
{ <instrucción 1>
. . .
<instrucción N>
}
Un bloque se puede usar en cualquier parte donde se necesite una instrucción simple.
2.1 Instrucciones de declaración de variables
Ya hemos visto varias declaraciones de variables; las instrucciones de declaración de variables
tienen la forma:
<tipo> <n . variable>
1
Tema 5: Instrucciones y matrices D.I.G.
2.2 Instrucciones de control de flujo
Las instrucciones de control de flujo controlan el orden en que se ejecutan las instrucciones de
los programas. Estas instrucciones pueden ser de uno de los siguientes cuatro tipos:
● instrucciones de repetición (while , do−while , for ),
● instrucciones de selección ( if−else , switch−case ),
● instrucciones para el control de excepciones (try−catch−finally , throw ), o
● instrucciones de salto/ramificación (break , continue , label: , return ).
La sintaxis y funcionamiento de la mayoría de estas instrucciones es similar a la que
encontramos en otros lenguajes, en particular en los lenguajes de la familia de los lenguajes C y C++,
que suponemos conocida, y por tanto vamos a pasar muy rápidamente por la descripción de estas
instrucciones.
Instrucciones de repetición
La sintaxis de las instrucciones de repetición es la siguiente:
while (<exp . booleana>)
<instrucción>
do
<instrucción>
while (<exp . booleana>) ;
for (<exp1>; <exp . bool>; <exp2>)
<instrucción>
Obsérvese que aunque el cuerpo de estas instrucciones —y de la mayoría de las disponibles en
Java— requiere una única instrucción, podemos tener tantas instrucciones como necesitemos
simplemente utilizando llaves para construir un bloque . De hecho, aunque tengamos una única
instrucción en el cuerpo de una de estas instrucciones, se suele recomendar utilizar igualmente llaves,
de forma que el código sea más fácil de leer y facilite la modificación del mismo.
De estas instrucciones la que tiene un comportamiento más particular es la instrucción for.
Esta instrucción proporciona una forma compacta de iterar sobre un rango de valores. Su primer
argumento es una expresión que inicializa el bucle, que se ejecuta una única vez al principio del bucle.
El segundo argumento es una expresión lógica que expresa la condición de terminación, de salida del
bucle; el bucle se ejecuta mientras esta expresión se evalúa a true. El tercer argumento es una
expresión que sirve para indicar el incremento de la variable de control del bucle; esta expresión se
evalúa al final de cada iteración. Estos tres componentes son opcionales, podemos por ejemplo
escribir una bucle infinito simplemente no especificando ninguno de ellos:
for ( ; ; ) {
. . .
}
El uso habitual de la instrucción for será el siguiente, donde utilizamos una variable i sobre
2
Tema 5: Instrucciones y matrices D.I.G.
la que iteramos de forma que vaya variando de 0 a 19.
for ( int i = 0; i < 20; ++ i ) {
. . .
}
El ámbito de las variables declaradas en la expresión de inicialización de una instrucción for
va desde su declaración hasta el final del cuerpo de la instrucción.
Pero en realidad podemos hacer un uso bastante más oscuro de las instrucciones for ; por
ejemplo, con el siguiente bucle podríamos recorrer las posiciones de una array array1 de atrás
adelante (los arrays se estudian en el apartado 3).
for ( int i = array1.length ; −−i >= 0 ; ) {
. . .
}
Más adelante veremos que existe una sintaxis de for especial para arrays y colecciones.
Instrucciones de selección
Las instrucciones de selección permiten a un programa ejecutar unas instrucciones u otras
dependiendo del resultado de la evaluación de una o varias condiciones. Dentro de las instrucciones
condicionales tenemos las instrucciones if−else y switch−case .
La forma general de la instrucción if es la siguiente:
if (<exp−bool>)
<instrucción 1>
else
<instrucción 2>
Aunque puede tener varias variantes; puede utilizarse sin la parte else ,
if (<exp−bool>)
<instrucción>
o encadenando varias instrucciones if :
if (<exp−bool1>)
<instrucción 1>
else if (<exp−bool2>)
<instrucción 2>
. . .
else
<instrucción N>
En el tema anterior presentamos el operador ?: , que proporciona una versión compacta de la
instrucción if . Este operador toma tres argumentos, una expresión booleana y dos expresiones de
tipos compatibles entre sí, y devuelve el resultado de evaluar una u otra dependiendo del valor de la
expresión booleana.
<exp−bool> ? <exp1> : <exp2>
3
Tema 5: Instrucciones y matrices D.I.G.
Por ejemplo, el siguiente fragmento de código escribe un texto indicando si un carácter
determinado (variable car ) es mayúscula o minúscula.
System.out.println( ” El carácter ” + car + ” es ” +
( Character.isUpperCase( car ) ? ”mayúscula ” : ” minúscula ” ) ) ;
Cuando necesitamos elegir entre más de dos opciones es muy útil la instrucción switch , la
cual nos permite ejecutar unas instrucciones u otras atendiendo al valor resultante de evaluar una
expresión entera. Tras evaluar la expresión entera dada se selecciona el bloque de instrucciones cuya
constante coincide con el resultado de la evaluación de la expresión (case).
La sintaxis de la instrucción switch es la siguiente:
switch (<exp−ent>) {
case <expr−ent1>:
<instrucción 11>
<instrucción 12>
. . .
break ;
case <expr−ent2>:
<instrucción 21>
<instrucción 22>
. . .
break ;
. . .
default :
<instrucción N1>
. . .
break ;
}
La expresión <exp−ent> debe ser de tipo char , byte , short o int , y las constantes de cada
case deben ser de ese tipo o de un tipo compatible. Si encuentra una constante que coincide con la
expresión, se ejecutan sus instrucciones hasta que se encuentra un case . Si no se encontrara una
constante con el valor resultante de la evaluación de la condición se ejecutarían las instrucciones en el
bloque default .
El siguiente ejemplo muestra un fragmento de código donde se escribe el nombre del mes
correspondiente al número almacenado en una variable mes .
int mes ;
. . .
switch (mes) {
case 1: System.out.println( ”Enero” ) ;
break ;
case 2: System.out.println( ”Febrero” ) ;
break ;
. . .
4
Tema 5: Instrucciones y matrices D.I.G.
case 12: System.out.println( ”Diciembre” ) ;
break ;
}
Es importante destacar el papel de los break al final de cada case. Al encontrarse un case
cuya constante coincide con el resultado de evaluar la expresión entera del switch se ejecuta una tras
otra todas las instrucciones a partir de ese punto hasta alcanzar un break , momento en el que se
saltaría a la instrucción inmediatamente después de la instrucción switch ; si no se alcanzara un break
, se seguirían ejecutando instrucciones de los case siguientes. El siguiente ejemplo asigna a la variable
númDías el número de días del mes correspondiente al entero almacenado en la variable mes .
int mes , númDías ;
. . .
switch (mes) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: númDías = 31;
break ;
case 4:
case 6:
case 9:
case 11: númDías = 30;
break ;
case 2: i f . . .
else . . .
}
Instrucciones de manejo de excepciones
Java dispone de un valioso mecanismo para el tratamiento de errores conocido como control
de excepciones . Básicamente, cuando se produce un error en un método se genera un objeto de la
clase Exception , o de alguna heredera de ésta, con información sobre el error, se interrumpe el flujo
normal de ejecución, y el entorno de ejecución trata de encontrar un manejador para dicho objeto, es
decir, un tratamiento para la situación excepcional, dentro del propio método o en uno anterior en la
pila de activaciones.
Existen tres instrucciones relacionadas con el control de excepciones: try , que delimita un
bloque de instrucciones donde se puede producir una excepción, catch que identifica un bloque de
código asociado a un bloque try donde se trata un tipo particular de excepción, y finally , que
identifica un bloque de código que se ejecutará después de un bloque try con independencia de que
se produzcan o no excepciones.
Tendremos un tema enteramente dedicado al manejo de excepciones, aquí nos limitamos a las
5
Tema 5: Instrucciones y matrices D.I.G.
explicaciones dadas y a introducir su sintaxis. El aspecto normal de un segmento de código con
control de excepciones sería el siguiente:
try {
<instrucciones>
} catch (<t ipo−excepción> <identif >) {
<instrucciones>
}
.. .
} catch(<t ipo−excepción> <identif >) {
<instrucciones>
} finally {
<instrucciones>
}
3. ARRAYS
3.1. Introducción
Un array se define como una colección ordenada de datos (todos del mismo tipo) con un
tamaño prefijado. Los arrays en Java son objetos que deben crearse; es en este momento donde se
establece qué tipo de datos contendrá el array y cuál será su tamaño.
3.2. Declaración y creación de una matriz
Un array puede contener tipos básico o referencia a objetos. La declaración de una referencia
a un array tiene la siguiente sintaxis:
<tipo−clase> [ ] <nombre−array>
o alternativamente
<tipo−clase> <nombre−array> [ ] .
donde <tipo−clase> se refiere al tipo (tipo básico, clase o interfaz) de los elementos que se
introducirán en el array y nombre−array será el nombre de la referencia. Por ejemplo,
int [ ] arInt;
Punto[ ] arPto ;
Punto oarPto [ ] ;
declaran que arInt es un array de enteros y arPto y oarPto un array de puntos cada uno.
Si el tipo que contiene un array resulta ser otro array entonces se está construyendo un array
bidimiensional. Es posible crear arrays de cualquier dimensión1. La expresión
Punto [ ] [ ] aarPto ;
declara aarPto como una referencia a un array de arrays de puntos.
1 Java no soporta matrices multidimensionales, pero se puede lograr la misma funcionalidad declarando matrices de
matrices.
6
Tema 5: Instrucciones y matrices D.I.G.
Para construir un array se utiliza la sintaxis
new <tipo−clase>[<número−elementos>]
donde ahora <número−elementos> indica el número de elementos que contendrá el array. Este valor
no puede alterarse a lo largo de la vida del array. La variable de instancia length proporciona
justamente este número. Por ejemplo,
int [ ] arInt = new int [ 4 ] ;
Punto [ ] arPto = new Punto [ 3 ] ;
Punto [ ] [ ] aarPto = new Punto [ 3 ] [ 5 ] ;
construyen, respectivamente, un array de 4 enteros referenciado por arInt , un array para 3 puntos
referenciado por arPto y por último un array de arrays de 3 x 5 referenciado por aarPto . Los valores
del array son implícitamente inicializados a su valor por defecto. Así, en el caso de enteros, serán
todos los valores 0 y en el caso de referencias a objetos serán todos los valores null.
Si aplica la variable length a la matriz arInt
arInt.length;
el resultado sería 4, es decir el tamaño de la matriz. Igualmente al realizar la instrucción
arPto.length obtendría 3 como resultado2.
El resultado de aplicar la variable length a una matriz multidimensional es distinto. Por
ejemplo, si realizamos
aarPto.length
el resultado será 2, es decir, la dimensión de la matriz. Para conocer el tamaño de la primera matriz de
aarPto tendría que escribir
aarPto[0].length
obteniendo, es este caso, 3 como resultado
3.3 Iniciar una matriz y acceder a sus elementos
Un array puede inicializarse también de forma literal. Esto es, con la sintaxis
<tipo−clase> [ ] <nombre−array> = <literal −array>
donde <literal−array> representa una constante de tipo array, descrito mediante una secuencia de
elementos (contenido del array) separados por comas y entre llaves (‘{ ’ . . . ‘} ’). Consideremos el
siguiente ejemplo,
int [ ] arInt = {4 ,2 ,3 ,7};
Punto [ ] [ ] aarPto = {{new Punto (1 ,2) , new Punto (2 ,5) } ,{new Punto (1 ,4) }};
Tras estas declaraciones la variable arInt referencia a un array de cuatro enteros, mientras que aarPto
referencia a un array de dos arrays, el primero de ellos con dos puntos y el segundo con uno.
En este caso podemos observar que la primera fila de este último array contiene dos columnas
2 Esto no quiere decir que la matriz tenga 3 puntos, sólo que es de tamaño 3.
7
Tema 5: Instrucciones y matrices D.I.G.
mientras que la segunda contiene sólo una.
Una vez creado un array, la forma de acceder a los elementos del mismo es mediante
expresiones como:
<nombre−array>[<posición >]
siendo el primer elemento del array el que ocupa la posición 0 . Considerando las inicializaciones
anteriores, arInt [1] es el entero 2 y aarPto[0][1] es el punto de coordenadas (2, 5) . En este último
caso, el mismo elemento también se puede expresar como aarPto[0,1] . Del mismo modo, para
cambiar el elemento almacenado en una posición del array se puede utilizar una asignación del tipo
arInt [3] = −1 , la cual reemplaza el entero almacenado en la posición 3 por −1 .
La forma habitual de recorrer arrays es mediante estructuras de control como los bucles for .
Así, por ejemplo, podríamos almacenar en un array los 10 primeros elementos de la serie de Fibonacci
del modo siguiente:
int [ ] fibonacci = new int [10] ;
fibonacci[0] = 1;
fibonacci[1] = 1;
for ( int i =2; i < 10; i ++) {
fibonacci [i] = fibonacci[ i −1] + f ibonacci[ i −2];
}
Desde la versión 1.5, Java permite también una forma alternativa de recorrer arrays y, en
general, cualquier estructura que contenga elementos sobre los que se pueda realizar algún tipo de
iteración. Una vez creado el array fibonacci anterior, si queremos comprobar la propiedad que afirma
2 2 2
f 0 f 1... f n= f n f n1 con la sucesión de Fibonacci, podríamos obtener la suma de los
cuadrados del modo siguiente:
cuadrados = 0;
for ( int f : fibonacci ) {
cuadrados += f *f ;
}
El efecto de este bucle (denominado for each ) es recorrer cada elemento del array fibonacci y
almacenarlo en la variable f , de hecho es habitual interpretarlo como “para cada elemento f del array
fibonacci hacer . . . ”.
3.4 Métodos de una matriz
Los arrays son un tipo primitivo de Java, pero existen métodos específicos para manipularlos
(ordenar, rellenar con un elemento, . . . ) en la clase Arrays del paquete java.util .
Método arraycopy
Permite realizar eficientemente copias de un array a otro. Se encuentra en la clase System y
tiene la siguiente cabecera:
8
Tema 5: Instrucciones y matrices D.I.G.
public static arraycopy ( Object arrayOrigen , int índiceOrigen ,
Object arrayDestino , int índiceDestino ,
int númCopiados )
Es un método estático que copia el número de elementos indicado por númCopiados del arrayOrigen,
a partir de la posición ndiceOrigení , al arrayDestino , comenzando en la posición ndiceDestinoí .
Método equals
Permite ver si dos referencias se refieren al mismo objeto. Su cabecera es la siguiente:
boolean equals (Object obj)
Ejemplo:
m1.equals(m2)
Método clone
Permite duplicar un objeto. Su cabecera es:
Object clone()
Ejemplo:
int[] m1 ={10, 20, 30, 40, 50};
int[] m2 =(int[])m1.clone(); // m2 es una copia de m1
Algunos métodos de la clase Arrays se verán en el próximo tema.