Palabras clave: Variables, Tipo de dato, Casting.

Preguntas de repaso
  • ¿Qué es un argumento?

  • ¿Qué diferencia hay entre un tipo de valor y un tipo de dato?

  • ¿Cómo se realiza una asignación a una variable de tipo char? ¿Y si es de tipo String?

  • Una línea de programa que contenga esto float a=2.5; ¿cuántas instrucciones contiene? ¿cómo se llaman dichas instrucciones?

  • ¿Qué valor almacena la variable a después de ejecutar la instrucción a=a+1?

No sigas si no conoces las respuestas.

1. Introducción

Cada vez que se evalúa una expresión en la que interviene un tipo de dato se espera obtener un nuevo dato y del mismo tipo. Por ejemplo, si se suman dos enteros uno espera obtener un nuevo entero y de hecho eso es lo que se obtendrá.

Sin embargo, con algunos tipos de datos tendrás sorpresas porque hay tipo de datos que internamente no son tratados como el tipo de dato declarado, sino como otro tipo de dato. La solución para "recuperar el tipo" consiste en hacer casting.

En otras ocasiones la conversión por casting no es posible y es necesario recurrir a funciones específicas para hacer dicha conversión. Por ejemplo, no es posible convertir un String a un float por casting pero sí que existen funciones que permiten dicha conversión.

2. Casting implícito

Ejecuta este programa

1 2 3 4 5 6 7 8 9 10 11
/* Autor: ISwCyP Fecha: 26/04/2015 La suma de char da como resultado un .... ¿¿¿¿ Cómo ???? */ char a = 'A'; char b = 'B'; char c = '2'; println(a+b-c);

¿Es el resultado esperado? Observa. Se declaran y se inicializan tres variables de tipo char. Después las "sumas" entre ellas. Independientemente de qué es eso de sumar char, lo que parecería aceptable es que el resultado fuera un char; pero no un número de tipo int.

¿Es esto absurdo? Para nada. En absoluto si consideras que todo en un ordenador se codifica con números binarios 0 y 1.

Un ordenador realmente no trabaja con datos de tipo char. El ordenador almacena internamente una tabla que asocia a cada carácter un número. Cuando guardas un carácter en una variable, realmente guardas un número en las celdas de memoria. Cuando muestras el valor de una variable de tipo char realmente recuperas un número y mediante la tabla interna de conversión el ordenador sabe qué símbolo debe de mostrar. Así, cuando operas con caracteres realmente operas con números. Sumar caracteres es por tanto sumar números. Esta conversión de tipo (de char a int) recibe el nombre de casting y como lo realiza internamente el ordenador recibe el nombre de casting implícito.

El número asociado a un carácter se corresponde al lugar que ocupa el carácter en la tabla interna. Así, en el dominio de los caracteres la expresión c+1 no se interpreta como sumar una unidad al carácter c, sino que debe interpretarse como pasar al carácter siguiente a 'c' dentro de la tabla interna y como un carácter es un número, la expresión se interpreta como pasar al número siguiente del número asociado a 'c' dentro de la tabla interna.

3. Casting explícito

Con el ejemplo anterior se muestra que Processing hace una conversión interna de char a int cuando "sumamos" caracteres. Esperábamos que nos diese como resultado otro carácter y no un entero. Para solucionar el problema deberemos convertir ahora el entero en un carácter, lo que se consigue escribiendo a la izquierda de la expresión la secuencia de caracteres (char) como se muestra en el siguiente código :

1 2 3 4 5 6 7 8 9 10 11 12 13
/* Autor: ISwCyP Fecha: 26/04/2015 La suma de char es un int. Si queremos mantener el mismo tipo de dato hemos de hacer casting a char. */ char a = 'A'; char b = 'B'; char c = '2'; println((char) (a+b-c));

En este caso estamos haciendo casting explícito pues somos nosotros (y no el ordenador) el que fuerza el cambio de tipo.

