Variables

Código 1 - hipotenusa sin variables
double hipotenusa(double a, double b) {
  return Math.sqrt((a * a) + (b * b));
}

El Código 1 muestra la función hipotenusa() del capítulo anterior. Es una manera de escribirla que es válida, pero suceden muchas cosas en el argumento de Math.sqrt(). Si desea que esta expresión sea más expresiva, podemos agregar variables:

Código 2 - hipotenusa con variables
double hipotenusa(double a, double b) {
  var cuadradoDeA = a * a;
  var cuadradoDeB = b * b;
  var sumaDeCuadrados = cuadradoDeA + cuadradoDeB;
  return Math.sqrt(sumaDeCuadrados);
}

Al crear una variable, le das un nombre a un valor. Esto generalmente ayuda a documentar tu código y puede ayudarte a reutilizar el valor sin volver a calcularlo. Pero así como las funciones no tienen nada que ver con la reutilización, las variables tampoco. Tanto las funciones como las variables deben usarse principalmente para mejorar la legibilidad de su código.

Para crear una variable utilizamos la palabra clave «var» y le damos un identificador. Luego usa el operador de asignación “=" y por último un valor. Puede ser un literal, otra variable o una llamada a una función. Así como los parámetros tienen tipos, las variables también tienen tipos, de hecho los parámetros son variables. El tipo de una variable local se toma del tipo de expresión despues del = . Por ejemplo: var cuadradoDeA = a * a, cuadradoDeA tendría el mismo tipo del resultado de la multiplicación. Y el tipo de la multiplicación sería del mismo tipo de las variables «a» y «b», que son double. Entonces cuadradoDeA es de tipo doble.

Código legado: código sin var

Código 3 - hipotenusa usando tipos de datos en lugar de var.
double hipotenusa(double a, double b) {
  double cuadradoDeA = a * a;
  double cuadradoDeB = b * b;
  double sumaDeCuadrados = cuadradoDeA + cuadradoDeB;
    return Math.sqrt(sumaDeCuadrados);
}

El Código 3 era la única manera de escribir código en versiones muy anteriores de Java. Al usar explícitamente el tipo de dato de la variable, el código no cambia realmente en su funcionamiento. ¿Por qué usamos «var»? Cuando hagamos código más complejo, con muchos tipos de datos, usar «var» ayuda a la legibilidad. Usualmente al leer código, cuando ves el valor asignado, el tipo de dato es obvio, así que repetirlo al declarar la variable no ayuda mucho.

En este material usaremos exclusivamente «var»

Cuidados con literales y variables

Escribamos una declaración que parece inofensiva:

double uno = 1;

¿Ves algo raro? Bueno, el tipo de variable y el literal no coinciden. Recuerda qué «1» es un literal entero de tipo int. Y la variable «uno» es de tipo «doble». Entonces, el compilador promueve el literal «1» y lo trata como un «double» para que la asignación pueda realizarse correctamente. Entonces después de eso «uno» tendrá el valor de «0»

Ahora veamos este código:
double uno = 1;
double mitad = uno / 2;

Esto produce el valor esperado de «0,5», pero ¿qué sucede si cambias la declaración de variable con «var»?

var uno = 1;
var mitad = uno / 2;

Ahora la mitad es «0». Debido a que «uno» es de tipo int, porque «1» es de tipo int, y luego «uno/2» opera dos enteros, el resultado es un int, por lo que «0,5» se convierte en «0».

Pero si escribes:
var uno = 1.0;
var mitad= uno / 2.0;

Ahora «mitad» es «0.5»

Ten mucho cuidado con los valores que utilizas para inicializar las variables para que obtengas los valores esperados.

Números Mágicos

Código 4 - números mágicos
double tercerÁngulo(double alfa, double beta) {
// la suma de los 3 ángulos de un triángulo es siempre 180.0
 var tercerÁngulo = 180.0 - (alfa + beta);
 return tercerÁngulo;
}

