Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
Guida al Visual Basic .NET - Gli Array Parte I

Guida al Visual Basic .NET

Capitolo 11° - Gli Array Parte I

<< Precedente Prossimo >>

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.

BoxVariable.jpg
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:

BoxArray.jpg
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 &egrave: " & (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 &egrave: " & Det)

        Console.ReadKey()
    End Sub
End Module 
Rappresentando graficamente l'array M, potremmo disegnarlo così:

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

ArrayOfArrays.jpg
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.


<< Precedente Prossimo >>
A proposito dell'autore

Programmatore e analista .NET 2005/2008/2010 (in particolare C# e VB.NET), anche nell'implementazione Mono per Linux. Conoscenze approfondite di Pascal, PHP, XML, HTML 4.01/5, CSS 2.1/3, Javascript (e jQuery). Conoscenze buone di C, LUA, GML, Ruby, XNA, AJAX e Assembly 68000. Competenze basilari di C++, SQL, Hlsl, Java.