|
Array a una dimensione
Fino a questo momento abbiamo avuto a che fare con variabili "singole". Con questo voglio dire che ogni identificatore dichiarato puntava ad
una cella di memoria dove era contenuto un solo valore, leggibile e modificabile usando il nome specificato nella dichiarazione
della variabile. L'esempio classico che si fa in questo contesto è quello della scatola, dove una variabile viene, appunto, assimilata
ad una scatola, il cui contenuto può essere preso, modificato e reimmesso senza problemi.

Allo stesso modo, un array è un insieme di scatole, tutte una vicina all'altra (tanto nell'esempio quando nella posizione
fisica all'interno della memoria), a formare un'unica fila che per comodità si indica con un solo nome. Per distinguere ogni "scomparto"
si fa uso di un numero intero (che per convenzione è un intero a 32 bit, ossia Integer), detto indice. Tutti i linguaggi .NET
utilizzano sempre un indice a base 0: ciò significa che si inizia a contare da 0 anziché da 1:

La sintassi usata per dichiarare un array è simile a quella usata per dichiarare una singola variabile:
Dim [nome]([numero elementi - 1]) As [tipo]
La differenza tra le due risiede nelle parentesi tonde che vengono poste dopo il nome della variabile. Tra queste parentesi può anche
essere specificato un numero (sempre intero, ovviamente) che indica l'indice massimo a cui si può arrivare: dato che, come abbiamo
visto, gli indici sono sempre a base 0, il numero effettivo di elementi presenti nella collezione sarà di un'unità superiore
rispetto all'indice massimo. Ad esempio, con questo codice:
Dim A(5) As String
il programmatore indica al programma che la variabile A è un array contenente questi elementi:
A(0), A(1), A(2), A(3), A(4), A(5)
che sono per la precisione 6 elementi. Ecco un listato che esemplifica i concetti fin'ora chiariti:
Module Module1
Sub Main()
'Array che contiene 10 valori decimali, rappresentanti voti
Dim Marks(9) As Single
'Questa variabile terrà traccia di quanti voti
'l'utente avrà immesso da tastiera e permetterà di
'calcolarne una media
Dim Index As Int32 = 0
'Mark conterrà il valore temporaneo immesso
'da tastiera dall'utente
Dim Mark As Single
Console.WriteLine("Inserisci un altro voto (0 per terminare):")
Mark = Console.ReadLine
'Il ciclo finisce quando l'utente immette 0 oppure quando
'si è raggiunto l'indice massimo che è
'possibile usare per identificare una cella dell'array
Do While (Mark > 0) And (Index < 10)
'Se il voto immesso è maggiore di 0, lo memorizza
'nell'array e incrementa l'indice di 1, così da
'poter immagazzinare correttamente il prossimo voto nell'array
Marks(Index) = Mark
Index += 1
Console.WriteLine("Inserisci un altro voto (0 per terminare):")
Mark = Console.ReadLine
Loop
'Decrementa l'indice di 1, poiché anche se l'utente
'ha immesso 0, nel ciclo precedente, l'indice era stato
'incrementato prevedendo un'ulteriore immissione, che,
'invece, non c'è stata
Index -= 1
'Totale dei voti
Dim Total As Single = 0
'Usa un ciclo For per scorrere tutte le celle dell'array
'e sommarne i valori
For I As Int32 = 0 To Index
Total += Marks(I)
Next
'Mostra la media
Console.WriteLine("La tua media è: " & (Total / (Index + 1)))
Console.ReadKey()
End Sub
End Module
Il codice potrebbe non apparire subito chiaro a prima vista, ma attraverso uno sguardo più attento, tutto si farà più
limpido. Di seguito è scritto il flusso di elaborazione del programma ammettendo che l'utente immetta due voti:
- Richiede un voto da tastiera: l'utente immette 5 (Mark = 5)
- Mark è maggiore di 0
- Inserisce il voto nell'array: Marks(Index) = Marks(0) = 5
- Incrementa Index di 1: Index = 1
- Entrambe le condizioni non sono verificate: Mark <> 0 e Index < 9. Il ciclo continua
- Richiede un voto da tastiera: l'utente immette 10 (Mark = 10)
- Mark è maggiore di 0
- Inserisce il voto nell'array: Marks(Index) = Marks(1) = 10
- Incrementa Index di 1: Index = 2
- Entrambe le condizioni non sono verificate: Mark <> 0 e Index < 9. Il ciclo continua
- Richiede un voto da tastiera: l'utente immette 0 (Mark = 0)
- Mark è uguale a 0: il codice dentro if non viene eseguito
- Una delle condizioni di arresto è verificata: Mark = 0. Il ciclo termina
- Decrementa Index di 1: Index = 1
- Somma tutti i valori in Marks da 0 a Index (=1): Total = Marks(0) + Marks(1) = 5 + 10
- Visualizza la media: Total / (Index + 1) = 15 / (1 + 1) = 25 / 2 = 7.5
- Attende la pressione di un tasto per uscire
È anche possibile dichiarare ed inizializzare (ossia riempire) un array in una sola riga di codice. La sintassi usata è la
seguente:
Dim [nome]() As [tipo] = {elementi dell'array separati da virgole}
Ad esempio:
Dim Parole() As String = {"ciao", "mouse", "penna"}
Questa sintassi breve equivale a questo codice:
Dim Parole(2) As String
Parole(0) = "ciao"
Parole(1) = "mouse"
Parole(2) = "penna"
Un'ulteriore sintassi usata per dichiarare un array è la seguente:
Dim [nome] As [tipo]()
Quest'ultima, come vedremo, sarà particolarmente utile nel gestire il tipo restituito da una funzione.
Array a più dimensioni
Gli array a una dimensione sono contraddistinti da un singolo indice: se volessimo paragonarli ad un ente geometrico, sarebbero assimilabili
ad una retta, estesa in una sola dimensione, in cui ogni punto rappresenta una cella dell'array. Gli array a più dimensioni, invece,
sono contraddistinti da più di un indice: il numero di indici che identifica univocamente un elemento dell'array di dice rango.
Un array di rango 2 (a 2 dimensioni) potrà, quindi, essere paragonato a un piano, o ad una griglia di scatole estesa in lunghezza
e in larghezza. La sintassi usata è:
Dim [nome]( , ) As [tipo] 'array di rango 2
Dim [nome]( , , ) As [tipo] 'array di rango 3
Ecco un esempio che considera un array di rango 2 come una matrice quadrata:
Module Module1
Sub Main()
'Dichiara e inizializza un array di rango 2. Dato che
'in questo caso abbiamo due dimensioni, e non una sola,
'non si può specificare una semplice lista di
'valori, ma una specie di "tabella" a due entrate.
'Nell'esempio che segue, ho creato una semplice
'tabella a due righe e due colonne, in cui ogni cella
'è 0.
Dim M(,) As Single = _
{{0, 0}, _
{0, 0}}
'Bisogna notare il particolare uso delle graffe: si
'considera l'array di rango 2 come un array i cui
'elementi sono altri array
Console.WriteLine("Inserire gli elementi della matrice:")
For I As Int32 = 0 To 1
For J As Int32 = 0 To 1
Console.Write("Inserire l'elemento (" & I & ", " & J & "): ")
M(I, J) = Console.ReadLine
Next
Next
Dim Det As Single
Det = M(0, 0) * M(1, 1) - M(0, 1) * M(1, 0)
Console.WriteLine("Il determinante della matrice è: " & Det)
Console.ReadKey()
End Sub
End Module
Rappresentando graficamente l'array M, potremmo disegnarlo così:

Ma il computer lo può anche vedere in questo modo, come un array di array:

Come si vede dal codice di inizializzazione, seppur concettualmente diversi, i due modi di vedere un array sono compatibili. Tuttavia,
bisogna chiarire che solo e soltanto in questo caso, le due visioni sono conciliabili, poiché un array di rango 2 e un array di
array sono, dopo tutto, due entità ben distinte. Infatti, esiste un modo per dichiarare array di array, come segue:
Dim [nome]()() As [tipo] 'array di array
E se si prova a fare una cosa del genere:
Dim A(,) As Int32
Dim B()() As Int32
'...
A = B
Si riceve un errore esplicito da parte del compilatore.
Ridimensionare un array
Può capitare di dover modificare la lunghezza di un array rispetto alla dichiarazione iniziale. Per fare questo, si usa la parola riservata
ReDim, da non confondere con la keyword Dim: hanno due funzioni totalmente differenti. Quando si ridimensiona un array, tutto il suo contenuto
viene cancellato: per evitare questo inconveniente, si deve usare l'istruzione ReDim Preserve, che tuttavia ha prestazioni molto
scarse a causa dell'eccessiva lentezza. Entrambe le istruzioni derivano dal Visual Basic classico e non fanno parte, pertanto, della sintassi
.NET, sebbene continuino ad essere molto usate, sia per comodità, sia per abitudine. Il metodo più corretto da adottare
consiste nell'usare la procedura Array.Resize. Eccone un esempio:
Module Module1
Sub Main()
Dim A() As Int32
Dim n As Int32
Console.WriteLine("Inserisci un numero")
n = Console.ReadLine
'Reimposta la lunghezza di a ad n elementi
Array.Resize(A, n)
'Calcola e memorizza i primi n numeri pari (zero compreso)
For I As Int16 = 0 To n - 1
A(I) = I * 2
Next
Console.ReadKey()
End Sub
End Module
La riga Array.Resize(A, n) equivale, usando ReDim a:
ReDim A(n - 1)
Per ridimensionare un array a più dimensioni, la faccenda si fa abbastanza complessa. Per prima cosa, non si può utilizzare
Array.Resize a meno che non si utilizzi un array di array, ma anche in quel caso le cose non sono semplici. Infatti, è possibile
stabilire la lunghezza di una sola dimensione alla volta. Ad esempio, avendo un array M di rango 2 con nove elementi, raggruppati in 3 righe
e 3 colonne, non si può semplicemente scrivere:
ReDim M(2, 2)
perchè, così facendo, solo la riga 2 verrà ridimensionata a 3 elementi, mentre la 0 e la 1 saranno vuote. Il codice da
usare, quindi, è:
ReDim M(0, 2)
ReDim M(1, 2)
ReDim M(2, 2)
In questo modo, ogni "riga" viene aggiustata alla lunghezza giusta.
|
|