En el código anterior, ¿qué es 180.0? Podrías pensar que es "obvio", pero la mayoría de los literales utilizados en las expresiones parecerían «números mágicos», literales que tienen un significado que no queda claro solo por su valor. Podemos agregar un comentario para explicar su significado pero un mejor enfoque sería utilizar una variable para darle un nombre a este valor:

Código 5 - usar una variable para evitar números mágicos
double tercerÁngulo(double alfa, double beta) {
  var sumaDeTodoslosÁngulos = 180.0;
  var sumaDeÁngulosConocidos = alfa + beta;
  var tercerÁngulo = sumaDeTodoslosÁngulos - sumaDeÁngulosConocidos
  return tercerÁngulo;
}

Con una variable, queda claro qué es lo que el valor intenta representar, mejorando la legibilidad del código.

Trata de evitar los valores que no esten en variables, para que tu codigo sea mas legible.

Reasignaciones

Código 6 - forma caótica de implementar el tercer ángulo
double tercerÁngulo(double alfa, double beta) {
  var ángulo = 180.0;
   ángulo = ángulo - alfa; // actualiza el valor del ángulo
// restando alfa del valor actual
   ángulo = ángulo - beta; // nuevamente, actualiza el ángulo
 return ángulo;
}

Cuando creas una variable usualmente, puedes reasignarle un valor. Las reasignaciones suelen ser malas, luego veremos un ejemplo que necesita reasignación, pero en general es mejor evitarlas. Si lo piensas bien, una variable le da un nombre a un valor, por lo que si estás reasignando, entonces el significado del nombre probablemente no estará relacionado con el nuevo valor. En ese caso, es mejor crear una nueva variable.

Sin embargo, a lo largo de la historia, ¡se ha escrito mucho código con reasignaciones! ¿Porqué es eso? Hubo una época en la que los recursos informáticos eran escasos por lo que había casos en los que era importante no crear demasiadas variables. Hoy en día las computadoras y los compiladores son mucho mejores, por lo que esto ya no es una preocupación.

Misión secundaria: Casting

Casting es una operación donde tomamos una variable de un tipo de dato y le pedimos al compilador que la trate como una variable de otro tipo de dato compatible, en primitivas solo funciona con variables numéricas. Por ejemplo para crear una variable int a partir de un valor double podemos escribir:

var n = (int) 2.0;

Casting tiene una consecuencia importante de entender y es que puede producir pérdida de información. En el código anterior la variable «n» va a tener el valor 2 que es equivalente a «2.0», pero por ejemplo:

var n2 = (int) 3.14;

«n2» tendrá el valor de 3, lo que significa que los valores decimales se perdieron. Así que cuando usemos casting tenemos que estar seguros que no vamos a perder información o que la pérdida es deliberada.

La razón principal para usar casting es para garantizar que una división de 2 ints dé el resultado esperado. Por ejemplo, ¿Qué valores crees que tendrán las variables «a» y «b»?

totalElementos = 11;
var tamañoGrupos = 2;
var a = totalElementos / tamañoGrupos;
var b = (double) totalElementos / tamañoGrupos;

Lo primero importante es entender que «a» es de tipo int y «b» es de tipo double. «a» es de tipo int porque es el resultado de la división de 2 valores int. Recordemos que la división siempre retorna un valor del tipo de los 2 operandos. «b» es de tipo double, debido a que aplicamos un casting a totalElementos por lo tanto el compilador lo trata como un valor double aunque es de tipo int. Usamos ese valor en una división con un int pero como lo habíamos mencionado al operar un valor double con un int, obtenemos un valor de tipo double. Ahora que estamos seguros del tipo de dato debería ser sencillo llegar a la realización que «a» es 5 y «b» es 5.5

Hay otro uso común para casting. Math es una clase que tiene muchos métodos interesantes. Antes vimos la función sqrt() pero hay muchas otras funciones interesantes. De hecho algunas de ellas evitarían que escribamos código más complicado de lo necesario. Dos de esas funciones son ceil() y floor(), ambas toman una variable double y retornan un valor double con el menor número entero mayor que el valor dado, para el caso de ceil() y el mayor número que sea menor que el valor dado, para el caso de floor().