Pero cuidado, poder hacer casting explícito no significa que puedas pasar de cualquier tipo de dato a cualquier otro tipo de dato (todo tiene sus limitaciones). Por ejemplo, nunca podrás pasar un dato de tipo entero a uno booleano o a la inversa.

Explica qué tipo de dato se mostrará con el siguiente código.

1 2 3 4
char a = 'A'; char b = 'B'; char c = '2'; println( (char) a+b-c);

Justifica el resultado

Gracias al casting podemos usar en la función println() un único argumento para imprimir texto y números utilizando el operador +.

El siguiente programa imprime el texto 2+2=4.

1
println("2+2=" + 4);

En este caso el operador + es el operador de sumar String, entendiendo como tal al hecho de concatenar dos cadenas de caracteres. Teniendo en cuenta esto, cuando Processing se encuentra la expresión "2+2=" + 4 lo que hace es:

  1. en primer lugar realiza un casting implícito del número 4 al string "4",

  2. a continuación concatena el String "2+2=" con el String "4", dando como resultado "2+2=4",

  3. por último realiza el correspondiente println() sobre el String "2+2=4".

Indica cuál será la salida del siguiente programa.

1 2
print("2+2="); println(2+2) println("2+2=" + 2 + 2);

Explica qué está pasando y cómo se puede solucionar el problema.

No se puede hacer casting al tipo de datos que te venga a la cabeza. Hay limitaciones.

4. Casting necesarios

En ocasiones estamos forzados a hacer casting. Un caso típico ocurre cuando el tipo de dato de un argumento no coincide con el tipo de dato esperado por la función invocada.

Por ejemplo, si deseamos crear una ventana gráfica de tamaño aleatorio uno puede pensar en usar:

size(random(200), random(200));

Sin embargo esto generará un error en la compilación porque se espera que los dos argumentos de la función size() sean enteros y no número reales. La solución pasa por hacer un casting explícito de reales a enteros con:

size((int) random(200), (int) random(200));

Explica qué está pasando en el siguiente código teniendo en cuenta que:

  • Un double es un tipo de dato que representa el mayor rango de reales posibles en Processing (ocupa 8 celdillas).

  • Consulta la función sin() y mira qué tipo de dato espera recibir como argumento.

1 2
double unNumero = random(10); println(sin(unNumero));

Encuentra una solución al problema.

5. Casting vs funciones de conversión

No podemos hacer cualquier casting. Por ejemplo, no podemos pasar de un tipo de dato compuesto a un tipo de dato simple, ¿cómo hemos de interpretar el string "123" o el string "UnoDosTres" como un entero? Por casting no es posible ninguna interpretación.

No obstante, en ocasiones los lenguajes de programación disponen de un conjunto de funciones que permiten pasar cualquier tipo de dato a cualquier tipo de dato. Por ejemplo, Processing dispone de la función int() que convierte el string "123" en el entero 123 y el string "UnoDosTres" en el entero 0. ¿Por qué hace esta conversión? Simplemente porque los programadores de Processing así lo decidieron.

Pero no es lo mismo hacer casting que usar una función de conversión. En un casting lo que hacemos es interpretar el contenido de la memoria como si fuera otro tipo de dato: se usa solo un valor. Por contra, en una función de conversión lo que hacemos es usar un valor como argumento de una función que nos retorna otro valor: se usan dos valores.

6. Repasa y memoriza

  • El casting es el proceso por el que cambiamos el valor de un tipo de dato a otro tipo de dato.

  • El casting puede ser implícito (lo hace el lenguaje) o explícito (lo hace el programador).

  • No podemos hacer casting explícito de cualquier tipo de dato a cualquier tipo de dato. Hay limitaciones.

  • No es lo mismo interpretar un valor (casting) como otro tipo de dato que convertir una valor en otro valor de otro tipo de dato (conversión).

  • Procura no usar funciones de conversión hasta que no domines el casting.