Seed7

Gli array

Eccoci ora ad affrontare una struttura dati molto utile e conosciuta, oltre che concettualmente abbastanza semplice Parliamo degli array. Si tratta della solita, nel senso che è così descritta in tutti i liguaggi a tipizzazione statica,  sequenza di elementi aventi tutti lo stesso tipo base e identificabili attraverso un indice costituito da un numero intero. L'accesso al singolo elemento è ottenuto per mezzo dell'operatore []. Diversamente da altri linguaggi è abbastanza facile usare elementi diversi da 0 come indice iniziale. Gli indici seguono la normale sequenza degli interi, senza salti. Tra l'altro, ma ne parleremo altrove, è possibile avere array con indice non numerico, evidentemente si tratta di qualche cosa di un po' diverso. La definizione di un array è molto semplice:

array tipo-base

è la forma per creare un array composto da elementi di un certo tipo. Ad esempio_

array integer

è la base per creare un array di interi. Ovviamente parziale. Esempi completi sono i seguenti:

var array integer: arr1 is 5 times 3
var array integer: arr2 is [] (1,2,3,4)


il primo esempio crea un array costituito da 5 elementi e tutti inizializzati con il numero 3. Il secondo presenta un array contenente i primi 4 numeri. Vediamo un esempio nel quale faremo uso anche di qualche funzione utile:

  Esempio 4.1
1
2
3
4
5
6
7
8
9
10
11
12
$ include "seed7_05.s7i";

const proc: main is func
local
var array integer: arr1 is 5 times 3;

begin
writeln(minIdx(arr1));
writeln(maxIdx(arr1));
writeln(length(arr1));
writeln(arr1[2]);
end func;

La riga 5 ci presenta il nostro array. E' interessante il sistema di inizializzazione quel "5 times", ovvero 5 volte. Piuttosto discorsivo, se vogliamo.
La riga 8 espone l'indice minimo, la 9 quello massimo, la 10 espone la lunghezza, ovvero il numero di elementi e la 10 estrae l'elemento avente indice 2. In questo caso l'ultima istruzione serve a poco, dato che tutti gli elementi sono uguali, per cui vediamo un ulteriore esempio che ci propone l'altra definizione di array:

  Esempio 4.2
1
2
3
4
5
6
7
8
9
10
11
$ include "seed7_05.s7i";
var array integer: arr1 is [] (1, 2, 3, 4);

const proc: main is func

begin
writeln(minIdx(arr1));
writeln(maxIdx(arr1));
writeln(length(arr1));
writeln(arr1[2]);
end func;

Il primo elemento di un array come creato negli esempi 4.1 e 4.2 ha indice 1, l'ultimo ha indice n, con n pari al numero di elementi. Se siamo nostalgici degli array 0 based possiamo ad esempio scrivere la riga 2 dell'esempio 4.2:

var array integer: arr1 is [0] (1, 2, 3, 4);

se vogliamo invece utilizzare la sintassi che fa uso di times, molto utile per inizializzazioni "massive" e vogliamo anche l'indice di partenza uguale a 0 possiamo fare così:

var array integer: arr1 is [0 .. 4] times 3;

questo formato permette anche di avere array con altri indici iniziali, basta cambiare la sequenza. Sono ammessi anche indici negativi:

var array integer: arr1 is [-1 .. 4] times 3;

Detto questo possiamo passare in analisi alcune funzioni utili per lavorare con gli array.

Abbiamo visto che accedere ad un singolo elemento di un array si fa grazie a [] (ad es. riga 10 dell'esempio 4.2). Come si fa per estrarre in stampa, o per altri scopi, tutti gli elementi? Attraverso il ciclo for, per esempio. Vediamo:

  Esempio 4.3
1
2
3
4
5
6
7
8
9
10
11
12
$ include "seed7_05.s7i";

const proc: main is func
local
var array integer: arr1 is [] (1,2,2,2,3,4,5);
var integer: x1 is 0;

begin
for x1 range 1 to length(arr1) do
  writeln(arr1[x1]);
end for;
end func;


Dal punto di vista della manipolazione degli array abbiamo già visto 3 funzioni, minIdx, maxIdx e length. Vediamone altre:

rand(A) estrae un elemento a caso dall'array A
remove(A, B) rimuove l'elemento avente indice B dall'array A
sort(A) ordina in senso crescente gli elementi dell'array A
insert(A,B,C)  inserisce l'elmento C nell'array A alla posizione B
insert(A, B)  inserisce B nell'array sortato A (ovvero: l'array deve essere già sortato altrimenti l'elemento viene inserito alla prima locazione che sembra adatta)
& appende un array ad un altro A := A & B appende B ad A e si può anche riscrivere come A &:= B

Detto questo vediamo un esempio con un paio di queste funzioni applicate:

  Esempio 4.4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ include "seed7_05.s7i";

const proc: main is func
local
var array integer: arr1 is [] (1,2,2,2,3,4,5);
var integer: x1 is 0;

begin
insert(arr1, 2, 8);
arr1 := sort(arr1);
for x1 range 1 to length(arr1) do
writeln(arr1[x1]);
end for;
end func;

In seed7 è possibile utilizzare anche i range:

[A .. B] permette di accedere ad un array dall'indice A all'indice B, estremi inclusi
[A .. ] accede ad un array dall'indice A alla fine
[ .. A] accede ad un array dall'inizio fino all'indice A

Esempio:

  Esempio 4.5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ include "seed7_05.s7i";

const proc: main is func
local
var array integer: arr1 is [] (1,2,2,2,3,4,5);
var array integer: arr2 is [] (0);
var integer: x1 is 0;
begin

arr2 := arr1[3 .. ];
for x1 range 1 to length(arr2) do
  writeln(arr2[x1]);
end for;
end func;


una domanda che ci si fa spesso è: come si fa la copia di due array? La risposta è ad esempio in questo frammento di codice:

var array integer: arr1 is [] (1,2,2,2,3,4,5);
var array integer: arr2 is [] (0);
begin
arr2 := arr1;

insomma: con la semplice assegnazione.

In tutte le operazioni riguardanti goi array ovviamente bisogna porre attenzione ai range. Lavorare fuori da quello corretto da orignire ad un eccezione quale:
EXCEPTION RANGE_ERROR