Input
> Math.ceil(7.5)
> Math.ceil(3.14)
> Math.floor(7.5)
> Math.floor(3.14)
Output
8.0
4.0
7.0
3.0

En algunos casos lo que queremos es el resultado de ceil() o floor() como un int y no como un double, así que debemos usar casting.

niños = 5;
var porciones = 1.5;
var elementosParaComprar = (int) Math.ceil(niños * porciones);

Si tenemos un número de niños y tenemos que alimentarlos con una número determinado de porciones de un alimento, podemos calcular el número de alimentos para comprar multiplicando ambos valores. Pero ese número puede dar un número decimal, en el ejemplo anterior la multiplicación de 7.5 pero en raros casos podemos comprar una cantidad no entera de alimentos. Por ejemplo manzanas, nadie nos vende 7.5 manzanas, así que usamos ceil() para estar seguros que obtendremos un número entero. Pero de nuevo ceil realmente retorna double así que el casting nos ayuda a almacenar en una variable int sabiendo que no vamos a tener pérdida de información.

Además de estos 2 casos, pueden haber otras situaciones donde el casting sea necesario, por eso no está de mal entender las reglas de casting.

Resumen

Si intentas empaquetar una gran cantidad de código en una sola línea, afectará la legibilidad del código. En su lugar, puedes utilizar variables para dar nombres a ciertos valores. La antigua forma de definir variables es:

int n = 1;

Pero la forma más nueva es usar «var»:

var n = 1;

Las variables definidas con «var» tienen un tipo y se inferira por el tipo de valor en la asignación.

Cuando utilice literales en su expresión, compruebe si la legibilidad del código se puede mejorar creando una variable para él.

Variables

Quiz Interactivo


Antes de intentar los ejercicios, toma unos minutos para verificar tu entendimiento de Variables tomando este quiz.

  • Las preguntas y el orden de las opciones son diferentes cada vez que tomes el quiz.
  • Las preguntas que tengas mal, vuelven a aparecer luego hasta que las contestes correctamente.
  • Cada pregunta tiene una pista y una explicación.

Ejercicios

Errores del compilador y en tiempo de ejecución

Escribe los siguientes códigos y lea el error devuelto por el compilador o el entorno de ejecución. Luego escribe el código correcto.

E3.1
int duplicar(double a) {
 var foo = a * 2;
return foo;
}

Ejercicios de Codificación

E3.2

Llena los huecos de esta función de modo que al llenarlos la función no arroje un error y funcione como se muestra en el ejemplo de Input / Output. No cambias nada que no sea un hueco.

___ mod(int p, int q) {
   var d = p / q;
   ___ r = d * q;
   ___ m = p - r;
  return m;
}
Input
> mod(3, 2)
> mod(4, 2)
Output
1
0
E3.3

Llena los huecos de esta función de modo que al llenarlos la función no arroje un error y funcione como se muestra en el ejemplo de Input / Output. No cambias nada que no sea un hueco.

int diferenciaDeCuadrados(int a, int b) {
   var ___ = a * a;
   var cuadradoDeB ___ b * b;
   var diferenciaDeCuadrados = cuadradoDeA - cuadradoDeB;
  ___ diferenciaDeCuadrados;
}
Input
> diferenciaDeCuadrados(3, 4)
> diferenciaDeCuadrados(2, 2)
Output
-7
0

E3.4

Escribe una función que calcule la distancia entre dos puntos. Cada punto está representado por 2 doubles; la función toma 4 parámetros: x1, y1, x2 e y2; los dos primeros son las coordenadas x e y del primer punto y los dos últimos son las coordenadas x e y del segundo punto. La fórmula de la distancia es:

Input
> distancia(0.0, 0.0, 1.0, 1.0)
> distancia(0.0, 3.0, 4.0, 0.0)
Output
1.4142135623730951
5.0

E3.5

