Condividi tramite


Matrici in Visual Basic

Una matrice è costituita da un insieme di valori logicamente correlati tra loro, ad esempio il numero degli studenti iscritti a ciascun anno scolastico di una scuola elementare.

Una matrice consente di fare riferimento a tali valori correlati mediante lo stesso nome e di utilizzare un numero, denominato indice, per distinguere i valori. I singoli valori sono denominati elementi della matrice e sono contigui dall'indice 0 fino al massimo valore di indice.

A differenza di una matrice, una variabile contenente un singolo valore è denominata variabile scalare.

Esempio

Nell'esempio riportato di seguito viene dichiarata una variabile di matrice che deve contenere il numero degli studenti iscritti a ciascun anno scolastico di una scuola elementare.

Dim students(6) As Integer

La matrice students dell'esempio precedente contiene 7 elementi. Gli indici degli elementi sono compresi tra 0 e 6. L'utilizzo di questa matrice è più semplice rispetto alla dichiarazione di 7 variabili diverse.

Nella seguente figura è indicata la matrice students. Per ciascun elemento della matrice:

  • L'indice dell'elemento rappresenta l'anno scolastico (l'indice 0 rappresenta l'asilo).

  • Il valore contenuto nell'elemento rappresenta il numero degli studenti iscritti a tale anno scolastico.

Elementi della matrice "students"

Immagine di matrice che illustra il numero di studenti

Nell'esempio riportato di seguito viene illustrato come fare riferimento al primo, al secondo e all'ultimo elemento della matrice students.

Dim kindergarten As Integer = students(0)
Dim firstGrade As Integer = students(1)
Dim sixthGrade As Integer = students(6)
MsgBox("Students in kindergarten = " & CStr(kindergarten))
MsgBox("Students in first grade = " & CStr(firstGrade))
MsgBox("Students in sixth grade = " & CStr(sixthGrade))

Per fare riferimento all'intera matrice è sufficiente utilizzare il nome della variabile di matrice senza indici.

Dimensioni delle matrici

La matrice students nell'esempio precedente utilizza un unico indice ed è quindi detta unidimensionale. Una matrice che utilizza più indici è detta multidimensionale. Per ulteriori informazioni, vedere Dimensioni di matrice in Visual Basic.

Una matrice nella quale gli elementi sono costituiti da altre matrici è detta matrice di matrici o matrice irregolare. Una matrice irregolare può essere unidimensionale o multidimensionale, come anche i relativi elementi. In alcuni casi, i dati nell'applicazione hanno una struttura bidimensionale ma non rettangolare. È possibile, ad esempio, che sia presente una matrice di mesi, in cui ogni elemento della matrice è costituito da una matrice di giorni. Poiché il numero di giorni varia a seconda del mese, gli elementi non costituiscono una matrice bidimensionale rettangolare. In tal caso, è possibile utilizzare una matrice irregolare anziché una matrice multidimensionale.

Dichiarazione di una matrice

Analogamente alle altre variabili, le variabili di matrici vengono dichiarate mediante l'istruzione Dim. Il nome della variabile è seguito da una o più coppie di parentesi per indicare che contiene una matrice e non una variabile scalare, ovvero che non si tratta di una variabile contenente un unico valore.

Per dichiarare una variabile di matrice unidimensionale, aggiungere una coppia di parentesi dopo il nome della variabile.

Dim cargoWeights() As Double

Per dichiarare una variabile di matrice multidimensionale, aggiungere una coppia di parentesi dopo il nome della variabile e inserire virgole all'interno delle parentesi per separare le dimensioni.

Dim atmospherePressures(,,,) As Short

Per dichiarare una variabile di matrice di matrici, aggiungere, dopo il nome della variabile, il numero di coppie di parentesi corrispondente ai livelli di matrici annidate.

Dim inquiriesByYearMonthDay()()() As Byte

