viernes, 30 de noviembre de 2007

Tipos de datos



Tipo de datos simples

Los tipos simples, que incluyen tipos ordinales y tipos reales de datos, son tipos de datos que definen conjuntos ordenados de valores.

En el conjunto de los tipos ordinales se incluyen:

Tipo de dato entero,

Tipo de dato carácter,

Tipo de dato lógico (booleano),

Tipo de dato enumerado y

Tipo de dato subrango

Un tipo ordinal define un conjunto ordenado de valores en los cuales cada valor, excepto el primero, tienen un único predecesor y cada valor, excepto el último, tienen un único sucesor. Más aún, cada valor tiene una ordinalidad, la cual determina el orden del tipo.

Para los tipos entero la ordinalidad de un valor es el valor por sí mismo; para todo el resto de los tipos ordinales, excepto los subrangos, el primer valor tiene ordinalidad 0 (cero), el siguiente valor tiene ordinalidad 1 (uno) y así sucesivamente. Si un valor tiene ordinalidad n, su predecesor tiene ordinalidad n-1 y su sucesor tiene ordinalidad n+1.

Tipo de dato entero

Un tipo de dato entero en computación es un tipo de dato que puede representar un subconjunto finito de los números enteros. El número mayor que puede representar depende del tamaño del espacio usado por el dato y la posibilidad (o no) de representar números negativos. Los tipos de dato entero disponibles y su tamaño dependen del lenguaje de programación usado así como la arquitectura en cuestión. Por ejemplo, si para almacenar un número entero disponemos de 4 bytes de memoria tememos que:

4 Bytes = 4x8 = 32 bits

Con 32 bits se pueden representar 232=4294967296 valores:

Sólo positivos: del 0 al 4294967295

Positivos y negativos: del -2147483648 al 2147483647

Operaciones con enteros

Las típicas operaciones aritméticas: suma, resta, multiplicación y división se pueden realizar con datos de tipo entero. En el caso de la división, el resultado podría ser un valor real, en ese caso, si el resultado se ha de almacenar como entero la parte decimal del resultado deberá ser eliminada, en principio hay dos métodos para hacerlo:

El redondeo: Aproximar el valor real al entero más cercano (Ej: 3,8-->4 / 3,2-->3)

El truncamiento: Eliminar del valor real la parte decimal (Ej: 3,8-->3 / 3,2-->3)

Otra operación importante que se puede realizar con número enteros es la operación de módulo o resto de la división entera, es decir:

184 dividido 3 = 61 (resto 1) --> 184 módulo 3 = 1

En general la operación módulo cumple que:

a mod b = c

c ≥ 0

c <>

si c es igual a 0 --> a es múltiplo de b

si c es igual a 0 y b es igual a 2 --> a es par

El desbordamiento (overflow)

Cuando operando con número enteros en un programa de ordenador ocurre que se intenta asignar a un valor entero un valor que está fuera del rango de los valores que se pueden representar (Ej: a=240) se produce un fallo que se conoce con el nombre de desbordamiento (overflow en inglés). Cuando esto ocurre lo habitual es que el programa siga funcionando como si nada hubiera pasado, pero el valor desbordado se habrá convertido en un valor indeterminado con lo que las operaciones posteriores en las que este valor intervenga producirán resultados incorrectos.

Tipo de dato carácter

Cualquier signo tipográfico. Puede ser una letra, un número, un signo de puntuación o un espacio. Este término se usa mucho en computación.

Un valor de tipo carácter es cualquier carácter que se encuentre dentro del conjunto ASCII ampliado, el cual está formado por los 128 caracteres del ASCII más los 128 caracteres especiales que presenta, en este caso, IBM.

Los valores ordinales del código ASCII ampliado se encuentran en el rango de 0 a 255. Dichos valores pueden representarse escribiendo el carácter correspondiente encerrado entre comillas simples (apóstrofos).

Así, podemos escribir:

'A' < 'a'

Que significa: "El valor ordinal de A es menor que el de a" o "A está antes que a"

Un valor de tipo carácter (char en inglés) se guarda en un byte de memoria.

