Programación bit a bit: Funciones y Procedimientos
Hasta ahora hemos realizado programas relativamente sencillos los cuales no realizaban subprocedimientos o subrutinas las cuales podían ser repetitivas.
Seguimos con los artículos sobre las bases de la programación, y en este caso nos enfocamos en las Variables y Operadores.
Tabla de contenidos
¿Qué sería de los programas sin datos ? ¿Y qué sería de los datos sin herramientas para manejarlos? Eso es lo que vamos a ver en el artículo de hoy. El código que usaremos hoy será el siguiente:
package net.openwebinars;
public class VariablesOperadores {
public static void main(String[] args) {
// Variables
char a = 'a';
char b = 'b';
double x = 3.2d;
float y = 4.8f;
int auxiliar = 30;
long numeroCuentas = 10000000000L;
boolean verdadero = true;
String perro = "perro";
String gato = "gato";
// Constantes
final double NUMERO_PI = Math.PI; // 3.14
final int CERO = 0;
// Arrays o Vectores
String[] paises = {"España", "Italia", "Portugal"};
String[] animales = new String[] {"perro", "vaca", "gato", "mono"};
String[] objetos = new String[3];
// Operadores
objetos[0] = "pelota";
objetos[1] = "caja";
objetos[2] = "zapato";
System.out.println(x + y);
System.out.println(x - y);
System.out.println(x * y);
System.out.println(x / y);
System.out.println(x % y);
System.out.println();
System.out.println(numeroCuentas += 1);
System.out.println(numeroCuentas++);
System.out.println(++numeroCuentas);
System.out.println();
System.out.println(x > y);
System.out.println(x < y);
System.out.println(x == y);
System.out.println(x != y);
System.out.println();
System.out.println(String.valueOf(b) + String.valueOf(a));
System.out.println("El " + perro + " persigue al " + gato);
System.out.println("El " + animales[0] + " persigue al " + animales[2]);
System.out.println("perro".equals(animales[0]));
System.out.println(paises[1].replace('a', '9'));
System.out.println(paises[1].substring(CERO, 5));
System.out.println(paises[1]);
}
}
Nota: los caracteres ">" y "<" no se ven correctamente a la hora de ponerlos en el artículo. En su lugar para el símbolo ">" usamos gt; (greater than) y en el caso de "<" usamos lt; (less than) con "&" delante. Perdón por las molestias.
Las variables son secciones reservadas en memoria para almacenar datos los cuales pueden cambiar durante la ejecución del programa. En Java cuando creamos una variable tenemos que seguir la siguiente sintaxis:
Tipo nombreVariable [= valorInicial];
donde:
He puesto entre corchetes ([]) un elemento opcional a la hora de crear una variable. Las variables al crearlas podemos darle un valor inicial. Para ello hay que usar primero el operador de asignación = seguido del valor inicial. Si vamos al código de ejemplo vemos que
char a = 'a'; char b = 'b'; double x = 3.2d; float y = 4.8f; int auxiliar = 30; long numeroCuentas = 10000000000L;
Hemos creado de esta forma 6 variables con valores iniciales. A esto se le conoce como inicialización de variables . A continuación veremos los tipos básicos de variables en Java.
Las variables de tipo entero o int son aquellas que almacenan un número (ya sea positivo o negativo) no decimal . Debido a que cuando creamos una variable reservamos memoria para ella, cada tipo de variable reservará más o menos memoria para representar el dato que almacenarán. Dicho esto, en el caso de variables de tipo int sólo podemos almacenar números que estén dentro del rango -2^31 y 2^31 - 1 . Si intentamos almacenar un número que esté fuera de ese rango nos dará un error de compilación o de ejecución. Por ejemplo, no podríamos almacenar el número 10000000000 en una variable de tipo int. Un ejemplo sería:
int auxiliar = 30;
Su valor por defecto si no lo inicializamos es 0.
Las variables de tipo entero grandes o long son aquellas que almacenan un número (ya sea positivo o negativo) no decimal . Las variables de tipo long almacenan números que están dentro del rango -2^63 y 2^63 - 1 . Si intentamos almacenar un número que esté fuera de ese rango nos dará un error de compilación o de ejecución. Para representar que un número es de tipo long, añadimos una L al final del número:
long numeroCuentas = 10000000000L;
Nota: No es recomendable crear una variable de tipo long para almacenar números pequeños debido a que estamos reservando más memoria de la que realmente necesitamos y eso a la larga puede producir que nuestro programa sea mucho más lento de lo que es realmente. Su valor por defecto si no lo inicializamos es 0L.
Si en lugar de números enteros queremos almacenar números decimales, tenemos dos tipos:
Si por algún motivo necesitamos especificar si un número es flotante o doble basta con añadir una letra f o d al final del número tal y como vemos en el siguiente código:
double x = 3.2d; float y = 4.8f;
Añadir que en caso de querer representar números grandes es mejor usar double en lugar de float ya que a la hora de operar con ellos puede producirse errores de aproximación y llevarnos a confusiones innecesarias. Su valor por defecto si no lo inicializamos es 0.0d para double y 0.0f para float. Existen dos tipos básicos más para representar números: short y byte . Estos tipos sólo almacenan números de tipo entero similar a como sucede con las variables de tipo int. No obstante, los rangos de valores que pueden almacenar son mucho más pequeños (byte: -128, 127 short: -32768, 32767) y sólo se suelen usar cuando la reserva de memoria tiene que estar muy controlada para el perfecto funcionamiento de un programa. En general basta con trabajar con variables de tipo int en lugar de estos dos tipos.
Más adelante veremos herramientas para controlar el flujo de ejecución del programa las cuales se basan en el uso de condiciones ante las cuales el programa se ejecutará de una forma u de otra. Normalmente, esas condiciones serán de la forma:
Si esVerdadero Hacer A Sino Hacer B
Evaluar ese "esVerdadero" no es más que evaluar una sentencia la cual devolverá verdadero ( true ) o falso ( false ) en función de la condición. Ese valor true-false se corresponde con variables booleanas o boolean . Las variables booleanas son aquellas que sólo pueden guardar dos valores: true y false. Se declaran igual que otra variable:
boolean verdadero = true;
Su valor por defecto si no lo inicializamos es false.
Ya hemos hablado de los números, pero ¿qué sucede con las letras o símbolos? Podríamos usar variables de tipo int para almacenarlas, pero al hacer eso en lugar de guardar el símbolo como tal, se almacenaría su correspondiente valor en formato decimal en ASCII y tendríamos que manualmente interpretar dicho número para pasarlo a su correspondiente símbolo si quisieramos por ejemplo imprimirlo por consola. Para evitar esto, tenemos las variables de tipo char :
char a = 'a'; char b = 'b';
En este caso hemos creado dos variables de tipo char; una para el símbolo "a" y otra para el símbolo "b". Notar que para referirnos a un símbolo como tal, tenemos que rodearlo con comillas simples '' . Su valor por defecto si no lo inicializamos es '\u0000'.
Hemos solucionado el problema de almacenar en memoria símbolos individuales. Supongamos que queremos trabajar con secuencias de símbolos o cadenas de texto . Con lo visto hasta ahora tendríamos que crear tantas variables de tipo char como letras tenga la cadena. Un ejemplo rápido, si quisieramos representar el Quijote con variables char tendríamos un total aproximadamente de 2059005 letras en él contando las letras repetidas. Resulta inviable crear tantas variables de tipo char, ¿verdad? Sin ir tan lejos, para la palabra "perro" tendríamos que crear 5 variables. Para solucionar esto, Java nos facilita el trabajo al definir una clase llamada String la cual representa la secuencia o el vector de símbolos que componen una palabra, una frase, un párrafo, etc. Siguiendo el código del ejemplo,
String perro = "perro"; String gato = "gato";
perro y gato son variables de tipo String las cuales almacenan las cadenas "perro" y "gato" respectivamente. El trabajar así con los símbolos facilita mucho el manejo de cadenas. Su valor por defecto si no lo inicializamos es null . El valor null es el usado en Java para indicar que un Objeto no está inicializado y por tanto no se puede usar.
Supongamos que tenemos un tipo de dato el cual nunca y por ningún motivo cambiará su valor. Por ejemplo el número PI (3.14159265358979323846…). Para indicar que una variable tomará siempre el mismo valor y no se podrá modificar es decir, es constante usamos la palabra reservada final escribiéndola antes del tipo de la variable:
final double NUMERO_PI = Math.PI; // 3.14 final int CERO = 0;
Si intentamos modificar el valor de una constante nos dará error de compilación. Nota: Por cuestiones de buena práctica, se suelen escribir las variables en minúscula y las constantes en mayúsculas. Si el nombre de la variable es compuesto es decir, tiene más de una palabra, la primera letra de las siguientes palabras se escribe en mayúsculas. En el caso de las constantes, se escribe un guión bajo (_) entre palabra y palabra. Por ejemplo NUMERO_PI para la constante y numeroCuentas para la variable.
Los arrays o vectores son listas donde cada elemento es una variable de un tipo específico con su valor correspondiente. Los arrays no pueden almacenar tipos de variables distintos (realmente eso no es cierto, pero con lo explicado hasta la fecha hay que asumir que sí de modo que lo correcto sería decir "no deberían almacenar tipos de variables distintos"). Existen tres maneras a lo sumo de definir un array:
String[] paises = {"España", "Italia", "Portugal"}; String[] animales = new String[] {"perro", "vaca", "gato", "mono"}; String[] objetos = new String[3];
En la primera estamos creando un array temporal con el nombre de tres países y luego lo almacenamos en la variable paises sin indicar qué tipo de dato va a almacenar; el propio Java se ocupa de reconocerlo. El segundo caso es similar al primero con la diferencia de que especificamos el tipo de valor que va a almacenar nuestro array. El último caso es la forma general (y común en muchos lenguajes) de declarar el array. En él indicamos que será un array de 3 elementos máximo de tipo String, sin inicializar los valores de cada posición o elemento de la lista. Si queremos asignar valores a cada posición del array tendremos que hacerlo de la siguiente forma:
objetos[0] = "pelota"; objetos[1] = "caja"; objetos[2] = "zapato";
Tal y como comenté al explicar la tercera forma de declarar un array, los vectores tienen un tamaño máximo el cual nosotros definimos. Por tanto, no podemos aumentar dicho tamaño; si deseamos un tamaño mayor tenemos que crear un nuevo array y posteriormente asignarle los valores almacenados en el anterior. Para acceder a los elementos almacenados en el vector la sintaxis es la siguiente:
nombreVector[índice];
donde índice será un número entero que esté dentro del rango 0 y tamañoVector - 1 . Hay que tener esto en cuenta ya que cuando queramos acceder a un elemento n-ésimo tendremos que usar el índice (n-1)-ésimo. Así por ejemplo:
System.out.println("El " + animales[0] + " persigue al " + animales[2]);
El mensaje que se muestra por consola es:
El perro persigue al gato
Algo más a tener en cuenta de los vectores en Java es que, a diferencia de otros lenguajes, los vectores no son cíclicos ; si intentamos acceder al siguiente elemento después del último se produce una excepción al usar un índice el cual está fuera de rango. Nota: Java implementa una clase llamada ArrayList la cual extiende los vectores para mejorar su manejo (igual que sucedía con String y las variables de tipo char). No obstante, yo me limitaré a los vectores ya que los ArrayLists no son un elemento de la programación básica. Si alguien quiere usarlos y quiere preguntarme algo de ellos no duraré en responder igualmente.
Similar a lo que sucede con los ArrayLists, los Wrappers son una clase propia de Java la cual extiende el uso de una variable básica del lenguaje. Simplemente añaden funcionalidades a los tipos básicos en Java. Los Wrappers existentes y el tipo correspondiente son:
Una utilidad muy común en ellos es la de dada una cadena String de un número (por ejemplo "10") transformarla en un número de tipo int y luego operar con ella:
System.out.println(Integer.parseInt("10") + 2);
El resultado de esa sentencia nos imprime por pantalla 12. Si por el contrario esa sentencia fuera esta:
System.out.println("10" + 2);
Java entendería que el número 2 también es una cadena y por tanto concatenaría ambas cadenas e imprimiría por pantalla 102. Un momento... ¿qué es concatenaría? Muy simple: un operador .
La información de por si es útil, pero no lo bastante. Necesitamos herramientas con las cuales poder manipularlas, poder hacer operaciones con ellas para obtener nueva información. Los operadores son eso, herramientas para trabajar con las variables. Hay varios tipos de operadores:
long numeroCuentas = 10000000000L; ... System.out.println(numeroCuentas += 1); System.out.println(numeroCuentas++); System.out.println(++numeroCuentas);En este caso los resultados que se muestran por pantalla son:
10000000001 10000000001 10000000003
System.out.println(String.valueOf(b) + String.valueOf(a));El resultado mostrado por pantalla sería:
baEl operador de concatenación es el único operador aritmético que se puede usar con cadenas mediante el símbolo + ; para restar (o mejor dicho, dividir) una cadena en dos no podemos usar el operador resta. Tampoco podemos usar el operador == para comparar dos cadenas y ver si son iguales. Algunos operadores de cadenas son: Iguales (.equals()), Sustitución (.replace()) usado para reemplazar el primer char por el segundo y Subcadena (.substring()) para obtener una subcadena desde el primer índice dado hasta el segundo. Un ejemplo de cómo se usan es:
System.out.println("perro".equals(animales[0])); System.out.println(paises[1].replace('a', '9')); System.out.println(paises[1].substring(CERO, 5));cuyo resultado por consola es:
true It9li9 ItaliSi se fijan al usar paises[1].replace('a', '9') estamos en primer lugar obteniendo el String almacenado en el array paises en la posición 1 ("Italia" en este caso) y luego llamamos a su método o función replace() la cual sustituye todos los char 'a' en la cadena "Italia" por el char 9. Marco lo de char porque insisto en que ese '9' no es un número tal y como expliqué antes sino un símbolo.
Supongamos que tenemos varios operadores en una misma sentencia. ¿Cuál se evaluará primero? ¿Se hace al azar? La respuesta es no. Todos los operadores tienen prioridades entre sí de forma que en caso de duda Java evaluará el que mayor prioridad tenga primero. Una lista ordenada de mayor a menor prioridad de los operadores es (los operadores que están en la misma línea tienen entre sí la misma prioridad): () [] . ++ -- ~ ! new * / % + - >> >>> < >= < <= == != & ^ | && || ?: = += -= *= ... Nota: Los operadores new y ?: son operadores que veremos más adelante. Por si tienes curiosidad, el primero es el operador usado para crear una nueva instancia de una clase y el segundo es un operador ternario condicional. Repito, lo veremos más adelante. 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 online en nuestra plataforma, donde pueden hacer ejercicios y/o cuestionarios 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 controlar el flujo de nuestros programas. ¡Un saludo!
En esta sección se listan todos los capítulos de este pequeño curso:
También te puede interesar
Hasta ahora hemos realizado programas relativamente sencillos los cuales no realizaban subprocedimientos o subrutinas las cuales podían ser repetitivas.
¡Por fin! Después de nombrarlo tantas veces, en el artículo de hoy veremos qué es un Objeto y una Clase.