Negli esempi precedenti vengono dichiarate variabili di matrice, ma non vi vengono assegnate matrici. È quindi necessario creare una matrice, inizializzarla e assegnarla alla variabile.

Matrici di lunghezza zero

Una matrice senza elementi viene definita anche matrice di lunghezza zero. Il valore di una variabile che contiene una matrice di lunghezza zero non è Nothing. Per creare una matrice che non dispone di elementi, dichiarare una delle dimensioni della matrice come -1, come illustrato nell'esempio seguente.

Dim twoDimensionalStrings(-1, 3) As String

Potrebbe essere necessario creare una matrice di lunghezza zero nelle seguenti circostanze:

  • È necessario che il codice acceda ai membri della classe Array, quali Length o Rank oppure chiami una funzione di Visual Basic come UBound, senza il rischio che venga generata un'eccezione NullReferenceException.

  • Si desidera che il codice che la utilizza rimanga più leggibile senza che sia necessario verificare la presenza di Nothing come caso particolare.

  • Il codice interagisce con un'API che richiede il passaggio di una matrice di lunghezza zero a una o più routine oppure che restituisce una matrice di lunghezza zero da una o più routine.

Creazione di una matrice

È possibile creare una matrice in due modi. È possibile fornire la dimensione di una matrice quando viene dichiarata, oppure, poiché una matrice è un oggetto, è possibile crearla con una clausola Operatore New (Visual Basic) e assegnarla alla variabile di matrice. È possibile eseguire questa operazione come parte della dichiarazione di matrice o in un'istruzione di assegnazione successiva, come illustrato nell'esempio seguente.

cargoWeights = New Double() {}
atmospherePressures = New Short(,,,) {}
inquiriesByYearMonthDay = New Byte()()() {}

Dopo l'esecuzione di queste istruzioni, le matrici hanno una lunghezza pari a 0.

Nota

La clausola New deve specificare il nome del tipo, seguito da parentesi tonde, quindi da parentesi graffe ({}). Le parentesi tonde non rappresentano una chiamata a un costruttore di matrici ma indicano che il tipo di oggetto è un tipo di matrice. All'interno delle parentesi graffe è possibile specificare i valori di inizializzazione. Il compilatore richiede le parentesi graffe anche se non viene fornito alcun valore. La clausola New deve pertanto includere sia le parentesi tonde che le parentesi graffe, anche se non contengono valori. Se si escludono le parentesi graffe, il compilatore presuppone che si stia chiamando il costruttore per il tipo specificato.

È possibile definire la dimensione di una matrice in molti modi diversi. È possibile specificare la dimensione quando la matrice viene dichiarata, come illustrato nell'esempio seguente.

Dim cargoWeights(10) As Double
Dim atmospherePressures(2, 2, 4, 10) As Short
Dim inquiriesByYearMonthDay(20)()() As Byte

È inoltre possibile specificare la dimensione di una matrice quando viene creata utilizzando una clausola New, come illustrato nell'esempio seguente.

cargoWeights = New Double(10) {}
atmospherePressures = New Short(2, 2, 4, 10) {}
inquiriesByYearMonthDay = New Byte(20)()() {}

Se si dispone di una matrice esistente, è possibile ridefinirne la dimensione tramite l'istruzione Redim. È possibile specificare che l'istruzione Redim mantenga i valori attualmente archiviati nella matrice oppure è possibile specificare la creazione di una nuova matrice vuota. Nell'esempio seguente vengono illustrati diversi tipi di utilizzo dell'istruzione Redim per modificare la dimensione di una matrice esistente.

' Assign a new array size and retain the current element values.
ReDim Preserve cargoWeights(20)
' Assign a new array size and retain only the first five element values.
ReDim Preserve cargoWeights(4)
' Assign a new array size and discard all current element values.
ReDim cargoWeights(15)

Per ulteriori informazioni, vedere Istruzione ReDim (Visual Basic).

