Un programa no es ni más ni menos que una automatización que se aplica a un conjunto de información, de datos.
Algunas veces son los datos de un elemento en particular, otras de muchos datos similares. A veces son cosas que pasaron antes, y otras, los sucesos del mismo momento (un juego, por ejemplo).
Sin embargo, sigue siendo, siempre, manipulación de datos.
Los usamos en la vida diaria, los usamos en cada momento en un programa, o en una aplicación que usamos… y sin ton ni son, sin entender muy bien que son, como son, como los entiende un procesador… así que, a ello vamos. A definir los datos.
Empecemos por entender que hace el procesador con los datos.
Calculando. (lo primero que hicieron los procesadores)
Desde el principio de la historia (informática :)), ha sido igual. Empezar por hacer algo del estilo 2+2=4 .. Pero muchas veces y muy rápido.
Eso se hace “moviendo” datos a espacios particulares e la circuitería del procesador, llamados registros. Los procesadores modernos se basan en la arquitectura IA32 (que se extendió este siglo a la IA64) ya que por una parte es eficiente y por otra, mantienen compatibilidad.
Se podría hablar mucho de esto, pero la realidad es que nos importa entender, desde el punto de vista de los datos, algo muy básico. Los datos se cargan y operan en los registros de maneras muy simples.
- Se mueve un valor a un registro
- Se mueve el otro valor al segundo registro.
- Se aplica el operador
- Se obtiene un resultado (por ser simple, digamos en el primer registro)
Por ejemplo:
Reg A | 2 | 00000010 | |
Reg B | 2 | 00000010 | |
+ | 4 | 00000100 |
Esto es fácil de entender, ya que estamos operando con números simples. Y así era, al principio. Números enteros, fáciles de operar.
Otro ejemplo clásico es la operatoria de lógica.
Digamos que tengo un valor de verdad (1) y un valor de falsedad (0) y operamos lógicamente. Esto es:
AND | OR | |
1 | 0 | 1 |
0 | 0 | 1 |
0 | 1 |
Por esto, cada cálculo se optimiza para los registros. En conclusión, los valores numéricos (enteros sobre todo), son los más rápidos y manejables.
Y las operaciones se hacen moviendo los valores de alguna parte de la memoria de trabajo, en los registros, ida y vuelta. Eso es por lo que se suele hablar de “tipos (de datos) por valor”.
En cambio, cuando no es posible utilizar esta operatoria, el procesador utiliza las referencias a los lugares en la memoria (direcciones), donde se encuentra los datos, y opera contra ellos. Más efectivo, pero mucho más lento. Entonces, ante estos datos, se realizan las operaciones pero con “punteros” que dirigen a la memoria (existen registros especiales del procesador para esto). Estos son, entonces, los “tipos por referencia”.
En el .Net Framework, tenemos entonces:
En la tabla, donde dice que char mide 1 byte, debiera decir 2 bytes. (Gracias Ivanov!). Es que son caracteres de doble byte, para que pueda almacenar cualquier idioma (por ejemplo, Klingon
)
Tipos por valor:
Finalmente, existen algunos pocos tipos de datos definidos por el programador que heredan naturalmente de ValueType (no es posible declarar herencia explícita).
Enumeraciones
Un tipo de dato, que naturalmente hereda de alguno de los anteriores, pero que solo exponen algunos valores, por ejemplo
Visual Basic
Enum DíasSemana As SByte Domingo Lunes Martes Miércoles Jueves Viernes Sábado End Enum
C#
enum DíasSemana : sbyte { Domingo, Lunes, Martes, Miércoles, Jueves, Viernes, Sábado }
Estructuras
Son tipos definidos por el usuario que admiten varios campos en la definición. Llamativamente, heredan de ValueType aun cuando en su definición contengan tipos por referencia. Sin embargo, esos tipos por referencia solo tienen la dirección de OTRA posición de memoria donde se almacena dicho objeto.
Visual Basic
Structure Estructura Public Entero As Integer Public Lógico As Boolean Public cadena As String End Structure
C#
struct Estructura { public int Entero; public bool Lógico; public string cadena; }
Los tipos por referencia
Hablamos de tipos de datos por referencia, cuando el procesador debe “saltar” de sus registros (especiales para referencias), a la dirección de memoria donde está ubicado el dato y volver luego a seguir con lo suyo. Siendo este proceso más lento es, sin embargo, mucho más versátil.
Por otra parte, los datos por referencia nos permiten mucha mayor versatilidad ya que podemos almacenar información diferente, compuesta y compleja. Obviamente, en la mayoría de los procesos, estos tipos de datos son los más utilizados. Pero recordemos siempre que procesar tipos por valor es más rápido.
En la próxima hablaremos de tipos por referencia en detalle, objetos y… seguimos.