Anterior | Superior | Siguiente

Guía de referencia básica de Ada 95

Punteros

Declaración.

Los punteros (access) constituyen el tipo de datos con el que se representan direcciones de memoria; su uso más habitual es para construir estructuras de datos complejas utilizando variables ubicadas dinámicamente. Como Ada es un lenguaje fuertemente tipado la declaración de una variable puntero se hace utilizando la palabra reservada access y requiere que se especifique el tipo de datos que el mismo va a poder referenciar.

type T_Persona is record
  Nombre: string(1..30);
  D_N_I: string(1..9);
end record;
--tipo puntero a variables dinámicas de tipo Integer
type P_Int is access Integer;
--tipo puntero a variables dinámicas de tipo T_Persona
type P_Persona is access T_Persona;
--tipo puntero a un puntero dinámico
type P_Punt is access P_Int;
--variables puntero a variables dinámicas de tipo Integer
Punt1, Punt2: P_Int;
--variables puntero a variables dinámicas de tipo T_Persona
Punt3, Punt4: P_Persona;
--variable puntero a un puntero dinámico
Punt5: P_Punt;

Si se quiere que un puntero pueda referenciar también variables declaradas, hay que especificarlo en su definición usando la palabra all.

type P_Tot_Int is access all Integer;
--Las variables de tipo P_Tot_Int pueden referenciar
--variables de tipo Integer, tanto declaradas como dinámicas
Punt6 : P_Tot_Int;

Usar punteros para referenciar variables declaradas es peligroso ya que supone la creación de un alias, por ello sólo se puede asignar a una variable puntero la dirección de una variable declarada que lo permita explícitamente (incluyendo la palabra aliased en su declaración).

I: Integer; --la dirección de I no se puede asignar a un puntero
J: aliased Integer;--la dirección de J se puede asignar a un puntero;

El problema de los alias se puede minimizar declarando el puntero de forma que aquello a lo que apunta se considere constante, no puede modificarse a través del puntero; ello, además, permite que a un puntero se le puedan asignar direcciones de constantes, no sólo de variables.

type P_Int_Const is access constant Integer;

Asignación de valores.

La forma más habitual de asignar un valor válido a un puntero es dándole la dirección de una variable dinámica creada con la operación new.

Punt1 := new Integer;

También se le puede asignar una dirección válida almacenada en otro puntero (aunque ello crea un alias).

Punt2 := Punt1;

Si ha sido declarado "all" se le puede también asignar la dirección de una variable "aliased", usando el atributo "access" propio de éstas.

Punt6 := J'access; --correcto;
Punt6 := I'access; --incorrecto;

Si ha sido declarado "constant" se le podrá asignar además la dirección de una constante.

En cualquier caso a todo puntero se le puede asignar el valor null que representa "ninguna dirección"; en Ada los punteros se inicializan con este valor cuando se declaran, a menos que dicha declaración incluya una inicialización diferente.

Acceso a las variables referenciadas por punteros.

Para acceder al contenido de una variable puntero se utiliza su nombre, como con cualquier otro tipo de variables; para acceder a la variable representada por la dirección contenida en el puntero se utiliza el cualificador .all.

Punt1 := Punt2; --asigna puntero a puntero
J := Punt1.all; --asigna Integer a Integer
Punt6 := J'access; --asigna la dirección de J a puntero
Punt6.all := I; --asigna Integer a Integer

Si la variable referenciada es de tipo record se puede acceder a cada campo con el cualificador .all.nombre_campo o abreviado . nombre_campo.

Punt3.all.D_N_I := "12345678D";
Punt3.D_N_I := "12345678D";

Si es un array se pueden aplicar los índices al cualificador . all o, directamente, para acceder a los elementos individuales.

type T_Vec is array (Integer range <>) of Integer;
type P_Vec is access T_Vec;
V : P_Vec := new T_Vec'(1,2,3,4,5);
...
I := V(3);

Estructuras recursivas con punteros.

Una aplicación frecuente de los punteros es la creación de estructuras de datos dinámicas, por ejemplo, listas encadenadas. Este tipo de estructuras están formadas por un conjunto de nodos conectados mediante campos de enlace que son punteros a nodos del mismo tipo. Para estos nodos sería necesaria una definición de tipo tal como:

type Nodo_Lista is record
   Info: Integer;
   Siguiente: P_Nodo_Lista;
end record;

donde P_Nodo_Lista es el tipo de los punteros a objetos de tipo Nodo_Lista. Esto significa que debería existir una definición para P_Nodo_Lista:

type P_Nodo_Lista is access Nodo_Lista;

Esta definición debería estar antes que la de Nodo_Lista, para que sea conocida cuando se declara el campo siguiente de éste; pero entonces Nodo_Lista no se conocería cuando se intenta definir P_Nodo_Lista, creándose un círculo vicioso. La solución consiste en empezar con una declaración incompleta de Nodo_Lista que establezca que tal tipo va a existir, pero sin concretarlo, cosa que debe hacerse más adelante en la misma región del programa:

type Nodo_Lista;
type P_Nodo_Lista is access Nodo_Lista;
type Nodo_Lista is record
   Info: Integer;
   Siguiente: P_Nodo_Lista;
end record;

© Grupo de Estructuras de Datos y Lingüística Computacional - ULPGC.

Anterior | Superior | Siguiente