Popolamento di una matrice con valori iniziali

È possibile creare una matrice contenente un set iniziale di valori utilizzando un valore letterale di matrice. Un valore letterale di matrice è costituito da un elenco di valori delimitati da virgole racchiusi tra parentesi graffe ({}).

Quando si crea una matrice utilizzando un valore letterale di matrice, è possibile specificare il tipo di matrice o utilizzare l'inferenza del tipo per determinare il tipo di matrice. Entrambe le opzioni sono illustrate nel codice seguente.

Dim numbers = New Integer() {1, 2, 4, 8}
Dim doubles = {1.5, 2, 9.9, 18}

Quando si utilizza l'inferenza del tipo, il tipo della matrice è determinato dal tipo dominante nell'elenco di valori fornito per il valore letterale di matrice. Il tipo dominante è un tipo univoco in cui tutti gli altri tipi nel valore letterale della matrice possono ampliarsi. Se questo tipo univoco non può essere determinato, il tipo dominante è il tipo univoco in cui possono restringersi tutti gli altri tipi nella matrice. Se nessuno di questi tipi univoci può essere determinato, il tipo dominante è Object. Se, ad esempio, l'elenco di valori fornito al valore letterale di matrice contiene valori di tipo Integer, Long e Double, la matrice risultante è di tipo Double. Sia Integer che Long possono ampliarsi nel tipo Double e solo Double. Double è pertanto il tipo dominante. Per ulteriori informazioni, vedere Conversioni di ampliamento e restrizione (Visual Basic). Queste regole di inferenza si applicano ai tipi dedotti per le matrici che sono variabili locali definite in un membro di classe. Sebbene sia possibile utilizzare valori letterali della matrice quando si creano variabili a livello di classe, non è possibile utilizzare l'inferenza del tipo a livello di classe. Di conseguenza, i valori letterali della matrice specificati a livello di classe consentono di dedurre i valori forniti per il valore letterale di matrice come tipo Object.

È possibile specificare in modo esplicito il tipo degli elementi in una matrice creata utilizzando un valore letterale di matrice. In questo caso, i valori nel valore letterale di matrice devono potersi ampliare al tipo degli elementi della matrice. Nell'esempio di codice seguente viene creata una matrice di tipo Double da un elenco di Integer.

Dim values As Double() = {1, 2, 3, 4, 5, 6}

Valori letterali della matrice annidati

È possibile creare una matrice multidimensionale tramite valori letterali della matrice annidati. I valori letterali della matrice annidati devono disporre di una dimensione e di un numero di dimensioni, o rango, coerente con la matrice risultante. Nell'esempio di codice seguente viene creata una matrice bidimensionale di Integer tramite un valore letterale di matrice.

Dim grid = {{1, 2}, {3, 4}}

Nell'esempio precedente verrebbe generato un errore nel caso in cui il numero di elementi nei valori letterali della matrice annidati non corrispondesse. Verrebbe inoltre generato un errore anche se la variabile di matrice venisse dichiarata in modo esplicito come tipo diverso da bidimensionale.

Nota

È possibile evitare un errore quando si specificano valori letterali della matrice annidati di dimensioni diverse racchiudendo i valori letterali della matrice interni tra parentesi. Le parentesi forzano la valutazione dell'espressione del valore letterale di matrice e i valori risultanti vengono utilizzati con il valore letterale di matrice esterno, come illustrato nel codice che segue.

Dim values = {({1, 2}), ({3, 4, 5})}

Quando si crea una matrice multidimensionale tramite valori letterali della matrice annidati, è possibile utilizzare l'inferenza del tipo. Quando si utilizza l'inferenza del tipo, il tipo dedotto è il tipo dominante per tutti i valori in tutti i valori letterali della matrice per un livello di annidamento. Nell'esempio di codice seguente viene creata una matrice bidimensionale di tipo Double da valori di tipo Integer e Double.

