Matrici in Visual Basic
Una matrice è un set di valori, ovvero elementi definiti logicamente correlati tra loro. Ad esempio, una matrice può essere costituita dal numero di studenti in ogni grado in una scuola di grammatica; ogni elemento della matrice è il numero di studenti in un singolo grado. Analogamente, una matrice può essere costituita dai voti di uno studente per una classe; ogni elemento della matrice è un singolo grado.
È possibile usare singole variabili per archiviare ognuno degli elementi di dati. Ad esempio, se l'applicazione analizza i voti degli studenti, è possibile usare una variabile separata per il grado di ogni studente, ad englishGrade1
esempio , englishGrade2
e così via. Questo approccio presenta tre limitazioni principali:
- Dobbiamo sapere in fase di progettazione esattamente il numero di voti che dobbiamo gestire.
- La gestione di grandi numeri di gradi diventa rapidamente senza problemi. Questo a sua volta rende un'applicazione molto più probabile avere bug gravi.
- È difficile mantenere. Ogni nuovo grado aggiunto richiede che l'applicazione venga modificata, ricompilata e ridistribuita.
Usando una matrice, è possibile fare riferimento a questi valori correlati con lo stesso nome e usare un numero denominato indice o sottoscript per identificare un singolo elemento in base alla relativa posizione nella matrice. Indici di un intervallo di matrice compreso tra 0 e uno inferiore al numero totale di elementi nella matrice. Quando si usa Visual Basic sintassi per definire le dimensioni di una matrice, specificarne l'indice più alto, non il numero totale di elementi nella matrice. È possibile usare la matrice come unità e la possibilità di eseguire l'iterazione dei relativi elementi consente di conoscere esattamente il numero di elementi che contiene in fase di progettazione.
Di seguito sono riportati alcuni esempi:
' Declare a single-dimension array of 5 numbers.
Dim numbers(4) As Integer
' Declare a single-dimension array and set its 4 values.
Dim numbers = New Integer() {1, 2, 4, 8}
' Change the size of an existing array to 16 elements and retain the current values.
ReDim Preserve numbers(15)
' Redefine the size of an existing array and reset the values.
ReDim numbers(15)
' Declare a 6 x 6 multidimensional array.
Dim matrix(5, 5) As Double
' Declare a 4 x 3 multidimensional array and set array element values.
Dim matrix = New Integer(,) {{1, 2, 3}, {2, 3, 4}, {3, 4, 5}, {4, 5, 6}}
' Declare a jagged array
Dim sales()() As Double = New Double(11)() {}
Elementi di matrice in una matrice semplice
Verrà creata una matrice denominata students
per archiviare il numero di studenti in ogni grado in una scuola di grammatica. Gli indici degli elementi sono compresi tra 0 e 6. L'uso di questa matrice è più semplice rispetto alla dichiarazione di sette variabili.
La figura seguente mostra la students
matrice. Per ogni 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.
L'esempio seguente contiene il codice Visual Basic che crea e usa la matrice:
Module SimpleArray
Public Sub Main()
' Declare an array with 7 elements.
Dim students(6) As Integer
' Assign values to each element.
students(0) = 23
students(1) = 19
students(2) = 21
students(3) = 17
students(4) = 19
students(5) = 20
students(6) = 22
' Display the value of each element.
For ctr As Integer = 0 To 6
Dim grade As String = If(ctr = 0, "kindergarten", $"grade {ctr}")
Console.WriteLine($"Students in {grade}: {students(ctr)}")
Next
End Sub
End Module
' The example displays the following output:
' Students in kindergarten: 23
' Students in grade 1: 19
' Students in grade 2: 21
' Students in grade 3: 17
' Students in grade 4: 19
' Students in grade 5: 20
' Students in grade 6: 22
L'esempio esegue tre operazioni:
- Dichiara una
students
matrice con sette elementi. Il numero6
nella dichiarazione della matrice indica l'ultimo indice della matrice. È uno minore del numero di elementi nella matrice. - Assegna valori a ogni elemento della matrice. Gli elementi della matrice vengono accessibili usando il nome della matrice e includendo l'indice dell'singolo elemento tra parentesi.
- Elenca ogni valore della matrice. Nell'esempio viene usata un'istruzione
For
per accedere a ogni elemento della matrice in base al relativo numero di indice.
La students
matrice nell'esempio precedente è una matrice unidimensionale perché usa un indice. Una matrice che usa più indici o sottoscrizioni è denominata multidimensionale. Per altre informazioni, vedere il resto di questo articolo e Dimensioni matrice in Visual Basic.
Creazione di una matrice
È possibile definire le dimensioni di una matrice in diversi modi:
È possibile specificare le dimensioni quando la matrice è dichiarata:
' Declare an array with 10 elements. Dim cargoWeights(9) As Double ' Declare a 24 x 2 array. Dim hourlyTemperatures(23, 1) As Integer ' Declare a jagged array with 31 elements. Dim januaryInquiries(30)() As String
È possibile usare una
New
clausola per specificare le dimensioni di una matrice quando viene creata:' Declare an array with 10 elements. Dim cargoWeights() As Double = New Double(9) {} ' Declare a 24 x 2 array. Dim hourlyTemperatures(,) As Integer = New Integer(23, 1) {} ' Declare a jagged array with 31 elements. Dim januaryInquiries()() As String = New String(30)() {}
Se è disponibile una matrice esistente, è possibile ridefinirne la dimensione usando l'istruzione ReDim
. È possibile specificare che l'istruzione ReDim
mantiene i valori presenti nella matrice oppure è possibile specificare che crea una matrice vuota. L'esempio seguente illustra vari modi di usare l'istruzione ReDim
per modificare la dimensione di una matrice esistente.
' Assign a new array size and retain the current values.
ReDim Preserve cargoWeights(20)
' Assign a new array size and retain only the first five values.
ReDim Preserve cargoWeights(4)
' Assign a new array size and discard all current element values.
ReDim cargoWeights(15)
Per altre informazioni, vedere l'istruzione ReDim.
Archiviazione dei valori in una matrice
È possibile accedere a ogni posizione in una matrice usando un indice di tipo Integer
. È possibile archiviare e recuperare i valori in una matrice facendo riferimento a ogni posizione della matrice tramite 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 seguente vengono illustrate alcune istruzioni che archiviano e recuperano i valori nelle matrici.
Module Example
Public Sub Main()
' Create a 10-element integer array.
Dim numbers(9) As Integer
Dim value As Integer = 2
' Write values to it.
For ctr As Integer = 0 To 9
numbers(ctr) = value
value *= 2
Next
' Read and sum the array values.
Dim sum As Integer
For ctr As Integer = 0 To 9
sum += numbers(ctr)
Next
Console.WriteLine($"The sum of the values is {sum:N0}")
End Sub
End Module
' The example displays the following output:
' The sum of the values is 2,046
Popolamento di una matrice con valori letterali di matrice
Usando un valore letterale di matrice, è possibile popolare una matrice con un set iniziale di valori contemporaneamente creato. Un valore letterale di matrice è costituito da un elenco di valori delimitati da virgole racchiusi tra parentesi graffe ({}
).
Quando si usa un valore letterale di matrice per creare una matrice, è possibile specificare il tipo o usare l'inferenza del tipo per determinare il tipo di matrice. L'esempio seguente mostra entrambe le opzioni.
' Array literals with explicit type definition.
Dim numbers = New Integer() {1, 2, 4, 8}
' Array literals with type inference.
Dim doubles = {1.5, 2, 9.9, 18}
' Array literals with explicit type definition.
Dim articles() As String = { "the", "a", "an" }
' Array literals with explicit widening type definition.
Dim values() As Double = { 1, 2, 3, 4, 5 }
Quando si usa l'inferenza dei tipi, il tipo della matrice viene determinato dal tipo dominante nell'elenco dei valori letterali . Il tipo dominante è il tipo a cui tutti gli altri tipi della matrice possono essere ampliati. Se non è possibile determinare il tipo univoco, 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
. Poiché Integer
e Long
si estende solo a Double
, Double
è il tipo dominante. Per altre informazioni, vedere Widening and Narrowing Conversions.
Nota
È possibile usare l'inferenza dei tipi solo per le matrici definite come variabili locali in un membro di tipo. Se una definizione di tipo esplicito è assente, le matrici definite con valori letterali di matrice a livello di classe sono di tipo Object[]
. Per altre informazioni, vedere Inferenza del tipo locale.
Si noti che l'esempio precedente definisce values
come matrice di tipo Double
anche se tutti i valori letterali della matrice sono di tipo Integer
. È possibile creare questa matrice perché i valori nel valore letterale della matrice possono essere ampliati ai Double
valori.
È anche possibile creare e popolare una matrice multidimensionale usando valori letterali matrice annidati. I valori letterali matrice annidati devono avere una serie di dimensioni coerenti con la matrice risultante. Nell'esempio seguente viene creata una matrice bidimensionale di interi usando valori letterali matrice annidati.
' Create and populate a 2 x 2 array.
Dim grid1 = {{1, 2}, {3, 4}}
' Create and populate a 2 x 2 array with 3 elements.
Dim grid2(,) = {{1, 2}, {3, 4}, {5, 6}}
Quando si usano valori letterali di matrice annidati per creare e popolare una matrice, si verifica un errore se il numero di elementi nei valori letterali della matrice annidata non corrisponde. Si verifica anche un errore se si dichiara in modo esplicito la variabile di matrice in modo da avere un numero diverso di dimensioni rispetto ai valori letterali della matrice.
Come è possibile per le matrici unidimensionali, è possibile basarsi sull'inferenza dei tipi durante la creazione di una matrice multidimensionale con valori letterali di matrice annidati. Il tipo dedotto è il tipo dominante per tutti i valori in tutti i valori letterali della matrice per tutti i livelli di annidamento. Nell'esempio seguente viene creata una matrice bidimensionale di tipo da valori di tipo Double[,]
Integer
e Double
.
Dim arr = {{1, 2.0}, {3, 4}, {5, 6}, {7, 8}}
Per altri esempi, vedere Procedura: inizializzare una variabile di matrice in Visual Basic.
Iterazione attraverso una matrice
Quando si esegue l'iterazione tramite una matrice, si accede a ogni elemento della matrice dall'indice più basso al più alto o dal più alto al più basso. In genere, usare entrambi i for... Istruzione successiva o per ogni oggetto... Istruzione successiva per scorrere gli elementi di una matrice. Quando non si conoscono i limiti superiori della matrice, è possibile chiamare il Array.GetUpperBound metodo per ottenere il valore più alto dell'indice. Anche se il valore di indice più basso è quasi sempre 0, è possibile chiamare il metodo per ottenere il Array.GetLowerBound valore più basso dell'indice.
Nell'esempio seguente viene eseguita un'iterazione tramite una matrice unidimensionale usando l'istruzione For...Next
.
Module IterateArray
Public Sub Main()
Dim numbers = {10, 20, 30}
For index = 0 To numbers.GetUpperBound(0)
Console.WriteLine(numbers(index))
Next
End Sub
End Module
' The example displays the following output:
' 10
' 20
' 30
L'esempio seguente illustra come scorrere una matrice multidimensionale usando un'istruzione For...Next
. Il metodo GetUpperBound ha un parametro che specifica la dimensione. GetUpperBound(0)
restituisce l'indice più alto della prima dimensione e GetUpperBound(1)
restituisce l'indice più alto della seconda dimensione.
Module IterateArray
Public Sub Main()
Dim numbers = {{1, 2}, {3, 4}, {5, 6}}
For index0 = 0 To numbers.GetUpperBound(0)
For index1 = 0 To numbers.GetUpperBound(1)
Console.Write($"{numbers(index0, index1)} ")
Next
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' Output
' 1 2
' 3 4
' 5 6
Nell'esempio seguente viene usato un oggetto For Each... Next Statementto iterate attraverso una matrice unidimensionale e una matrice bidimensionale.
Module IterateWithForEach
Public Sub Main()
' Declare and iterate through a one-dimensional array.
Dim numbers1 = {10, 20, 30}
For Each number In numbers1
Console.WriteLine(number)
Next
Console.WriteLine()
Dim numbers = {{1, 2}, {3, 4}, {5, 6}}
For Each number In numbers
Console.WriteLine(number)
Next
End Sub
End Module
' The example displays the following output:
' 10
' 20
' 30
'
' 1
' 2
' 3
' 4
' 5
' 6
Dimensioni 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. L'esempio seguente, ad esempio, dichiara una matrice 2dimensionale con quattro elementi in ogni dimensione. Come illustrato dall'esempio, la dimensione della matrice è 16 (o (3 + 1) * (3 + 1).
Module Example
Public Sub Main()
Dim arr(3, 3) As Integer
Console.WriteLine(arr.Length)
End Sub
End Module
' The example displays the following output:
' 16
Nota
Questa discussione sulle dimensioni della matrice non si applica alle matrici con estensione frastagliata. Per informazioni sulle matrici frastagliate e sulla determinazione delle dimensioni di una matrice frastagliata, vedere la sezione Matrici frastagliate .
È possibile determinare le dimensioni di una matrice usando la proprietà Array.Length. È possibile trovare la lunghezza di ogni dimensione di una matrice multidimensionale usando il Array.GetLength metodo .
È possibile ridimensionare una variabile di matrice assegnando un nuovo oggetto matrice o usando l'istruzione ReDim
Statement . Nell'esempio seguente viene usata l'istruzione ReDim
per modificare una matrice di 100 elementi in una matrice di 51 elementi.
Module Example
Public Sub Main()
Dim arr(99) As Integer
Console.WriteLine(arr.Length)
Redim arr(50)
Console.WriteLine(arr.Length)
End Sub
End Module
' The example displays the following output:
' 100
' 51
Di seguito sono indicati alcuni elementi importanti relativi alla dimensione di una matrice.
Note | |
---|---|
Lunghezza delle dimensioni | L'indice di ogni dimensione è basato su 0, ovvero è compreso tra 0 e il limite superiore. Pertanto, la lunghezza di una determinata dimensione è maggiore del limite superiore dichiarato di tale dimensione. |
Limiti di lunghezza | La lunghezza di ogni dimensione di una matrice è limitata al valore massimo del Integer tipo di dati, ovvero Int32.MaxValue o (2 ^ 31) - 1. La dimensione totale di una matrice, tuttavia, è limitata anche dalla memoria disponibile nel sistema. Se si tenta di inizializzare una matrice che supera la quantità di memoria disponibile, il runtime genera un OutOfMemoryExceptionoggetto . |
Dimensione ed elementi della matrice | La dimensione di una matrice è indipendente dal tipo di dati dei relativi elementi. Le dimensioni rappresentano sempre il numero totale di elementi, non il numero di byte usati in memoria. |
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 (CLR) può assegnare la memoria in modo da compattare al massimo gli elementi oppure in modo da allinearli tutti in base ai limiti dell'hardware. Per le informazioni di controllo di una matrice è richiesto un sovraccarico di archiviazione che aumenta con ogni dimensione aggiunta. |
Tipo di matrice
Ogni matrice ha un tipo di dati diverso dal tipo di dati degli 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 sono dello stesso tipo di dati solo quando hanno lo stesso rango e i relativi elementi hanno lo stesso tipo di dati. Le lunghezze delle dimensioni di una matrice non influiscono 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
. Ad esempio, anche se il codice seguente dichiara che la variabile deve essere di tipo Array
e chiama il arr
metodo per creare un'istanza della matrice, il Array.CreateInstance tipo della matrice dimostra di essere Object[].
Module Example
Public Sub Main()
Dim arr As Array = Array.CreateInstance(GetType(Object), 19)
Console.WriteLine(arr.Length)
Console.WriteLine(arr.GetType().Name)
End Sub
End Module
' The example displays the following output:
' 19
' Object[]
L'istruzione ReDim non può inoltre operare su una variabile dichiarata di tipo Array
. Per questi motivi, e per la sicurezza dei tipi, è consigliabile dichiarare ogni matrice come tipo specifico.
È possibile determinare il tipo di dati di una matrice o dei relativi elementi in diversi modi.
- È possibile chiamare il GetType metodo nella variabile per ottenere un Type oggetto che rappresenta il tipo di runtime della variabile. Nelle proprietà e nei metodi dell'oggetto Type sono presenti informazioni complete.
- È possibile passare la variabile alla TypeName funzione per ottenere un
String
con il nome del tipo di runtime.
Nell'esempio seguente viene chiamato sia il GetType
metodo che la TypeName
funzione per determinare il tipo di una matrice. Il tipo di matrice è Byte(,)
. Si noti che la Type.BaseType proprietà indica anche che il tipo di base della matrice di byte è la Array classe .
Module Example
Public Sub Main()
Dim bytes(9,9) As Byte
Console.WriteLine($"Type of {nameof(bytes)} array: {bytes.GetType().Name}")
Console.WriteLine($"Base class of {nameof(bytes)}: {bytes.GetType().BaseType.Name}")
Console.WriteLine()
Console.WriteLine($"Type of {nameof(bytes)} array: {TypeName(bytes)}")
End Sub
End Module
' The example displays the following output:
' Type of bytes array: Byte[,]
' Base class of bytes: Array
'
' Type of bytes array: Byte(,)
Matrici come valori e parametri restituiti
Per restituire una matrice da una routine Function
, specificare il tipo di dati della matrice e il numero di dimensioni come tipo restituito dell'istruzione Function. All'interno della funzione dichiarare una variabile di matrice locale con lo stesso tipo di dati degli elementi e lo stesso numero di dimensioni. Includere la variabile di matrice locale senza parentesi nell'istruzione Return.
Per specificare una matrice come parametro in una routine Sub
o Function
, definire il parametro come matrice con un tipo di dati e un numero di dimensioni specificati. Nella chiamata alla procedura passare una variabile di matrice con lo stesso tipo di dati e il numero di dimensioni.
Nell'esempio seguente la GetNumbers
funzione restituisce una Integer()
matrice unidimensionale di tipo Integer
. La routine ShowNumbers
accetta un argomento Integer()
.
Module ReturnValuesAndParams
Public Sub Main()
Dim numbers As Integer() = GetNumbers()
ShowNumbers(numbers)
End Sub
Private Function GetNumbers() As Integer()
Dim numbers As Integer() = {10, 20, 30}
Return numbers
End Function
Private Sub ShowNumbers(numbers As Integer())
For index = 0 To numbers.GetUpperBound(0)
Console.WriteLine($"{numbers(index)} ")
Next
End Sub
End Module
' The example displays the following output:
' 10
' 20
' 30
Nell'esempio seguente la GetNumbersMultiDim
funzione restituisce una Integer(,)
matrice bidimensionale di tipo Integer
. La routine ShowNumbersMultiDim
accetta un argomento Integer(,)
.
Module Example
Public Sub Main()
Dim numbers As Integer(,) = GetNumbersMultidim()
ShowNumbersMultidim(numbers)
End Sub
Private Function GetNumbersMultidim() As Integer(,)
Dim numbers As Integer(,) = {{1, 2}, {3, 4}, {5, 6}}
Return numbers
End Function
Private Sub ShowNumbersMultidim(numbers As Integer(,))
For index0 = 0 To numbers.GetUpperBound(0)
For index1 = 0 To numbers.GetUpperBound(1)
Console.Write($"{numbers(index0, index1)} ")
Next
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' 1 2
' 3 4
' 5 6
Matrici di matrici
In alcuni casi la struttura dei dati nell'applicazione è bidimensionale, ma non rettangolare. Ad esempio, è possibile usare una matrice per archiviare i dati relativi alla temperatura elevata di ogni giorno del mese. La prima dimensione della matrice rappresenta il mese, ma la seconda dimensione rappresenta il numero di giorni e il numero di giorni in un mese non è uniforme. Una matrice frastagliata, denominata anche matrice di matrici, è progettata per tali scenari. Una matrice frastagliata è una matrice i cui elementi sono anche matrici. Una matrice irregolare e ogni elemento di una matrice irregolare possono avere una o più dimensioni.
Nell'esempio seguente viene usata una matrice di mesi, ogni elemento di cui è una matrice di giorni. Nell'esempio viene usata una matrice frastagliata perché diversi mesi hanno diversi numeri di giorni. Nell'esempio viene illustrato come creare una matrice frastagliata, assegnarne i valori e recuperarne e visualizzarne i valori.
Imports System.Globalization
Module JaggedArray
Public Sub Main()
' Declare the jagged array of 12 elements. Each element is an array of Double.
Dim sales(11)() As Double
' Set each element of the sales array to a Double array of the appropriate size.
For month As Integer = 0 To 11
' The number of days in the month determines the appropriate size.
Dim daysInMonth As Integer =
DateTime.DaysInMonth(Year(Now), month + 1)
sales(month) = New Double(daysInMonth - 1) {}
Next
' Store values in each element.
For month As Integer = 0 To 11
For dayOfMonth = 0 To sales(month).GetUpperBound(0)
sales(month)(dayOfMonth) = (month * 100) + dayOfMonth
Next
Next
' Retrieve and display the array values.
Dim monthNames = DateTimeFormatInfo.CurrentInfo.AbbreviatedMonthNames
' Display the month names.
Console.Write(" ")
For ctr = 0 To sales.GetUpperBound(0)
Console.Write($" {monthNames(ctr)} ")
Next
Console.WriteLine()
' Display data for each day in each month.
For dayInMonth = 0 To 30
Console.Write($"{dayInMonth + 1,2}. ")
For monthNumber = 0 To sales.GetUpperBound(0)
If dayInMonth > sales(monthNumber).GetUpperBound(0) Then
Console.Write(" ")
Else
Console.Write($"{sales(monthNumber)(dayInMonth),-5} ")
End If
Next
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
' 1. 0 100 200 300 400 500 600 700 800 900 1000 1100
' 2. 1 101 201 301 401 501 601 701 801 901 1001 1101
' 3. 2 102 202 302 402 502 602 702 802 902 1002 1102
' 4. 3 103 203 303 403 503 603 703 803 903 1003 1103
' 5. 4 104 204 304 404 504 604 704 804 904 1004 1104
' 6. 5 105 205 305 405 505 605 705 805 905 1005 1105
' 7. 6 106 206 306 406 506 606 706 806 906 1006 1106
' 8. 7 107 207 307 407 507 607 707 807 907 1007 1107
' 9. 8 108 208 308 408 508 608 708 808 908 1008 1108
' 10. 9 109 209 309 409 509 609 709 809 909 1009 1109
' 11. 10 110 210 310 410 510 610 710 810 910 1010 1110
' 12. 11 111 211 311 411 511 611 711 811 911 1011 1111
' 13. 12 112 212 312 412 512 612 712 812 912 1012 1112
' 14. 13 113 213 313 413 513 613 713 813 913 1013 1113
' 15. 14 114 214 314 414 514 614 714 814 914 1014 1114
' 16. 15 115 215 315 415 515 615 715 815 915 1015 1115
' 17. 16 116 216 316 416 516 616 716 816 916 1016 1116
' 18. 17 117 217 317 417 517 617 717 817 917 1017 1117
' 19. 18 118 218 318 418 518 618 718 818 918 1018 1118
' 20. 19 119 219 319 419 519 619 719 819 919 1019 1119
' 21. 20 120 220 320 420 520 620 720 820 920 1020 1120
' 22. 21 121 221 321 421 521 621 721 821 921 1021 1121
' 23. 22 122 222 322 422 522 622 722 822 922 1022 1122
' 24. 23 123 223 323 423 523 623 723 823 923 1023 1123
' 25. 24 124 224 324 424 524 624 724 824 924 1024 1124
' 26. 25 125 225 325 425 525 625 725 825 925 1025 1125
' 27. 26 126 226 326 426 526 626 726 826 926 1026 1126
' 28. 27 127 227 327 427 527 627 727 827 927 1027 1127
' 29. 28 228 328 428 528 628 728 828 928 1028 1128
' 30. 29 229 329 429 529 629 729 829 929 1029 1129
' 31. 30 230 430 630 730 930 1130
L'esempio precedente assegna i valori alla matrice con estensione con estensione in base a un elemento usando un For...Next
ciclo. È anche possibile assegnare valori agli elementi di una matrice frastagliata usando valori letterali matrice annidati. Tuttavia, il tentativo di usare valori letterali matrice annidati (ad esempio, Dim valuesjagged = {{1, 2}, {2, 3, 4}}
) genera l'errore del compilatore BC30568. Per correggere l'errore, racchiudere i valori letterali della matrice interna tra parentesi. Le parentesi forzano la valutazione dell'espressione letterale della matrice e i valori risultanti vengono usati con il valore letterale della matrice esterna, come illustrato nell'esempio seguente.
Module Example
Public Sub Main()
Dim values1d = { 1, 2, 3 }
Dim values2d = {{1, 2}, {2, 3}, {3, 4}}
Dim valuesjagged = {({1, 2}), ({2, 3, 4})}
End Sub
End Module
Una matrice frastagliata è una matrice unidimensionale i cui elementi contengono matrici. Pertanto, la Array.Length proprietà e il Array.GetLength(0)
metodo restituiscono il numero di elementi nella matrice unidimensionale e Array.GetLength(1)
genera un IndexOutOfRangeException oggetto perché una matrice frastagliata non è multidimensionale. Si determina il numero di elementi in ogni sottoarray recuperando il valore di ogni proprietà della Array.Length sottoarray. Nell'esempio seguente viene illustrato come determinare il numero di elementi in una matrice frastagliata.
Module Example
Public Sub Main()
Dim jagged = { ({1, 2}), ({2, 3, 4}), ({5, 6}), ({7, 8, 9, 10}) }
Console.WriteLine($"The value of jagged.Length: {jagged.Length}.")
Dim total = jagged.Length
For ctr As Integer = 0 To jagged.GetUpperBound(0)
Console.WriteLine($"Element {ctr + 1} has {jagged(ctr).Length} elements.")
total += jagged(ctr).Length
Next
Console.WriteLine($"The total number of elements in the jagged array: {total}")
End Sub
End Module
' The example displays the following output:
' The value of jagged.Length: 4.
' Element 1 has 2 elements.
' Element 2 has 3 elements.
' Element 3 has 2 elements.
' Element 4 has 4 elements.
' The total number of elements in the jagged array: 15
Matrici a lunghezza zero
Visual Basic differenzia tra una matrice non inizializzata (una matrice il cui valore è Nothing
) e una matrice a lunghezza zero o una matrice vuota (una matrice senza elementi). Una matrice non inizializzata è una che non è stata ridimensionata o che ha alcun valore assegnato a esso. Ad esempio:
Dim arr() As String
Una matrice a lunghezza zero viene dichiarata con una dimensione di -1. Ad esempio:
Dim arrZ(-1) As String
Potrebbe essere necessario creare una matrice di lunghezza zero nelle circostanze seguenti:
Senza rischiare un'eccezioneNullReferenceException, il codice deve accedere ai membri della Array classe, ad esempio o Rank, o chiamare una funzione Visual Basic, ad esempio UBoundLength .
Si vuole mantenere il codice semplice senza dover controllare
Nothing
come caso speciale.Il codice interagisce con un'API (Application Programming Interface) 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.
Divisione di una matrice
In alcuni casi, potrebbe essere necessario suddividere una singola matrice in più matrici. Ciò comporta l'identificazione del punto o dei punti in cui la matrice deve essere suddivisa e quindi spittinge la matrice in due o più matrici separate.
Nota
Questa sezione non illustra la suddivisione di una singola stringa in una matrice di stringhe in base a alcuni delimitatori. Per informazioni sulla suddivisione di una stringa, vedere il String.Split metodo .
I criteri più comuni per la suddivisione di una matrice sono:
Numero di elementi nella matrice. Ad esempio, è possibile dividere una matrice di più di un numero specificato di elementi in un numero di parti approssimativamente uguali. A questo scopo, è possibile usare il valore restituito dal Array.Length metodo o Array.GetLength .
Valore di un elemento, che funge da delimitatore che indica dove deve essere divisa la matrice. È possibile cercare un valore specifico chiamando i Array.FindIndex metodi e Array.FindLastIndex .
Dopo aver determinato l'indice o gli indici in corrispondenza del quale la matrice deve essere suddivisa, è quindi possibile creare le singole matrici chiamando il Array.Copy metodo .
Nell'esempio seguente viene divisa una matrice in due matrici di dimensioni approssimativamente uguali. Se il numero totale di elementi della matrice è dispari, la prima matrice ha un altro elemento rispetto al secondo.
Module Example
Public Sub Main()
' Create an array of 100 elements.
Dim arr(99) As Integer
' Populate the array.
Dim rnd As new Random()
For ctr = 0 To arr.GetUpperBound(0)
arr(ctr) = rnd.Next()
Next
' Determine how many elements should be in each array.
Dim divisor = 2
Dim remainder As Integer
Dim boundary = Math.DivRem(arr.GetLength(0), divisor, remainder)
' Copy the array.
Dim arr1(boundary - 1 + remainder), arr2(boundary - 1) as Integer
Array.Copy(arr, 0, arr1, 0, boundary + remainder)
Array.Copy(arr, boundary + remainder, arr2, 0, arr.Length - boundary)
End Sub
End Module
Nell'esempio seguente viene suddivisa una matrice di stringhe in due matrici in base alla presenza di un elemento il cui valore è "zzz", che funge da delimitatore della matrice. Le nuove matrici non includono l'elemento contenente il delimitatore.
Module Example
Public Sub Main()
Dim rnd As New Random()
' Create an array of 100 elements.
Dim arr(99) As String
' Populate each element with an arbitrary ASCII character.
For ctr = 0 To arr.GetUpperBound(0)
arr(ctr) = ChrW(Rnd.Next(&h21, &h7F))
Next
' Get a random number that will represent the point to insert the delimiter.
arr(rnd.Next(0, arr.GetUpperBound(0))) = "zzz"
' Find the delimiter.
Dim location = Array.FindIndex(arr, Function(x) x = "zzz")
' Create the arrays.
Dim arr1(location - 1) As String
Dim arr2(arr.GetUpperBound(0) - location - 1) As String
' Populate the two arrays.
Array.Copy(arr, 0, arr1, 0, location)
Array.Copy(arr, location + 1, arr2, 0, arr.GetUpperBound(0) - location)
End Sub
End Module
Unione di matrici
È anche possibile combinare un numero di matrici in una singola matrice più grande. A tale scopo, si usa anche il Array.Copy metodo .
Nota
Questa sezione non illustra l'aggiunta di una matrice di stringhe in una singola stringa. Per informazioni sull'aggiunta di una matrice di stringhe, vedere il String.Join metodo .
Prima di copiare gli elementi di ogni matrice nella nuova matrice, è prima necessario assicurarsi di aver inizializzato la matrice in modo che sia abbastanza grande per supportare la nuova matrice. Questa operazione può essere eseguita in due modi:
- Usare l'istruzione per espandere dinamicamente la
ReDim Preserve
matrice prima di aggiungere nuovi elementi. Questa è la tecnica più semplice, ma può causare una riduzione delle prestazioni e un consumo eccessivo di memoria quando si copiano matrici di grandi dimensioni. - Calcolare il numero totale di elementi necessari per la nuova matrice di grandi dimensioni, quindi aggiungere gli elementi di ogni matrice di origine.
Nell'esempio seguente viene usato il secondo approccio per aggiungere quattro matrici con dieci elementi ciascuno a una singola matrice.
Imports System.Collections.Generic
Imports System.Threading.Tasks
Module Example
Public Sub Main()
Dim tasks As New List(Of Task(Of Integer()))
' Generate four arrays.
For ctr = 0 To 3
Dim value = ctr
tasks.Add(Task.Run(Function()
Dim arr(9) As Integer
For ndx = 0 To arr.GetUpperBound(0)
arr(ndx) = value
Next
Return arr
End Function))
Next
Task.WaitAll(tasks.ToArray())
' Compute the number of elements in all arrays.
Dim elements = 0
For Each task In tasks
elements += task.Result.Length
Next
Dim newArray(elements - 1) As Integer
Dim index = 0
For Each task In tasks
Dim n = task.Result.Length
Array.Copy(task.Result, 0, newArray, index, n)
index += n
Next
Console.WriteLine($"The new array has {newArray.Length} elements.")
End Sub
End Module
' The example displays the following output:
' The new array has 40 elements.
Poiché in questo caso le matrici di origine sono tutte di piccole dimensioni, è anche possibile espandere dinamicamente la matrice man mano che si aggiungono gli elementi di ogni nuova matrice. Nell'esempio seguente viene eseguita questa operazione.
Imports System.Collections.Generic
Imports System.Threading.Tasks
Module Example
Public Sub Main()
Dim tasks As New List(Of Task(Of Integer()))
' Generate four arrays.
For ctr = 0 To 3
Dim value = ctr
tasks.Add(Task.Run(Function()
Dim arr(9) As Integer
For ndx = 0 To arr.GetUpperBound(0)
arr(ndx) = value
Next
Return arr
End Function))
Next
Task.WaitAll(tasks.ToArray())
' Dimension the target array and copy each element of each source array to it.
Dim newArray() As Integer = {}
' Define the next position to copy to in newArray.
Dim index = 0
For Each task In tasks
Dim n = Task.Result.Length
ReDim Preserve newArray(newArray.GetUpperBound(0) + n)
Array.Copy(task.Result, 0, newArray, index, n)
index += n
Next
Console.WriteLine($"The new array has {newArray.Length} elements.")
End Sub
End Module
' The example displays the following output:
' The new array has 40 elements.
Raccolte come alternativa alle matrici
Le matrici sono estremamente utili per la creazione e l'uso di un numero fisso di oggetti fortemente tipizzati. Le raccolte consentono di lavorare in modo più flessibile con gruppi di oggetti. A differenza delle matrici, che richiedono di modificare in modo esplicito le dimensioni di una matrice con l'istruzioneReDim
, le raccolte aumentano e si riducono in modo dinamico in base alle esigenze di un'applicazione.
Quando si usa ReDim
per ridimensionare una matrice, Visual Basic crea una nuova matrice e rilascia quella precedente. Questa operazione causa un aumento del tempo di esecuzione. Pertanto, se il numero di elementi usati di frequente o non è possibile stimare il numero massimo di elementi necessari, in genere si otterranno prestazioni migliori usando una raccolta.
Per alcune raccolte è possibile assegnare una chiave a qualsiasi oggetto inserito nella raccolta in modo da recuperare rapidamente l'oggetto usando la chiave.
Se la raccolta contiene elementi di un solo tipo di dati, è possibile usare una delle classi dello spazio dei nomi System.Collections.Generic. In una raccolta generica viene imposta l'indipendenza dai tipi, in modo da impedire che vengano aggiunti altri tipi di dati alla raccolta.
Per altre informazioni sulle raccolte, vedere Raccolte.
Argomenti correlati
Termine | Definizione |
---|---|
Array Dimensions in Visual Basic | Illustra il numero di dimensioni, o rango, e le dimensioni delle matrici. |
Procedura: Inizializzare una variabile di matrice in Visual Basic | Descrive come popolare le matrici con valori iniziali. |
Procedura: ordinare una matrice in Visual Basic | Illustra come ordinare alfabeticamente gli elementi di una matrice. |
Procedura: Assegnare una matrice a un'altra matrice | Descrive regole e passaggi per l'assegnazione di una matrice a un'altra variabile di matrice. |
Risoluzione dei problemi relativi alle matrici | Illustra alcuni problemi comuni che si verificano quando si usano le matrici. |