La única operación (además de las relacionales) que podemos hacer con caracteres es la concatenación concatenando dos caracteres, por ejemplo 'a' y 'X' obtendríamos la cadena "aX".

Tipo de dato lógico

El tipo de dato lógico o booleano es en computación aquel que puede representar valores de lógica binaria, esto es, valores que representen falso o verdadero.

Para generar un dato o valor lógico a partir de otros tipos de datos, típicamente, se emplean los operadores relacionales (u operadores de relación), por ejemplo:

3>2 --> verdadero

7>9 --> falso

Una vez se dispone de uno o varios datos de tipo booleano, estos se pueden combinar en expresiones lógicas mediante los operadores lógicos (AND, OR, NOT, ...). Un ejemplo de este tipo de expresiones serían:

verdadero AND falso --> falso

falso OR verdadero --> verdadero

Tipo de dato enumerado

Un tipo enumerado define un conjunto ordenado de valores con el simple hecho de listar los identificadores que denotan tales valores. Los valores no tienen un significado/valor inherente al nombre del identificador y su ordinalidad sigue la secuencia en la cual los identificadores se listan.

Definición

Para definir un tipo enumerado se utiliza la siguiente sintaxis:

( ident-1, ident-2, ..., ident-n )

Donde ident-i es un identificador legal de Lenguaje de programación Pascal: Esto significa que ident-i no debe ni empezar ni ser un número en sí. Deben ser letras del alfabeto inglés y que no aparezcan en otra definición de tipo enumerado. El objetivo es definir un tipo de datos cuyos valores sean los identificadores: ident-1, ident-2, ..., ident-n.

Ejemplo: ( B21, ABC, B33 ) define un tipo enumerado de datos. Pero ni ( 12531, 14405 ) ni ( A-, B+, B- ) son definiciones legales de tipo.

Aplicaciones

La lista de valores que definen un tipo enumerado de datos se puede asociar con un identificador en la sección de tipos. Este identificador se puede usar después para especificar el tipo de variables, parámetros formales y valores de funciones. Ejemplo:

TYPE

DiasDeSemana = ( Lunes, Martes, Miercoles,

Jueves, Viernes, Sabado, Domingo )
VAR

Dia : DiasDeSemana;


FUNCTION Convertir ( x, y : integer ) : DiasDeSemana;


PROCEDURE Calendario ( Dia : DiasDeSemana; VAR NumeroDeDia : integer );

La lista de valores que definen un tipo enumerado se puede utilizar en la sección de variables para especificar el tipo de una variable, pero no se puede utilizar en cabeceras de funciones y procedimientos. Los valores de un tipo enumerado están ordenados por la lista de valores en la definición de ese tipo. Los tipos enumerados son, por tanto, tipos ordinales. Para cualquier valor de un tipo enumerado, la función ord devuelve su posición en la lista de valores que define el tipo, empezando por la numeración. Los valores de los tipos enumerados se pueden comparar utilizando los operadores relacionales: =, <>, <, >, <=, >=. Las funciones predefinidas pred y succ se pueden utilizar para encontrar el predecesor y el antecesor de un valor de un tipo enumerado. Los valores de un tipo enumerado no se pueden leer desde un teclado o mostrarse en pantalla, ni se pueden leer o escribir en un archivo de texto. Se deben, por tanto, escribir procedimientos especiales de entrada/salida para los tipos enumerados: para la salida, se puede utilizar una instrucción CASE que seleccione la cadena apropiada para cada valor; para la entrada, se puede examinar toda la cadena, carácter a carácter, hasta determinar el valor del tipo enumerado que se asigna a la variable de entrada.

Tipo de dato subrango

El tipo de dato más simple que se puede definir en un programa Pascal es el tipo subrango o intervalo. Estos tipos son útiles, sobre todo por la facilidad que ofrecen para verificar automáticamente errores. Un tipo subrango se define de un tipo ordinal, especificando dos constantes de ese tipo, que actúan como límite inferior y superior del conjunto de datos de ese tipo. Un tipo subrango es un tipo ordinal y sus valores se ordenan de igual modo que en el tipo patrón de que se deducen.