Dim a = {{1, 2.0}, {3, 4}, {5, 6}, {7, 8}}

Per ulteriori esempi, vedere Procedura: inizializzare variabili di matrice in Visual Basic.

Archiviazione di valori in una matrice

È possibile accedere a ogni posizione in una matrice utilizzando un indice di tipo Integer. È possibile archiviare e recuperare i valori in una matrice facendo riferimento a ogni posizione della matrice utilizzando il relativo indice racchiuso tra parentesi. Gli indici per le matrici multidimensionali sono separati da virgole (,). È necessario un indice per ogni dimensione della matrice. Nell'esempio riportato di seguito vengono illustrate alcune istruzioni che consentono di inserire valori nelle matrici.

Dim i = 4
Dim j = 2

Dim numbers(10) As Integer
Dim matrix(5, 5) As Double

numbers(i + 1) = 0
matrix(3, j * 2) = j

Nell'esempio riportato di seguito vengono illustrate alcune istruzioni che consentono di ottenere valori dalle matrici.

Dim v = 2
Dim i = 1
Dim j = 1
Dim k = 1
Dim wTotal As Double = 0.0
Dim sortedValues(5), rawValues(5), estimates(2, 2, 2) As Double
Dim lowestValue = sortedValues(0)
wTotal += (rawValues(v) ^ 2)
Dim firstGuess = estimates(i, j, k)

Per ciascuna dimensione della matrice, il metodo GetUpperBound restituisce il valore dell'indice più alto possibile. Il valore più basso dell'indice è sempre 0.

Dimensione della matrice

La dimensione di una matrice è il prodotto delle lunghezze di tutte le relative dimensioni e rappresenta il numero totale di elementi attualmente contenuti nella matrice.

Nell'esempio riportato di seguito viene dichiarata una matrice tridimensionale.

Dim prices(3, 4, 5) As Long

La dimensione complessiva della matrice nella variabile prices è pari a (3 + 1) x (4 + 1) x (5 + 1) = 120.

È possibile determinare la dimensione di una matrice utilizzando la proprietà Length. È possibile determinare la lunghezza di ogni dimensione di una matrice multidimensionale utilizzando il metodo GetLength.

È possibile ridimensionare una variabile di matrice assegnando un nuovo oggetto matrice oppure utilizzando l'istruzione ReDim.

Di seguito sono indicati alcuni elementi importanti relativi alla dimensione di una matrice.

Lunghezza delle dimensioni

L'indice di ciascuna dimensione è compreso tra 0 e il relativo limite superiore. Pertanto, la lunghezza di una data dimensione è maggiore di 1 rispetto al limite superiore dichiarato di tale dimensione.

Limiti di lunghezza

La lunghezza di ciascuna dimensione di una matrice è limitata al valore massimo del tipo di dati Integer, ovvero (2 ^ 31) - 1. Tuttavia, la dimensione totale di una matrice è limitata anche dalla memoria disponibile sul sistema. Se si tenta di inizializzare una matrice che supera la quantità di RAM disponibile, Common Language Runtime genera un'eccezione OutOfMemoryException.

Dimensione ed elementi della matrice

La dimensione di una matrice è indipendente dal tipo di dati dei relativi elementi. La dimensione rappresenta sempre il numero totale di elementi e non il numero di byte necessari per l'archiviazione di tali elementi.

Consumo di memoria

Non è possibile fare ipotesi sulla modalità di archiviazione di una matrice in memoria. L'archiviazione dipende dalla larghezza dei dati delle diverse piattaforme, Di conseguenza, è possibile che l'archiviazione di una stessa matrice richieda più memoria in un sistema a 64 bit che in un sistema a 32 bit. A seconda della configurazione di sistema al momento dell'inizializzazione di una matrice, Common Language Runtime può assegnare la memoria in modo da compattare al massimo gli elementi oppure in modo da allinearli tutti in base ai limiti dell'hardware. Una matrice, inoltre, richiede un sovraccarico di archiviazione per le relative informazioni di controllo e tale sovraccarico aumenta con ogni dimensione aggiunta.

