Lenguajes de Programación

Programación bit a bit: Control de Flujo

En este nuevo artículo de la serie sobre aspectos básicos de la programación vamos a explicar qué son y cómo se utilizan las estructuras de control de flujo.

Publicado el 15 de Noviembre de 2013
Compartir

A la hora de diseñar un programa nos interesa que éste se comporte de formas distinta en función de los datos que maneja. Para hacer eso se utilizan estructuras de control de flujo , que es lo que aprenderemos en el capítulo de hoy. El código que usaremos hoy será el siguiente:

package net.openwebinars;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Random;

public class ControlFlujo {

  public static void main(String[] args) throws NumberFormatException, IOException {

    int cantidad = 0;
    int[][] tabla;
    boolean seguir = true;
    Random aleatorio = new Random();
    final int VALOR_MAXIMO = 20;
    final int VALOR_MINIMO = 5;
    BufferedReader bLectura = new BufferedReader(new InputStreamReader(System.in));
    System.out.println("[PC]: ¡Hola programador!");
    try {
      System.out.println("[Programador]: " + bLectura.readLine());
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    System.out.print("- Introduzca un número: ");
    try {
      cantidad = Integer.parseInt(bLectura.readLine());
    } catch (NumberFormatException e) {
      System.err.println("El valor dado no es un número. Mostrando el error: ");
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    if (cantidad > 0) {

      // Bucle simple

      for (int i = 0; i < cantidad; i++)
        System.out.println("Imprimo el valor de i: " + i);

      tabla = new int[cantidad][cantidad];

      // Rellenamos la tabla conociendo sus dimensiones
      // usando bucles for anidados

      for (int i = 0; i < cantidad; i++)
        for (int j = 0; j < cantidad; j++)
          tabla[i][j] = aleatorio.nextInt((VALOR_MAXIMO - VALOR_MINIMO) + 1) + VALOR_MINIMO;

      // Recorremos la tabla sin conocer sus dimensiones
      // y mostramos su contenido por pantalla

      for (int[] i: tabla) {
        for (int j: i) {
          System.out.print(j + " ");
        }
        System.out.println();
      }      

    } else if (cantidad == 0){
      System.out.println("El valor dado fue un 0");
    }

    System.out.println("- Bucle while 1");
    int valor = 0;
    while (valor != 0) {
      System.out.println("Valor: " + valor);
      valor++;
      if (valor == 5)
        valor = 0;
    }
    System.out.println("- Bucle while 2");
    valor = 0;
    do {
      System.out.println("Valor: " + valor);
      valor++;
      if (valor == 5)
        valor = 0;
    } while (valor != 0);

    do {    
      System.out.print("Dame un número que esté dentro del rango [0, 10]: ");
      valor = Integer.parseInt(bLectura.readLine());
      System.out.println();      
      if ((valor  10)) {
        System.err.println("Tiene que ser un número que esté dentro del rango dicho");
        continue;
      }
      switch (valor) {
        case 0:
        case 2:
        case 4:
        case 6:
        case 8:
        case 10:
          seguir = false;
          System.out.println("El número dado era par");
          break;
        case 1:
        case 3:
        case 5:
        case 7:
        case 9:
          seguir = false;
          System.out.println("El número dado era impar");
          break;
      }    
    } while (seguir);

  }

}

Las estructuras de control de flujo podemos definirlas como bloques de códigos en los cuales se evalua una condición de parada (la cual puede ser verdadera o falsa) y en función de su resultado se realizarán unas acciones u otras redirigiendo así el flujo de ejecución de nuestro programa (de ahí su nombre). Por poner un ejemplo, a lo mejor queremos recorrer un vector e ir mostrando sus valores. Si lo hicieramos con los conocimientos que tenemos hasta ahora tendríamos que hacer algo así:

int[] vector = {1, 3, 2};
int indice = 0;
System.out.println(vector[indice]);
indice++;
System.out.println(vector[indice]);
indice++;
System.out.println(vector[indice]);

Eso está bien para vectores pequeños, pero ¿y para vectores grandes? Sería bastante tedioso hacer una tarea que podría ser repetitiva de manera manual. Gracias a las estructuras que veremos ahora.

Bloques if-else

El esquema de esta estructura es la siguiente:

Si (esVerdadero)
  hacer A
sino 
  hacer B

Esta estructura llamada if-else es la más simple de las que veremos hoy. Simplemente evalua una expresión y si es verdadera realiza una acción y si no realiza otra. En Java esta estructura es:

if (expresion) {
  codigo_A
} else {
  codigo_B
}

No es obligado que este tipo de estructuras tenga que acabar en un bloque else de forma que podremos realizar una "acción especial" (por llamarla de una manera) para una condición única. Si esa condición no se da, seguir con normalidad la ejecución del código. En el código que puse hoy de ejemplo podemos ver el siguiente bloque if-else:

if (cantidad > 0) {
      // Codigo A
    } else if (cantidad == 0) {
      System.out.println("El valor dado fue un 0");
    }

No, no me he equivocado. Es totalmente viable escribir otra estructura condicional seguida inmediatamente del else. Explicando paso a paso esta estructura tenemos que sólo se ejecutará el código A si el valor de la variable cantidad es estrictamente mayor que 0, de lo contrario iríamos al bloque else. De nuevo sólo se ejecutará el bloque else si el valor de cantidad es exactamente 0. A esta estructura del if junto al else se le conoce como estructura anidada . Diremos que una estructura es anidada cuando ésta estará dentro de otra estructura de control de flujo. Las estructuras anidadas se pueden escribir como en el fragmento de código de antes o así:

if (cantidad > 0) {
  // Codigo A
} else {
  if (cantidad == 0)
    System.out.println("El valor dado fue un 0");
}

Como podemos ver, el segundo bloque if está dentro del bloque else de la estructura if superior. Por ello se dice que el segundo if está anidado al bloque anterior. Nota: Cuando declaremos una estructura de control de flujo si el código a ejecutar es una sola sentencia no es necesario envolverla entre llaves {}. Si por el contrario el código es de más de una sentencia estamos obligados a usar las llaves, de lo contrario la condición del if sólo afectará a la primera sentencia. Cuando nuestro programa evalua la expresión que determinará si se ejecuta o no el código dentro del if, dicha evaluación no es más que realizar las operaciones que forman la expresión y extraer de ella un único valor: Verdadero o Falso . Por ejemplo:

if ((2 + 3 * 5 - 2 * (20 / 10)) > 0) {
  // Codigo A
}

Al programa le da igual que la secuencia de operaciones que hemos puesto en el if dé como resultado 13. A él lo único que le interesa es "¿El resultado de esa secuencia de operaciones es mayor que 0?" ¿Sí? Pues ejecutas el código A y ya está, ni almacena el resultado en alguna variable ni nada parecido. Lo que acaba de ocurrir es que el programa ha empleado la lógica para saber si ejecutar el código A o no. ¿Qué es eso de la lógica? La lógica es...

Introducción a la Lógica orientada a la programación

¡Bienvenidos a uno de mis aspectos favoritos de la programación: La Lógica ! La lógica no es más que aplicar los operadores lógicos del Álgebra de Boole a dos variables binarias, es decir, variables que sólo pueden tomar dos valores: Verdadero o Falso . ¿Recuerdan cuando en el artículo anterior de Variables y Operadores (si no lo has visto date un saltito a él que no tardarás ni 5 minutos en leerlo) vimos las variables booleanas? Bien entonces si las entendiste habrás llegado a una conclusión: evaluar una expresión es equivalente a evaluar la variable booleana resultante de dicha expresión. Volviendo al ejemplo de antes, cuando evaluamos la expresión "(2 + 3 * 5 - 2 * (20 / 10)) > 0", internamente Java indica que el resultado de la operación > o "mayor que" da una variable booleana con valor true . De hecho si hacemos lo siguiente:

System.out.println((2 + 3 * 5 - 2 * (20 / 10)) > 0);

se mostrará por pantalla "true". Volviendo a la lógica binaria, hemos visto varios operadores lógicos y relacionales los cuales ante dos valores de entrada devuelven siempre true o false. La entrada en los operadores relacionales suelen ser números (por ejemplo 3 != 0), mientras que la entrada en los operadores lógicos son dos variables booleanas. ¿Cómo saber qué resultado obtendremos entonces? Muy sencillo. Los operadores lógicos siempre se comportarán de la siguiente manera:

  • Operador AND (&&)
A B A && B
Verdadero Verdadero Verdadero
Verdadero Falso Falso
Falso Verdadero Falso
Falso Falso Falso
  • Operador OR (||)
A B A || B
Verdadero Verdadero Verdadero
Verdadero Falso Verdadero
Falso Verdadero Verdadero
Falso Falso Falso
  • Operador NOT (!)
A !A
Verdadero Falso
Falso Verdadero

Nota: El operador NOT es un caso particular en el que sólo hay una entrada y siempre devuelve el contrario del valor de entrada.

Operador Condicional Ternario (expresion) A ? B :

Existe un operador especial que se suele utilizar cuando no es necesario una estructura if-else muy compleja. Se le conoce como operador condicional ternario . Este operador tiene tres entradas:

  • Expresión a evaluar
  • Expresión a ejecutar si la expresión a evaluar es verdadera
  • Expresión a ejecutar si la expresión a evaluar es falsa

Para entenderlo mejor pongo un ejemplo:

int resultado = ((3 + 2) == 5) ? -1 : 5 ;

El valor almacenado en la variable resultado es -1 . Lo que hace este ejemplo es primero evaluamos si (3 + 2) es igual a 5. Si es verdadero devolvemos el valor -1, de lo contrario devolvemos el valor 5. Simple, ¿verdad? Se suele utilizar mucho para aquellas operaciones donde necesitamos evaluar una condición, que sea rápido y cuando las expresiones resultantes no son complejas.

Bucles

Ya hemos visto la estructura más básica de control de flujo. Supongamos que tenemos un código que queremos que se repita un número finito de veces. Para hacer eso tenemos las estructuras conocidas como bucles . Los bucles generalmente siguen el siguiente esquema:

Mientras (expresión) hacer {
  // Código A
}

Dicho de otra forma, mientras la expresión sea verdadera, ejecutar el código A. Si la condición de la expresión siempre es verdadera da lugar lo que se conoce como bucle infinito , uno de los mayores incordios para un programador. Un bucle infinito produce que nuestro programa nunca acabe (a no ser que lo forcemos a ello) e incluso que nos sature la memoria. Así que importante: cuando declaremos un bucle, procurar que en algún momento se salga de él es decir, que la expresión se vuelva falsa. Existen dos tipos de estructuras de bucles principalmente: bucles for y bucles while .

Bucles for

Los bucles for tienen el siguiente esquema:

for (int variable; condicion; incremento/decremento) {
  // Codigo A
}
  • Variable iteradora. Normalmente es de tipo int, pero también puede ser de otro tipo numérico.
  • Condición de parada del bucle. Cuando esta condición sea falsa, el bucle parará. En esta condición suele evaluarse el valor actual de la variable iteradora
  • Incremento o Decremento. A cada iteración del bucle, se ejecuta esta expresión para incrementar o decrementar el valor de la variable iteradora

Viendo el código de ejemplo del artículo de hoy, un bucle for sería el siguiente:

for (int i = 0; i < cantidad; i++)
  System.out.println("Imprimo el valor de i: " + i);

Donde la salida de este bucle por pantalla sería:

Imprimo el valor de i: 0
Imprimo el valor de i: 1
Imprimo el valor de i: 2
Imprimo el valor de i: 3
Imprimo el valor de i: 4
... // Depende del valor de la variable cantidad

Los bucles for se suelen utilizar para recorrer vectores o arrays, en especial los arrays multidimensionales . Un ejemplo de cómo recorrer un vector es el siguiente:

int[] vector = {3, 2, 8, 9, 11, 23, 5};
final int TAM_VECTOR = 7;
for (int i = 0; i < TAM_VECTOR; i++)
  System.out.println(vector[i]);

Existe un tipo de bucle for propio de Java el cual permite recorrer vectores o ArrayLists iterando directamente sobre los miembros sin tener que preocuparnos del tamaño del mismo:

int[] vector = {3, 2, 8, 9, 11, 23, 5};
final int TAM_VECTOR = 7;
for (int i : vector)
  System.out.println(i);

Este fragmento de código es exactamente equivalente al anterior, la única diferencia es que no tenemos una condición de parada implícita; el bucle parará cuando no queden más elementos en el vector. Además tampoco necesitamos incrementar la variable iteradora para ir recorriendo el vector, ya se ocupa de ello Java. Es muy recomendable usar este tipo de bucles si no necesitamos manejar el índice de la posición actual de la variable iteradora .

Bucles while

Los bucles while son similares a los bucles for. Se diferencian principalmente en que no hay una variable iteradora ni un incremento de ésta, aunque siguen teniendo una condición de parada. Su estructura es la siguiente:

while (expresion) {
  // Código A
}

Entonces si es similar al bucle for, ¿cuándo usamos un bucle for y cuándo un bucle while? En general, usamos el bucle for cuando antes de entrar en él sabemos el número exacto de iteraciones que tendrá que realizar el bucle para que funcione como debe. Sin embargo, usamos el bucle while cuando no sabemos cuántas iteraciones necesitará el bucle para acabar. Supongamos por ejemplo queremos buscar un número dentro de un vector. Si usamos un bucle for, no sabemos en qué posición estará el número por lo tanto tendremos que recorrer el vector entero. De esta forma es muy probable que encontremos el número antes de llegar al final del vector, lo que se resume como un gasto de tiempo innecesario. Si por el contrario esa misma operación la hacemos con un bucle while, desde que encuentre el número podemos salir del vector sin estar obligados a recorrer el resto de posiciones. Existe un segundo tipo de bucle while llamados bucles do-while cuya estructura es:

do {
  // Código A
} while (expresion);

Se diferencia del bucle while normal en que siempre se ejecutará el código A como mínimo una vez . Esto es debido a que este bucle ejecuta primero el código A y luego evalua la expresión, mientras que el otro bucle while primero evalua la expresión y luego ejecuta el código A. Dicho esto, si en el primer bucle while que expliqué la condición de parada se cumple antes incluso de ejecutar por primera vez el código interno, se ignorará por completo el bucle. Un ejemplo del bucle do-while con el código de hoy sería:

System.out.println("- Bucle while 2");
    valor = 0;
    do {
      System.out.println("Valor: " + valor);
      valor++;
      if (valor == 5)
        valor = 0;
    } while (valor != 0);

Arrays multidimensionales

Antes nombré los arrays multidimensionales, pero nunca lo he explicado. Hasta ahora los arrays que hemos visto eran de una sola dimensión es decir, un vector. A medida que vamos aumentado las dimensiones, podemos crear estructuras de memoria más complejas. A continuación muestro una imagen de cómo se construyen dichos vectores de una forma más gráfica:

imagen_vectores

  • Una dimensión se corresponde a un vector o array
  • Dos dimensiones se corresponden a una tabla. Esta tabla se construye añadiendo en cada posición un vector de una dimensión.
  • Tres dimensiones se corresponden a una tabla donde cada posición contiene un vector de una dimensión

Y así sucesivamente. La forma de declarar un vector muldidimensional es la siguiente:

TipoDato[][] nombreVariable;

donde ponemos tantos corchetes [] como dimensiones queremos que tenga. Si queremos inicializarlo la forma correcta sería:

int[][] vector = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
// o bien
int [][] vector2 = new int[5][5];

Usando bucles anidados, en este caso bucles for, podemos acceder/insertar elementos en la tabla:

final int LONGITUD = 5;
final int MAXIMO = 10;
final int MINIMO = 1;
Random aleatorio = new Random();
for (int i = 0; i < LONGITUD; i++)
  for (int j = 0; j < LONGITUD; j++)
    vector[i][j] = aleatorio.nextInt(MAXIMO - MINIMO + 1) + MINIMO;
/* o bien:
for (int[] i: vector)
  for (int j: i)
    j = aleatorio.nextInt(MAXIMO - MINIMO + 1) + MINIMO;
*/

He aprovechado este ejemplo para introducir un nuevo elemento: generar números aleatorios dentro de un rango . Para hacerlo primero tenemos que crear un objeto de la clase Random y usar su método .nextInt. La fórmula que he usado ahí sirve para obtener un número aleatorio entre MAXIMO (10) y el MINIMO (1).

Bloque switch

Hay ocasiones donde queremos que el programa se comporte de maneras distintas en función de los muchos valores que puede tomar una variable en concreto. Imagínate que esa variable puede llegar a tomar 10 valores distintos. Si para cada valor definimos un bloque if-else nuestro código resultaría bastante molesto a la vista, además de que tendríamos como 10 expresiones de la forma "variable == número". Para ello podemos usar las estructuras switch . Las estructuras switch nos permiten ante distintos valores de una variable realizar distintas operaciones. La estructura general del switch es:

sea (variable) {
  caso valor1
     // Código 1
  fincaso
  caso valor2
     // Código 2
  fincaso
  caso valor3
     // Código 3
  fincaso
  pordefecto
     // Código defecto
}

Si nos fijamos en el código de ejemplo de hoy tenemos el siguiente switch:

switch (valor) {
        case 0:
        case 2:
        case 4:
        case 6:
        case 8:
        case 10:
          seguir = false;
          System.out.println("El número dado era par");
          break;
        case 1:
        case 3:
        case 5:
        case 7:
        case 9:
          seguir = false;
          System.out.println("El número dado era impar");
          break;
      }

En este caso estamos diciendo que cuando la variable valor tenga los valores 0, 2, 4, 6, 8 o 10 imprimimos por pantalla "El número dado era par". Si por el contrario toma valores 1, 3, 5, 7, 9 imprimimos por pantalla "El número dado era impar". También habrá ocasiones donde queremos que para el resto de valores que no controlamos siempre se ejecute el mismo código por defecto . Para ello antes de cerrar el bloque switch usamos la palabra reservada default: seguida del código a ejecutar:

switch (valor) {
        case 0:
        case 2:
        case 4:
        case 6:
        case 8:
        case 10:
          seguir = false;
          System.out.println("El número dado era par");
          break;
        case 1:
        case 3:
        case 5:
        case 7:
        case 9:
          seguir = false;
          System.out.println("El número dado era impar");
          break;
        default:
          seguir = false;
          System.out.println("El número dado es mayor que 10 o menor que 0");
      }

Si definimos varios bloques case, se ejecutará el código que esté desde el case en el que se entró hasta que se encuentre un break , default: (si lo hay) o una llave que indique el fin de la estructura switch.

Break y Continue

Otra forma de modificar el flujo de ejecución son las palabras reservadas break y continue . Tal y como indican su nombre, interactúan con la estructura de control en la cual se encuentre modificando la iteración actual. Más concretamente, break interrumpe la ejecución actual saliéndose de la estructura de control de flujo en donde esté. Así por ejemplo en el caso del switch se usa para después de realizar el código de un case evitar que ejecute el código de todos los demás case. Si por ejemplo se utiliza dentro de un bucle, aunque la condición de parada no se cumpla se termina el bucle. En el caso de continue se utiliza en los bucles para saltar a la siguiente iteración sin ejecutar el resto de código. Por ejemplo:

for (int i = 0; i < 10; i++) {
  if (i % 2 == 0)
    continue;
  System.out.println(i);
}

La salida del programa será:

1
3
5
7
9

Nota: Técnicamente se puede utilizar break en bucles for para interrumpirlos antes de que se cumpla la condición de parada. No obstante, no es una buena práctica ya que para esos casos es mejor utilizar un bucle while.

Bloques try-catch

En algunas ocasiones nuestro código es probable que genere errores o excepciones . Si no las controlamos, nuestro programa terminará de manera repentina o producirá situaciones bastante caóticas. Para manejar esas excepciones y evitar problemas en nuestro programa contamos con la estructura de control try-catch . Estas estructuras se encargan de "vigilar" un bloque de código que puede generar una excepción. Ese código irá dentro del bloque try . Si se produce un error, se disparará una excepción la cual será capturada por el bloque catch . Es en este bloque donde podemos manejar la excepción. Siguiendo nuestro código podemos ver el siguiente bloque try-catch:

System.out.print("- Introduzca un número: ");
    try {
      cantidad = Integer.parseInt(bLectura.readLine());
    } catch (NumberFormatException e) {
      System.err.println("El valor dado no es un número. Mostrando el error: ");
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

En este caso hemos leído un número introducido por el usuario desde teclado (tranquilo, a continuación explico cómo se hace jeje) y queremos comprobar que efectivamente lo introducido es un número. Para ello, usamos el método parseInt de la clase Wrapper Integer el cual dado un String lo transforma a una variable de tipo int. Si la cadena no era un número, se dispara una excepción de tipo NumberFormatException . Cuando eso ocurra, se mostrará el mensaje "El valor dado no es un número. Mostrando el error: " por pantalla seguido del resultado del método printStackTrace(); . Ese método se ocupa de mostrar los errores producidos por culpa de dicha excepción y en qué línea del código se produjo. Para que vean como funciona, yo por ejemplo en lugar de poner un número he puesto "hola" y se ha mostrado lo siguiente:

El valor dado no es un número. Mostrando el error: 
java.lang.NumberFormatException: For input string: "hola"
	at java.lang.NumberFormatException.forInputString(Unknown Source)
	at java.lang.Integer.parseInt(Unknown Source)
	at java.lang.Integer.parseInt(Unknown Source)
	at net.openwebinars.ControlFlujo.main(ControlFlujo.java:29)

Como vemos el error se ha producido en la línea:

cantidad = Integer.parseInt(bLectura.readLine());

Si en lugar de gestionar nosotros mismos las excepciones queremos que se ocupe de ello la propia máquina de Java, tenemos que declarar en el main los errores que se pueden producir:

public static void main(String[] args) throws NumberFormatException, IOException {

Estamos indicando que se pueden producir excepciones de tipo NumberFormatException y IOException usando la palabra clave throws . Personalmente recomiendo que seamos nosotros mismos los que gestionemos las excepciones que se puedan producir en lugar de dejar que sea Java quien se ocupe de ellas para que el usuario no note que se ha producido un problema. Nota: A partir de ahora cada vez que explique algo que pueda generar una excepción intentaré dar el nombre exacto del tipo de excepción que se puede generar.

Entrada de datos por teclado

Antes de acabar el artículo de hoy, me gustaría adelantar un concepto para que puedan ir practicando con programas más dinámicos. En primer lugar me gustaría explicar cómo pedir valores al usuario y obtenerlos . Para hacer eso necesitamos definir un objeto de la clase BufferedReader de la siguiente forma:

BufferedReader bLectura = new BufferedReader(new InputStreamReader(System.in));

De esta forma estamos declarando una variable de tipo BufferedReader la cual cuando usemos el método readLine() se quedará esperando a que el usuario introduzca una cadena por teclado. Llamar a dicho método produce una excepción de tipo IOException (Input/Output Exception). Recordar que readLine() siempre devuelve una cadena (String), de modo que si queremos pedir un número y almacenarlo en una variable de tipo int necesitamos parsear la cadena:

System.out.print("- Introduzca un número: ");
    try {
      cantidad = Integer.parseInt(bLectura.readLine());
    } catch (NumberFormatException e) {
      System.err.println("El valor dado no es un número. Mostrando el error: ");
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

Haciendo esto tendremos en la variable cantidad el número dado por teclado. También es posible pasarle parámetros a nuestro programa cuando vamos a ejecutarlo para que trabaje sobre ellos. Para ello cuando ejecutemos nuestro programa tenemos que ejecutarlo como explicamos en el capítulo de "Hello World!" añadiéndole los parámetros separados por espacios . Si ejecutan los programas como un jar por ejemplo, la forma de hacerlo es:

java -jar Fichero.jar parametro1 parametro2 parametro3

Ahora bien, ¿cómo obtenemos esos parámetros dentro del programa? Muy fácil. Si se acuerdan cuando declaramos el main de nuestros programas tiene la siguiente forma:

public static void main(String[] args) throws NumberFormatException, IOException {

A estas alturas seguramente te habrás dado cuenta de que lo que está dentro de los paréntesis (String[] args) es un vector de String donde se almacenan los parámetros de entrada que tenga nuestro programa ordenados según se los pasásemos . Esto es si ejecutamos el programa así:

java -jar Fichero.jar perro 12 cuarenta
  • args[0] almacena "perro"
  • args[1] almacena "12"
  • args[2] almacena "cuarenta"

Acuerdate de parsear los valores para convertirlos al tipo de dato que te interese. Si intentas acceder por ejemplo a args[0] sin pasarle argumentos al programa se producirá una excepción de tipo ArrayIndexOutOfBoundsException al intentar acceder a posiciones de un array sin tamaño. Para evitar este error el siguiente fragmento de código te puede ser útil:

if (args.length != 0) {
  // Código
}

Con .length obtenemos el tamaño de cualquier vector (en este caso de args). De esta forma si tiene un tamaño distinto de 0 sabemos que han pasado argumentos al programa. Y hasta aquí llegamos con el capítulo de hoy. No se olviden de que tienen a su disposición el curso de la asignatura en la sección de Cursos en OpenWebinars donde pueden hacer ejercicios y/o cuestionarios (en especial este tema donde he puesto ejercicios resueltos bastante útiles de cara a futuros artículos) a modo de autoaprendizaje. No duden en preguntar todo aquello que no entiendan y espero verles en el próximo artículo donde veremos cómo añadirle más funcionalidad a nuestros programas. ¡Un saludo!

Listado de capítulos

En esta sección se listan todos los capítulos de este pequeño curso:

  1. Introducción
  2. Hello World!
  3. Variables y Operadores

Compartir este post

También te puede interesar...

Tecnología

Programación bit a bit: Funciones y Procedimientos

22 Noviembre 2013 César Ravelo Martínez
Tecnología

Programación bit a bit: Recursividad y Divide y Vencerás

28 Noviembre 2013 César Ravelo Martínez
Artículos
Ver todos