Declaración de arrays
Los arrays de Ada son de alto nivel, comparados, por ejemplo, con los de C/C++. Esto se traduce en varias posibilidades sintácticas que se presentan a continuación.
Sintáxis básica
La declaración básica de un array es la siguiente:
array∞ (Tipo_Índice)
of∞ Tipo_Elemento
Este array consiste en un elemento de tipo
Tipo_Elemento por cada posible valor de Tipo_Índice. Por ejemplo, si quisieramos contar las ocurrencias de cada letra en un texto nos definiríamos un array de este tipo:
type∞ Contador_Caracteres
is∞ array∞ (Character)
of∞ Natural;
Nota: usamos Natural como tipo de elemento puesto que los valores negativos de Integer no tienen sentido en una cuenta. Es conveniente usar el subtipo entero más adecuado en cada caso, puesto que así nos beneficiamos de la comprobación de rango y podemos descubrir errores fácilmente.
Con subrango conocido
A menudo no necesitamos un array con todos los valores posibles del tipo del índice. En este caso definimos un
subtipo∞ del tipo índice con el rango necesitado.
subtype∞ Subtipo_Índice
is∞ Tipo_Índice
range∞ Primero ... Último;
array∞ (Subtipo_Índice)
of∞ Tipo_Elemento;
Para lo que hay una forma más abreviada si no deseamos definir el subtipo con nombre, se puede hacer anónimamente:
array∞ (Tipo_Índice
range∞ Primero ... Último)
of∞ Tipo_Elemento;
Puesto que Primero y Último son expresiones del tipo Tipo_Índice, una forma más simple es la siguiente:
array∞ (Primero ... Último)
of∞ Tipo_Elemento
Ten en cuenta que si First y Last son literales numéricos, esto implica que el tipo índice base es el Integer.
Si en el ejemplo anterior, sólo deseasemos contar letras mayúsculas desechando otros caracteres, podríamos definir el tipo array de este modo:
type∞ Contador_Caracteres
is∞ array∞ (Character
range∞ 'A' .. 'Z')
of∞ Natural;
Con un subrango desconocido
A menudo el rango necesitado no se conoce hasta tiempo de ejecución o necesitamos
objetos∞ array de varias longitudes. En lenguajes de más bajo nivel como
C∞ necesitaríamos hacer uso de la memoria dinámica (del
heap). Pero no es el caso de Ada, puesto que la caja
<> nos permite declarar arrays de tamaño no restringido:
array∞ (Tipo_Índice
range∞ <>)
of∞ Tipo_Elemento
Cuando declaramos objetos de este tipo, los extremos (
bounds) del array deben conocerse, bien como resultado de una función o por una inicialización mediante un agregado. Desde su declaración hasta su finalización, el objeto no puede cambiar de tamaño.
Con elementos aliased
Los programadores de C/C++ dan por hecho que todo elemento de un array tiene una dirección propia en memoria (de hecho el nombre del array es un puntero sobre el que se puede operar).
En Ada, esto no es siempre así. Veamos este ejemplo:
type∞ Día_De_Mes
is∞ range∞ 1 .. 31;
type∞ Día_Con_Cita
is∞ array∞ (Día_De_Mes)
of∞ Boolean;
pragma∞ Pack∞ (Día_Con_Cita);
Puesto que hemos empaquetado el array, el compilador usará el mínimo espacio de almacenamiento posible. En la mayoría de los casos esto implica que los 8 valores booleanos cabrán en un byte.
Pero este no es el único caso en el que el compilador de Ada puede empaquetar un array puesto que tiene libertad en los casos en que sea más optimo.
Si queremos acceder con un
puntero∞ a cada elemento tenemos que expresarlo explícitamente.
type∞ Día_De_Mes
is∞ range∞ 1 .. 31;
type∞ Día_Con_Cita
is∞ array∞ (Día_De_Mes)
of∞ aliased∞ Boolean;
Uso de arrays
Para acceder a los elementos de un array se usan el nombre del objeto array seguido del índice entre paréntesis.
Se puede acceder a una rodaja (
slice) de un array usando (x .. y).
Vector_A (1 .. 3) := Vector_B (4 .. 6);
El operador "&" permite concatenar arrays:
Nombre_Completo := Nombre & ' ' & Apellidos;
Si se intenta acceder a un elemento más alla de los límites del array o se asigna a un array (completo o slice) un array de distinto tamaño se levanta la
excepción∞ Constraint_Error (a menos que los chequeos estén deshabilitados).
Ejemplo de uso
with∞ Ada.Text_IO, Ada.Integer_Text_IO;
use∞ Ada.Text_IO, Ada.Integer_Text_IO;
procedure∞ Agenda
is∞
type∞ Día_De_Mes
is∞ range 1 .. 31;
type∞ Día_Con_Cita
is∞ array (Día_De_Mes)
of∞ Boolean;
Citas_En_Mayo : Día_Con_Cita := (
others∞ => False);
-- Se inicializa todo el mes a False
begin∞
-- Tengo citas los días 3, del 8 al 16 (excepto el 14), y el último día del mes.
Citas_En_Mayo (3) := True;
Citas_En_Mayo (8 .. 16) := (
others∞ => True);
Citas_En_Mayo (14) := False;
Citas_En_Mayo (Citas_En_Mayo'Last) := True;
Put ("En mayo tienes citas los días:");
for∞ I
in∞ Citas_En_Mayo'Range
loop∞
if∞ Citas_En_Mayo (I)
then∞
Put (Día_De_Mes'Image (I));
end∞ if∞;
end∞ loop∞;
end∞ Agenda;