Tipi di matrice e altri tipi

Tipi di dati

Ogni matrice dispone di un tipo di dati, diverso da quello dei relativi elementi. Non esiste un singolo tipo di dati per tutte le matrici. Il tipo di dati di una matrice viene invece determinato dal numero di dimensioni, o rango, della matrice e dal tipo di dati degli elementi nella matrice. Due variabili di matrice hanno lo stesso tipo di dati solo se hanno lo stesso numero di dimensioni e i relativi elementi includono lo stesso tipo di dati. La lunghezza delle dimensioni in una matrice non influisce sul tipo di dati della matrice.

Ogni matrice eredita dalla classe System.Array. È possibile dichiarare una variabile di tipo Array, ma non è possibile creare una matrice di tipo Array. Inoltre, l'Istruzione ReDim (Visual Basic) non è in grado di operare su una variabile dichiarata di tipo Array. Per questi motivi, e per garantire l'indipendenza dai tipi, si consiglia di dichiarare ogni matrice con un tipo specifico, ad esempio Integer nell'esempio precedente.

E' possibile determinare il tipo di dati di una matrice o dei relativi elementi in diversi modi.

  • È possibile chiamare il metodo Object.GetType sulla variabile per ricevere un oggetto Type per il tipo della variabile in fase di esecuzione. Nelle proprietà e nei metodi dell'oggetto Type sono presenti informazioni complete.

  • È possibile passare la variabile alla funzione TypeName per ricevere un oggetto String contenente il nome del tipo in fase di esecuzione.

  • È possibile passare la variabile alla funzione VarType per ricevere un valore VariantType che rappresenta la classificazione del tipo della variabile.

Nell'esempio seguente viene chiamata la funzione TypeName per determinare il tipo della matrice e il tipo degli elementi nella matrice. Il tipo di matrice è Integer(,) e gli elementi nella matrice sono di tipo Integer.

Dim thisTwoDimArray(,) As Integer = New Integer(9, 9) {}
MsgBox("Type of thisTwoDimArray is " & TypeName(thisTwoDimArray))
MsgBox("Type of thisTwoDimArray(0, 0) is " & TypeName(thisTwoDimArray(0, 0)))

Insiemi come alternativa alle matrici

Sebbene vengano in genere utilizzati con il Tipo di dati Object, gli insiemi possono essere utilizzati con qualsiasi tipo di dati. In alcuni casi può risultare più efficace archiviare elementi in un insieme anziché in una matrice.

Se occorre modificare la dimensione di una matrice, è necessario utilizzare l'Istruzione ReDim (Visual Basic). In questo modo, in Visual Basic viene creata una nuova matrice e la matrice precedente viene rilasciata per l'eliminazione. Questa operazione causa un aumento del tempo di esecuzione. Di conseguenza, se il numero degli elementi utilizzati cambia spesso, oppure non è possibile prevedere il numero massimo di elementi necessari, è preferibile utilizzare un insieme per ottenere prestazioni migliori.

Il ridimensionamento di un insieme, per il quale non è necessario creare un nuovo oggetto né copiare elementi esistenti, richiede un tempo di esecuzione inferiore rispetto a quello di una matrice, per la quale è necessario utilizzare l'istruzione ReDim. Tuttavia, se la dimensione della matrice rimane invariata o cambia solo raramente, è probabile che l'utilizzo di una matrice garantisca prestazioni migliori. Come sempre, le prestazioni dipendono principalmente dalla specifica applicazione. È quindi consigliabile effettuare alcune prove utilizzando sia una matrice che un insieme.

Insiemi specializzati