Ejemplos:

1. 0..9 — este tipo subrango consta de los elementos

0,1,2,3,4,5,6,7,8,9

2. '0'..'9' — este subrango consta de los caracteres

'0','1','2','3','4','5','6','7','8', '9'

3. 'A'..'F' — este subrango consta de los caracteres

'A','B','C','D','F'

Se pueden crear variables cuyos valores se restrinjan a un subrango dado. Las declaraciones de tipo subrango se sitúan entre las declaraciones de constantes y de variables.

Formato:

type

Nombre = límite inferior .. límite superior


Ejemplos:

{$R+} {Directiva de compilador R}

Program Positivos;

Uses Crt;

{El siguiente programa realiza una validación

para que sólo se acepten valores positivos

entre 0 y 32767 por medio de un tipo subrango}

Type

NumPositivo = 0..MaxInt;

Var

numero : NumPositivo;

Begin

ClrScr;

{numero:=-1; (está instrucción provocaría un error}

Write('Escribe un número entero positivo : ');

ReadLn(numero);

ReadKey

end.

Nota: Puesto que Turbo Pascal no siempre produce un error cuando el valor de un tipo subrango está fuera de su rango definido. Sin embargo se puede tener la posibilidad de visualizar dichos errores mediante la directiva de compilador:

{$R+} activada

{$R-} desactivada

Por defecto, está desactivada. Sólo se debe usar durante la fase de depuración.

TIPOS ENUMERADOS

En estos tipos de datos simples, se listan los identificadores que serán asociados con cada valor a utilizar.

Por ejemplo :

Type

dias_semana =(lunes,martes,miércoles,jueves,

viernes,sabado,domingo);

colores_baraja =(espada,oro,basto,copa);

De igual forma las variables pueden ser de tipo enumerado:

Var

días : dias_semana;

baraja : colores_baraja;

Formato:

Type

nombre = (constante1,constante2,...,constanteN)

Los datos de tipo colores_baraja sólo podrán tomar los valores denotados por : espada, oro, basto, copa . La posición de cada valor en la lista define su orden, por lo que para el tipo dias_semana tenemos que :

domingo > viernes da como resultado true

sabado < style=""> da como resultado false

jueves <> miércoles da como resultado true

Características:

Un tipo de dato enumerado es un tipo ordinal cuyo orden se indica por la disposición de los valores en la definición.

El número de orden de cada elemento comienza en 0 para el primer elemento.

Las variables de tipo enumerado sólo pueden tomar valores de estos tipos.

Los únicos operadores que pueden acompañar a los tipos ordinales son los operadores de relación y asignación.

A los valores de los tipos enumerados se les pueden aplicar las funciones estándar succ (de sucesor), pred (de predecesor) y ord (de ordinal).

En el caso del valor máximo de un tipo enumerado, succ no está definido, y, para su valor mínimo, no está definido pred.

La función estándar ord es aplicable a los argumentos que sean valores de tipo enumerado. La relación biunívoca se da entre los valores del tipo y los enteros comprendidos entre 0 y N-1, donde N es la cardinalidad del tipo enumerado.

El tipo estándar boolean es equivalente a un tipo enumerado de la forma :

boolean = ( false, true);

Ejemplo:

Program Dias_Semana;

Uses Crt;

{El siguiete programa muestra los días de

la semana por medio de tipos enumerados}

Type

Dia_Semana = (Lunes,Martes,Miércoles,Jueves,

Viernes,Sabado,Domingo);

Var

días :Dia_Semana;

i :byte;

Begin

ClrScr;

días:=lunes;

for i:=1 to 7 do

begin

case días of

Lunes :WriteLn('Lunes ');

Martes :WriteLn('Martes ');

Miércoles :WriteLn('Miércoles');

Jueves :WriteLn('Jueves ');

Viernes :WriteLn('Viernes ');

Sabado :WriteLn('Sabado ');

Domingo :WriteLn('Domingo ')

end;

días:=succ(días)

end;

ReadKey

end.

Tipo de dato real

El tipo de dato real define un conjunto de números que pueden ser representados con la notación de coma flotante.

Al igual que los números enteros, el tipo real está limitado superior e inferiormente según la cantidad de memoria que haya disponible para almacenarlo. Otro elemento importante a tener en cuenta en este tipo de datos es la precisión con que pueden representar número con decimales (cuantos decimales se pueden representar), esta característica también esta directamente relacionada con la cantidad de memoria disponible para almacenar un valor real.

A modo de ejemplo, en la tabla siguiente se muestran los rangos así como los formatos de almacenamiento para los tipos reales fundamentales para un determinado lenguaje de programación.

Tipos reales fundamentales en Pascal:


Imagen1

Cuando la precisión que admite un valor real es rebasada el valor de este trunca o se redondea. Por ejemplo si el máximo número de dígitos decimales que puede albergar un tipo real es 10 la siguiente operación:

a = 123,123456789 / 100

debería dar como resultado que a es igual a 1,23123456789, pero este valor tiene 11 decimales, por lo que el valor de a será uno de estos:

Truncando: a = 1,2312345678

Redondeando: a = 1,2312345679

Operaciones

Las típicas operaciones aritméticas:

Suma

Resta

Multiplicación

División

Puntero (programación)

Un puntero (o apuntador) es una variable manipulable que referencia una región de memoria; en otras palabras es una variable cuyo valor es una dirección de memoria. Si se tiene una variable ' p ' de tipo puntero que contiene una dirección de memoria en la que se encuentra almacenado un valor ' v ' se dice que p apunta a v.

[Memoria]

Imagen2

Trabajar con punteros implica la no manipulación de las variables en sí, sino manejar direcciones de memoria en la cuales residen los datos.

Los punteros son de amplia utilización en programación y casi todos los lenguajes permiten la manipulación de los mismos. La razón de ser principal de los punteros reside en manejar datos alojados en la zona de memoria dinámica o heap (aunque también se pueden manipular objetos en la zona estática), bien sean datos elementales, estructuras (struct en C) u objetos pertenecientes a una clase (en lenguajes Orientados a Objetos). Gracias a esta propiedad, los punteros permiten modelar un grafo, en donde los elementos de éste son los datos residentes en memoria y las relaciones entre los elementos son los propios apuntadores. Sin embargo, los punteros son un gran dolor de cabeza para los programadores novatos y para cualquier programador que deba depurar una aplicación.

En nuevos lenguajes de alto nivel, los punteros se han tratado de abstraer. De tal forma que en el lenguaje C# sólo pueden ser usados en zonas de código delimitadas como "inseguras", o llegando a su total desaparición en lenguajes como Java o Eiffel.

Ejemplo de uso de punteros en una estructura en C

(El ejemplo que sigue es propio del lenguaje C/C++ y no es de aplicación en otros lenguajes de programación).

struct Elemento // Ejemplo de un nodo de lista doble enlazada

{

int dato;

struct Elemento *siguiente; // Para la declaración de un puntero se usa '*'

struct Elemento *anterior;

};

Para acceder a los atributos como punteros de una estructura que va a ser tratada como tal, se debe desreferenciar el puntero y acceder a sus miembros como se haría con una variable normal, o usar directamente el operador: ->. De tal modo que:

Elemento *elem;

Elemento sig1 = (*elem).siguiente;

Elemento sig2 = elem->siguiente;

/* Se cumple que: sig1==sig2 */

Otro ejemplo en C++

void swap(int *x, int *y) {

int temp;

temp = *x; // copia el valor apuntado por x a temp

*x = *y; // copia el valor apuntado por y en la ubicación del puntero x

*y = temp; // copia el valor de temp en la ubicación apuntada por y

}

Cadena de caracteres

En matemáticas o en programación, una cadena de caracteres, palabra o frase (String en inglés) es una secuencia ordenada de longitud arbitraria (aunque finita) de elementos que pertenecen a un cierto alfabeto. En general, una cadena de caracteres es una sucesión de caracteres (letras, números u otros signos o símbolos).

En matemáticas es habitual usar las letras w, x, y,... para referirnos a las cadenas. Por ejemplo, si tenemos un alfabeto Σ = {a, b, c}, una cadena podría ser: x = aacbbcba.

Desde un punto de vista de la programación, si no se ponen restricciones al alfabeto, una cadena podrá estar formada por cualquier combinación finita de todo el juego caracteres disponibles (las letras de la 'a' a la 'z' y de la 'A' a la 'Z', los números del '0' al '9', el espacio en blanco ' ', símbolos diversos '!', '@', '%', etc). En este mismo ámbito (el de la programación), se utilizan normalmente como un tipo de dato predefinido, para palabras, frases o cualquier otra sucesión de caracteres. En este caso, se almacenan en un vector de datos, o matriz de datos de una sola fila (array en inglés). Las cadenas se pueden almacenar físicamente:

Seguidas.

Enlazados letra a letra.

Generalmente son guardados un carácter a continuación de otro por una cuestión de eficiencia de acceso.

Un caso especial de cadena es la que contiene cero caracteres, a esta cadena se la llama cadena vacía.

Operaciones con cadenas

Siguiendo en el ámbito de la informática, al considerar las cadenas como un tipo de datos, hay que definir (o conocer) cuales son las operaciones que podemos hacer con ellas, en principio estas podrían ser muchas y llegar a ser muy sofisticadas, pero las que podríamos considerar básicas son:

Concatenación: Consiste en unir dos cadenas o más (o una cadena con un carácter) para formar una cadena de mayor tamaño.

Búsqueda: Consiste en localizar dentro de una cadena una subcadena más pequeña o un carácter.

Extracción: Se trata de sacar fuera de una cadena una porción de la misma según su posición dentro de ella.

(Operaciones con cadenas en el lenguaje C)

Representación

Una cadena suele ser representada entre comillas dobles superiores ("palabra"), mientras que un carácter de esa cadena (un char en inglés) suele ser representado entre comillas simples ('p'). Por ejemplo, en C:

char c = 'a';

char str [5] = "hola";

Generalmente para acceder a un carácter en una posición determinada se suele usar la forma variable[posición] como cuando se accede a un vector.

Para poder mostrar una comilla (") dentro de la cadena y no tener problemas con las comillas que la delimitan, se usan secuencias de escape. Esto se aplica a otros caracteres reservados o no imprimibles como el retorno de carro. No obstante, las expresiones para producir estas secuencias de escape dependen del lenguaje de programación que se esté usando. Una forma común, en muchos lenguajes, de escapar un carácter es anteponiéndole un «\» (sin comillas), p. e.: «\"» (sin comillas).

Cadenas dinámicas y estáticas

Las cadenas pueden ser de naturaleza dinámica (pueden alterar su longitud durante el tiempo de ejecución), o de naturaleza estática (su longitud es fija a lo largo del tiempo de ejecución). En este segundo caso el programador debe prever que al recorrer la cadena los indíces no se vayan de los límites previstos (C no permite que las cadenas crezcan automáticamente de forma explíta, mientras que C# sí).

El final de la cadena se delimita de diferente manera en uno u otro caso:

Mediante un carácter de fin de cadena ("\0" en C) para las cadenas de tipo dinámico.

Mediante una propiedad de la cadena que delimite su longitud (Count en C#) para las de tipo estático.

Algunas operaciones comunes

Concatenación: unir dos cadenas de caracteres.

$pareja = "Joshua"." y "."Lidia" # en Perl y PHP;

pareja = "Luisa" & " y " & "Carmen" # en Visual Basic;

pareja = "Luisa" + " y " + "Carmen"; # en C++ y Java con la clase String.

Multiplicar una cadena: repetir una cadena un número de veces

$puntos ="." x 5 # pone 5 puntos en Perl

Estructura de datos

En programación, una estructura de datos es una forma de organizar un conjunto de datos elementales (un dato elemental es la mínima información que se tiene en el sistema) con el objetivo de facilitar la manipulación de estos datos como un todo o individualmente.

Una estructura de datos define la organización e interrelacionamiento de estos, y un conjunto de operaciones que se pueden realizar sobre él. Las operaciones básicas son:

Alta, adicionar un nuevo valor a la estructura.

Baja, borrar un valor de la estructura.

Búsqueda, encontrar un determinado valor en la estructura para realizar una operación con este valor, en forma SECUENCIAL o BINARIO (siempre y cuando los datos estén ordenados)...

Otras operaciones que se pueden realizar son:

Ordenamiento, de los elementos pertenecientes a la estructura.

Apareo, dadas dos estructuras originar una nueva ordenada y que contenga a las apareadas.

Cada estructura ofrece ventajas y desventajas en relación a la simplicidad y eficiencia para la realización de cada operación. De esta forma, la elección de la estructura de datos apropiada para cada problema depende de factores como la frecuencia y el orden en que se realiza cada operación sobre los datos.

Tipos de datos elementales

-Binarios

--Bit

--Byte

-Numéricos

--Entero

--Real

---Coma fija

---Coma flotante

-Alfanuméricos

--Carácter

--Cadena

Estructuras de datos

-Vectores (matriz o array)

-Registro (estructura de datos)

-Tipo de datos algebraico

-Listas Enlazadas

--Listas Simples

--Listas Dobles

--Listas Circulares

--Listas por saltos (Skip lists)

-Pilas (stack)

-Colas (queue)

--Colas de Prioridad

-Árboles

--Árboles Binarios

---Árbol binario de búsqueda

---Árbol binario de búsqueda equilibrado

---Árboles Rojo-Negro

---Árboles AVL

---Árboles Biselados (Árboles Splay)

--Árboles Multicamino (Multirrama)

---Árboles B

---Árboles B+

---Árboles B*

-Conjuntos (set)

-Grafos

-Tablas Hash

-Montículos (o heaps)

--Montículo binario

--Montículo binómico

--Montículo de Fibonacci

--Montículo suave

--Montículo 2-3

Tipo de dato abstracto

Un tipo de dato abstracto (TDA) o Tipo abstracto de datos (TAD) es un modelo matemático compuesto por una colección de operaciones definidas sobre un conjunto de datos para el modelo.

Introducción

En el mundo de la programación existen diversos lenguajes que se han ido creando con el paso del tiempo y que se han perfeccionado debido a las necesidades de los programadores de la época a la que pertenecen. Los primeros lenguajes de programación eran de tipo lineales, ya que un programa se recorría desde un punto marcado como Inicio hasta llegar a un punto Fin. Con el tiempo se fueron creando nuevos lenguajes y en nuestros días los más utilizados son los llamados “Orientados a Objetos”.

Los Lenguajes Orientados a Objetos (LOO) tienen la característica de que no son lenguajes lineales, sino que se forman de diversas funciones, las cuales son llamadas en el orden en que el programa mismo las pide o el usuario determina. Para entender mejor cómo funcionan los Lenguajes Orientados a Objetos, vamos a introducir un concepto fundamental en las Estructuras de Datos denominado Abstracción de Datos y que es parte importante de estos Lenguajes y de la manera en que funciona la mayoría del software comercial de nuestros días.

Historia

El concepto de tipo de dato abstracto (TDA, Abstract Data Types ), fue propuesto por primera vez hacia 1974 por John Guttag y otros, pero no fue hasta 1975 que por primera vez Liskov lo propuso para el lenguaje CLU.llina

Definición

Con mucha frecuencia se utilizan los términos “TDA” y “Abstracción de Datos” de manera equivalente, y esto es debido a la similitud e interdependencia de ambos. Sin embargo, es importante definir por separado los dos conceptos.

Como ya se mencionó, los Lenguajes de Programación Orientados a Objetos son lenguajes formados por diferentes métodos o funciones y que son llamados en el orden en que el programa lo requiere, o el usuario lo desea. La abstracción de datos consiste en ocultar las características de un objeto y obviarlas, de manera que solamente utilizamos el nombre del objeto en nuestro programa. Esto es similar a una situación de la vida cotidiana. Cuando yo digo la palabra “perro”, usted no necesita que yo le diga lo que hace el perro. Usted ya sabe la forma que tiene un perro y también sabe que los perros ladran. De manera que yo abstraigo todas las características de todos los perros en un solo término, al cual llamo “perro”. A esto se le llama ‘Abstracción’ y es un concepto muy útil en la programación, ya que un usuario no necesita mencionar todas las características y funciones de un objeto cada vez que éste se utiliza, sino que son declaradas por separado en el programa y simplemente se utiliza el término abstracto (“perro”) para mencionarlo.

En el ejemplo anterior, “perro” es un Tipo de Dato Abstracto y todo el proceso de definirlo, implementarlo y mencionarlo es a lo que llamamos Abstracción de Datos.

Vamos a poner un ejemplo real de la programación. Supongamos que en algún Lenguaje de Programación Orientado a Objetos un pequeño programa saca el área de un rectángulo de las dimensiones que un usuario decida. Pensemos también que el usuario probablemente quiera saber el área de varios rectángulos. Sería muy tedioso para el programador definir la multiplicación de ‘base’ por ‘altura’ varias veces en el programa, además que limitaría al usuario a sacar un número determinado de áreas. Por ello, el programador puede crear una función denominada ‘Área’, la cual va a ser llamada el número de veces que sean necesitadas por el usuario y así el programador se evita mucho trabajo, el programa resulta más rápido, más eficiente y de menor longitud. Para lograr esto, se crea el método Área de una manera separada de la interfaz gráfica presentada al usuario y se estipula ahí la operación a realizar, devolviendo el valor de la multiplicación. En el método principal solamente se llama a la función Área y el programa hace el resto.

Al hecho de guardar todas las características y habilidades de un objeto por separado se le llama Encapsulamiento y es también un concepto importante para entender la estructuración de datos.

Caracterización

Un TDA está caracterizado por un conjunto de operaciones (funciones) al cual le denominaron usualmente como su interfaz pública y representan el comportamiento del TDA; mientras que la implementación como la parte privada del TDA está oculta al programa cliente que lo usa. Todos los lenguajes de alto nivel tienen predefinidos TDA; que son los tipos denominados simples y las estructuras predefinidas, y estos tienen sus interfaces públicas que incluyen las operaciones como la +, -, *, etc.

En un TDA no se necesita conocer como actúan tales operadores sobre la representación interna de los tipos definidos, que además, suele ser una implementación bastante dependiente de la máquina sobre la que trabaje el compilador. Lo interesante es que los lenguajes actuales nos van a permitir ampliar los TDA predefinidos con otros que serán definidos por el propio programador para adecuar así los tipos de datos a las necesidades de los programas.

Los TDA que nos van a interesar de ahora en adelante son aquellos que reflejen cierto comportamiento organizando cierta variedad de datos estructuradamente. A esta forma estructurada de almacenar los datos será a la que nos refiramos para caracterizar cada TDA.

Los TDA que tienen informaciones simples pero dependientes de un comportamiento estructural serán llamados polilíticos y aquellos TDA simples, como son los tipos predefinidos donde la información no es relacionada mediante ninguna estructura y no admiten más que un valor en cada momento serán denominados TDA monolíticos.

Nótese que cuando hablemos de un TDA no haremos ninguna alusión al tipo de los elementos sino tan sólo a la forma en que están dispuestos estos elementos. Sólo nos interesa la estructura que soporta la información y sus operaciones. Para determinar el comportamiento estructural basta con observar la conducta que seguirán los datos.

Caractericemos entonces los TDA. Un TDA tendrá una parte que será invisible al usuario la cual hay que proteger y que se puede decir que es irrelevante para el uso del usuario y está constituida tanto por la maquinaria algorítmica que implemente la semántica de las operaciones como por los datos que sirvan de enlace entre los elementos del TDA, es decir, información interna necesaria para la implementación que se esté haciendo para ese comportamiento del TDA. Resumiendo podemos decir, que tanto la implementación de las operaciones como los elementos internos del TDA serán privados al acceso externo y ocultos a cualquier otro nivel.

Un TDA representa una abstracción:

Se destacan los detalles (normalmente pocos) de la especificación (el qué).

Se ocultan los detalles (casi siempre numerosos) de la implementación (el cómo).

La abstracción

La abstracción, una de las herramientas que más nos ayuda a la hora de solucionar un problema, es un mecanismo fundamental para la comprensión de problemas y fenómenos que poseen una gran cantidad de detalles, su idea principal consiste en manejar un problema, fenómeno, objeto, tema o idea como un concepto general, sin considerar la gran cantidad de detalles que estos puedan tener. El proceso de abstracción presenta dos aspectos complementarios.

1. Destacar los aspectos relevantes del objeto.

2. Ignorar los aspectos irrelevantes del mismo (la irrelevancia depende del nivel de abstracción, ya que si se pasa a niveles más concretos, es posible que ciertos aspectos pasen a ser relevantes).

De modo general podemos decir que la abstracción permite establecer un nivel jerárquico en el estudio de los fenómenos, el cual se establece por niveles sucesivos de detalles. Generalmente, se sigue un sentido descendente de detalles, desde los niveles más generales a los niveles más concretos.

Por ejemplo: los lenguajes de programación de alto nivel permiten al programador abstraerse del sin fin de detalles de los lenguajes ensambladores. Otro ejemplo, la memoria de la computadora es una estructura unidimensional formada por celdas y sin embargo trabajamos como si fuera única. La abstracción nos brinda la posibilidad de ir definiendo una serie de refinamientos sucesivos a nuestro TDA y entiéndase bien que cuando decimos refinamientos sucesivos nos estamos refiriendo a la estrategia que se utiliza para descomponer un problema en subproblemas. Conforme evoluciona el diseño de software a cada nivel de módulos se representa un refinamiento en el nivel de abstracción. Esto es, incluir detalles que fueron obviados en un nivel superior, en un nivel más bajo de la jerarquía.

Veamos los diferentes tipos de abstracción que podemos encontrar en un programa:

1. Abstracción funcional: crear procedimientos y funciones e invocarlos mediante un nombre donde se destaca qué hace la función y se ignora cómo lo hace. El usuario sólo necesita conocer la especificación de la abstracción (el qué) y puede ignorar el resto de los detalles (el cómo).

2. Abstracción de datos:

Tipo de datos: proporcionado por los leguajes de alto nivel. La representación usada es invisible al programador, al cual solo se le permite ver las operaciones predefinidas para cada tipo.

Tipos definidos: por el programador que posibilitan la definición de valores de datos más cercanos al problema que se pretende resolver.

TDA: para la definición y representación de tipos de datos (valores + operaciones), junto con sus propiedades.

Objetos: Son TDA a los que se añade propiedades de reutilización y de compartición de código.

Si profundizamos más al mundo de la programación y sus conceptos, existen dos de estos conceptos que no se deben confundir, ellos son: tipo de datos y estructura de datos.

Un tipo de dato, en un lenguaje de programación, define un conjunto de valores que una determinada variable puede tomar, así como las operaciones básicas sobre dicho conjunto. Ahora veamos como se van relacionando estos conceptos. Los tipos de datos constituyen un primer nivel de abstracción, ya que no se tiene en cuenta cómo se implementan o se representan realmente la información sobre la memoria de la máquina. Para el usuario, el proceso de implementación o representación es invisible.

Veamos entonces que son las estructuras de datos. Las estructuras de datos son colecciones de variables, no necesariamente del mismo tipo, relacionadas entre sí de alguna forma. Las estructuras de datos están caracterizadas por el tipo de dato de los elementos guardados en la estructura y por la relación definida sobre estos elementos.

Al nivel de las estructuras de datos son totalmente irrelevantes las operaciones sobre un elemento en particular, solamente tienen carácter relevante las operaciones que envuelvan la estructura de forma global.

Ejemplos de utilización de TDAs

Algunos ejemplos de utilización de TDAs en programación son:

Conjuntos: Implementación de conjuntos con sus operaciones básicas (unión, intersección y diferencia), operaciones de inserción, borrado, búsqueda...

Árboles Binarios de Busqueda: Implementación de árboles de elementos, utilizados para la representación interna de datos complejos.

Pilas y Colas: Implementación de los algoritmos FIFO y LIFO.