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;
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;
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.
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);
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