In .NET Framework sono inoltre disponibili diverse classi, interfacce e strutture per insiemi generali e speciali. Gli spazi dei nomi System.Collections e System.Collections.Specialized contengono definizioni e implementazioni che includono dizionari, elenchi, code e stack. Lo spazio dei nomi System.Collections.Generic fornisce molte di esse in versioni generiche, che accettano uno o più argomenti di tipo.

Se l'insieme deve contenere elementi appartenenti a un unico tipo di dati, un insieme generico offre il vantaggio di imporre l'indipendenza dai tipi. Per ulteriori informazioni sui generics, vedere Tipi generici in Visual Basic (Visual Basic).

Insiemi specializzati

In .NET Framework sono inoltre disponibili diverse classi, interfacce e strutture per insiemi generali e speciali. Gli spazi dei nomi System.Collections e System.Collections.Specialized contengono definizioni e implementazioni che includono dizionari, elenchi, code e stack. Lo spazio dei nomi System.Collections.Generic fornisce molte di esse in versioni generiche, che accettano uno o più argomenti di tipo.

Se l'insieme deve contenere elementi appartenenti a un unico tipo di dati, un insieme generico offre il vantaggio di imporre l'indipendenza dai tipi. Per ulteriori informazioni sui generics, vedere Tipi generici in Visual Basic (Visual Basic).

Esempio

Nell'esempio seguente viene utilizzata la classe generica System.Collections.Generic.List<T> .NET Framework per creare un insieme di oggetti Customer.

' Define the class for a customer.
Public Class Customer
    Public Property Name As String
    ' Insert code for other members of customer structure.
End Class

' Create a module-level collection that can hold 200 elements.
Public CustomerList As New List(Of Customer)(200)

' Add a specified customer to the collection.
Private Sub AddNewCustomer(ByVal newCust As Customer)
    ' Insert code to perform validity check on newCust.
    CustomerList.Add(newCust)
End Sub

' Display the list of customers in the Debug window.
Private Sub PrintCustomers()
    For Each cust As Customer In CustomerList
        Debug.WriteLine(cust)
    Next cust
End Sub

La dichiarazione dell'insieme CustomerFile specifica che l'insieme può contenere soltanto elementi di tipo Customer e definisce inoltre una capacità iniziale di 200 elementi. La routine AddNewCustomer controlla la validità del nuovo elemento e quindi lo aggiunge all'insieme. La routine PrintCustomers utilizza un ciclo For Each per attraversare l'insieme e visualizzarne gli elementi.

Argomenti correlati

Argomento

Definizione

Dimensioni di matrice in Visual Basic

Vengono illustrati il numero di dimensioni e le dimensioni delle matrici.

Procedura: inizializzare variabili di matrice in Visual Basic

Viene descritto come popolare le matrici con valori iniziali.

Procedura: invertire il contenuto di una matrice in Visual Basic

Viene illustrato come invertire l'ordine degli elementi di una matrice.

Procedura: ordinare una matrice in Visual Basic

Viene illustrato come ordinare alfabeticamente gli elementi di una matrice.

Procedura: assegnare una matrice a un'altra matrice (Visual Basic)

Vengono descritte regole e passaggi per l'assegnazione di una matrice a un'altra variabile di matrice.

Procedura: cambiare una matrice in una matrice differente (Visual Basic)

Viene illustrato quali sono le modifiche possibili e come compierle.

Procedura: passare una matrice a una proprietà o a una routine (Visual Basic)

Viene illustrato come passare una matrice come argomento a una procedura o proprietà.

Procedura: restituire una matrice da una proprietà o una routine (Visual Basic)

Viene descritto come restituire una matrice al codice che chiama una procedura o una proprietà.

Risoluzione dei problemi relativi alle matrici (Visual Basic)

Vengono illustrati alcuni problemi comuni che si verificano quando si utilizzano le matrici.

Vedere anche

Riferimenti

Istruzione Dim (Visual Basic)

Istruzione ReDim (Visual Basic)

Array