Para pasar una temperatura de Fahrenheit a Celsius puedes seguir el siguiente algoritmo:

  • De la temperatura de Fahrenheit, resta 32
  • Al resultado anterior multiplícalo por 5/9

Escribe una función que reciba un double que representa una temperatura en fahrenheit y retorne la temperatura equivalente en Celsius.

Input
> fahrenheitACelsius(60.0)
> fahrenheitACelsius(32.0)
Output
15.555555555555557
0.0

E3.6

Escribe una función que calcule la gravedad superficial de un planeta dada la masa y el radio de este. La fórmula para la gravedad superficial es:

en donde G es la constante gravitacional que es 6.67430 x 10-1

Input
> gravedadSuperficial(5.972e24, 6.378e6)
> gravedadSuperficial(6.421e23, 3.3972e6)
Output
9.798429966761134
3.713352371667296

E3.7

Escribe una función que calcule la gravedad superficial de la tierra. Para este ejercicio asume que la masa de la tierra en literal de doubles es 5.972e24 y el radio es 6.378e6. Utiliza la fórmula del ejercicio anterior.

Input
> gravedadSuperficialDeLaTierra()
Output
9.798429966761134             

E3.8

Escribe una función que tome el peso de una persona en la tierra, y devuelva el peso de esa persona en Marte. Para eso, utiliza la fórmula:

Para este ejercicio asume que la masa y el radio de Marte son, respectivamente: 6.421e23 y 3.3972e6

Input
> pesoEnMarte(80.0)
> pesoEnMarte(65.0)
Output
30.31793774524261
24.63332441800962             

E3.9

Un Triángulo es un polígono cerrado de 3 lados. Cada lado tiene una longitud, pero ¿crees que dadas 3 longitudes aleatorias siempre puedes dibujar un triángulo con ellas? La respuesta es no, hay una propiedad de los 3 lados que debe ser cierta para formar un triángulo: el lado más largo debe ser menor que la suma de los otros 2 lados.

Escribe una función que dadas las longitudes de 3 lados, verifique si se puede formar un triángulo.

Hay una manera de escribir la función probando todas las combinaciones posibles, pero hay una manera ingeniosa de usar Math.max(double,double) y otras operaciones para hacer la verificación

Input
> esTriángulo(3.0, 4.0, 5.0)
> esTriágulo(17.0, 10.0, 7.0)
Output
Verdadero
Falso             

E3.10

Los triángulos han jugado un papel muy importante en la historia del hombre. Gracias a sus propiedades, es posible saber cuánto mide una montaña sin ningún instrumento sofisticado y sin tener que subirse a ella. Una de las fórmulas relacionadas con los triángulos es la llamada Ley de Cosenos que dice que para un triángulo cualquiera, si conozco las medidas de 2 lados, llamémoslos «a» y «b» y el ángulo que forman llamesmolo gamma:

Podemos calcular el lado desconocido con la fórmula:

Haz una función que reciba, la medida de «a», de «b» y de gamma, medido en grados centrigados, y retorne el valor de «c».

Para esto lee la documentación de la clase Math y busca:

  • Un método para elevar al cuadrado o en su defecto para hallar potencias (power en inglés)
  • Un método para convertir un ángulo medido en grados (degrees en inglés), a un ángulo medido en radianes (radians en inglés)
  • Un método que dado un ángulo en radianes, devuelva su coseno (cosine en inglés)

Input
> leyCosenos(3.0, 4.0, 90.0)
> leyCosenos(11.0, 11.0, 60.0)
Output
5.0
10.999999999999998           

Ejercicios de Corrección de Código

Para estos problemas, mira los ejemplos de uso de una función y luego revisa el código inicial que no está funcionando como se espera. Ejecútalo y luego corrígelo para coincidir con los ejemplos.

E3.11

Input
> promedio(11, 16)
> promedio(2, 3)
Output
13.5
2.5 
double promedio(int edadMenor, int edadMayor) {
var sumaEdades = edadMenor + edadMayor;
var promedio = sumaEdades / 2;
return promedio;
}

© 2022 Carlos Obregón. This work is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0)

Scroll to Top