|
Dit artikel is gepubliceerd op woensdag 28 april 2010 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
7.8.1. ReDim StatementHet kan voorkomen dat men toch reeds een arrayvariabele wenst te declareren, maar men nog niet weet hoe groot de array dient te zijn. En men bijgevolg dus niet weet welke waarden als upperbound op te geven.
Een aantal oplossingen bieden zich hierbij aan : - toch wachten met het declareren van de arrayvariabele ( dit is niet altijd mogelijk wegens "scope" redenen ( later hierover meer ) ) - de array zo groot maken dat je later zeker voldoende elementen hebt ( dit heeft als nadeel geheugenverlies indien niet alle elementen zullen worden gebruikt )
De beste oplossing is hier bij het declareren van de arrayvariabele nog geen upperbounds op te geven. Hiermee bekom je nog altijd ( de declaratie van ) een arrayvariabele, maar deze variabele wijst nog niet naar een arrayinstantie.
Op een later moment kan dan een grootte opgeven voor deze array. Visual Basic Broncode Module Example1
Sub Main()
Dim row() As Integer
Dim matrix(,) As Integer
ReDim row(9)
ReDim matrix(9, 9)
row(5) = 5
matrix(5, 5) = 5
Console.WriteLine(row(5))
Console.WriteLine(matrix(5, 5))
Console.ReadLine()
End Sub
End ModuleDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
Zoals je merkt ( regel (1) ) moet je bij het declareren van een arrayvariabele die moet kunnen wijzen naar een twee dimensional tabel wel reeds in de dimensielijst aangeven wat het aantal dimensies is. Door hier dus in die dimensielijst een komma te plaatsen geef je als het ware aan dat je voor 2 dimensies geen upperbound opgeeft, en dat de variabele matrix dus zal moeten kunnen verwijzen naar een twee dimensional tabel.
In bovenstaand voorbeeld zullen regels (2) en (3) niet functioneren ( ze veroorzaken een uitvoeringsfout ) omdat je dus verwijst naar een element van de array die nog niet bestaat, tenslotte bestaat nog enkel maar de arrayvariabele en niet de array zelf.
Het opgeven van een grootte voor een tabel ( dimensioneren van de tabel ) kan door een ReDim statement te gebruiken, en wel in volgende vorm : ReDim identifier(first-upperbound, second-upperbound, ...) Het opgeven van een grootte gebeurt dus door tussen de haakjes upperbounds te definiëren.
Na het dimensioneren van de tabel, kan men nu wel tabelelementen ( weliswaar op een bestaande index ) aanspreken.
De declaratie : Zou ook op volgende wijze kunnen gedefinieerd worden : De haakjes bij een declaratie van een arrayvariabele zonder dimensionering van die array mogen ook na het datatype staan. Je bekomt zo steeds hetzelfde resultaat : een declaratie van die arrayvariabele, zonder dat er een array zelf werd aangemaakt.
Geeft men echter wel een dimensie op bij het declareren van een arrayvariabele dan moet de dimensielijst na de arrayidentifier staan.
Niet alleen tabellen die nog niet gedimensioneerd waren kan je gaan dimensioneren ( zoals in vorig voorbeeld ), maar ook reeds gedimensioneerde tabellen kan je herdimensioneren ( zoals in onderstaand voorbeeld ).
In onderstaand voorbeeld wordt een tabel ( met 3 rijen en 4 kolommen ) geherdimensioneerd naar een tabel met 6 rijen en 10 kolommen. Visual Basic Broncode Module Example2
Sub Main()
Dim matrix(2, 3) As Integer
matrix(1, 1) = 10
Console.WriteLine(matrix(1, 1))
ReDim matrix(5, 9)
Console.WriteLine(matrix(1, 1))
Console.ReadLine()
End Sub
End ModuleDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
Merk op ( aan de output van regel (1) ) dat alle elementen na het herdimensioneren terug de defaultwaarde van het datatype ( van de Asclausule uit de declaratie van de array ) bevatten.
Bij het (her)dimensioneren van een tabel via het ReDim statement wordt immers een nieuwe tabel in het geheugen aangemaakt. De tabel die je dan zogezegd herdimensioneert, verwijst dan gewoon naar de nieuwe tabel die is aangemaakt. De oude tabel ( als geen andere arrayvariabelen hiernaar nog verwijzen ) zal dan uit het geheugen worden verwijderd.
(Her)dimensioneren via ReDim is een "zware" operatie. Een volledig nieuwe arrayinstantie moet in het geheugen worden aangemaakt.
Opgelet : bij het (her)dimensioneren via ReDim kan men enkel de upperbounds van de dimensies aanpassen. Dus enkele het aantal elementen per dimensie kan gewijzigd worden, dit kunnen meer of minder elementen worden. Het aantal dimensies kan bijvoorbeeld ook niet worden aangepast.
Ook het datatype van de elementen kan niet worden gewijzigd, in een ReDim statement staat tenslotte geen nieuwe As clausule die het nieuwe datatype van de elementen zou kunnen aangeven. Terug naar boven 7.8.2. ReDim PreserveWenst men toch de oude waarden bij het zogenaamde herdimensioneren te behouden dan kan het keyword Preserve toevoegen aan het ReDim statement ( zoals in regel (1) van onderstaand voorbeeld ).
Hierbij wordt dan niet alleen een nieuwe array in het geheugen aangemaakt, met die ( in het ReDim statement ) opgeven dimensies, maar zullen de oude waarden worden overgenomen in deze nieuwe tabel : Visual Basic Broncode Module Example3
Sub Main()
Dim matrix(2, 3) As Integer
matrix(1, 1) = 10
Console.WriteLine(matrix(1, 1))
ReDim Preserve matrix(2, 9)
Console.WriteLine(matrix(1, 1))
ReDim Preserve matrix(5, 9)
Console.ReadLine()
End Sub
End ModuleDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
Regel (2) geeft nu toch als output 10, wat ook de oude waarde was van dat element.
Men is echter beperkt bij het gebruiken van het ReDim statement, men kan hier enkel de upperbound van de laatste dimensie aanpassen. De aantal rijen uit de oorspronkelijke matrix tabel ( 3 rijen ) kan dus bijvoorbeeld niet worden aangepast. We hebben hier 2-dimensies, dus kan enkel de upperbound van de tweede dimensie worden gewijzigd ( enkel het aantal kolommen dus ). Opnieuw kunnen het meer of minder elementen zijn.
Regel (3) zou hier een uitvoeringsfout veroorzaken die aangeeft dat de nieuw gedimensioneerde tabel niet kan gebruikt worden.
ReDim Preserve is een nog "zwaardere" operatie dan een gewone ReDim. Niet alleen moet een nieuwe arrayinstantie in het geheugen worden aangemaakt, ook moeten de oude waarden worden overgenomen. Het spreekt voor zich dat men het aantal ReDims en zeker het aantal ReDim Preserves in een algoritme moet proberen te beperken, zeker indien men met grote arrays aan het werken is. Terug naar boven
7.8.3. OefeningOpgave :
Maak een programma om de namen van personeelsleden en de afdelingen waarin ze werken te beheren.
De vereisten zijn dat je slechts 1 meer dimensionale tabel hiervoor gebruikt en dat deze tabel nooit meer elementen bevat dan hoogst-noodzakelijk. Visual Basic Output No Employees.
MENU : <a> Add Employee / <r> Remove Last Employee / <x> Exit : a
Name : John
Department : Management
Employees Overview :
John ( Management )
MENU : <a> Add Employee / <r> Remove Last Employee / <x> Exit : A
Name : Paul
Department : Marketing
Employees Overview :
John ( Management )
Paul ( Marketing )
MENU : <a> Add Employee / <r> Remove Last Employee / <x> Exit : b
Employees Overview :
John ( Management )
Paul ( Marketing )
MENU : <a> Add Employee / <r> Remove Last Employee / <x> Exit : r
Employees Overview :
John ( Management )
MENU : <a> Add Employee / <r> Remove Last Employee / <x> Exit : R
No Employees.
MENU : <a> Add Employee / <r> Remove Last Employee / <x> Exit : a
Name : Jane
Department : Management
Employees Overview :
Jane ( Management )
MENU : <a> Add Employee / <r> Remove Last Employee / <x> Exit : X Oplossing : Visual Basic Broncode Module Exercise1Solution
Sub Main()
Dim menu As Char
Dim employees As String(,)
Dim count As Integer
Dim index As Integer
Do Until menu = "x"c OrElse menu = "X"c
If count > 0 Then
Console.WriteLine("Employees Overview :")
For index = 0 To count - 1
Console.WriteLine(employees(0, index) & _
" (" & employees(1, index) & ")")
Next
Else
Console.WriteLine("No Employees.")
End If
Console.Write("MENU : <a> Add Employee / " & _
"<r> Remove Last Employee / " & _
"<x> Exit : ")
menu = Console.ReadLine()
Select Case menu
Case "a"c, "A"c
ReDim Preserve employees(1, count)
Console.Write("Name : ")
employees(0, count) = Console.ReadLine()
Console.Write("Department : ")
employees(1, count) = Console.ReadLine()
count += 1
Case "r"c, "R"c
If count > 0 Then
ReDim Preserve employees(1, count - 1)
count -= 1
End If
Case "x"c, "X"c
End Select
Loop
End Sub
End ModuleDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
Terug naar boven
7.8.4. Intelligent Vergroten van ArraysAls men een grote collectie moet beheren, zou men ervoor kunnen opteren om meteen een array te creëren met "voldoende" elementen. Hierbij vermijdende dat men steeds een "zware" ReDim Preserve dient toe te passen. Natuurlijk heeft dit als nadeel dat deze grote array (te)veel geheugenruimte in beslag zal nemen.
Een goed alternatief is het werken met een steeds verdubbelende capaciteit. Hierbij vermijdt men het al te vaak herdimensioneren van de tabel, en zal ook niet al te veel geheugenruimte verkwist worden. Visual Basic Broncode Module Example4
Sub Main()
Dim capacity As Integer = 2
Dim count As Integer
Dim numbers(capacity - 1) As Integer
Do
Dim index As Integer
Console.Write("Numbers ( capacity " & capacity & _
", count " & count & " ) : ")
For index = 0 To count - 1
Console.Write(numbers(index) & " ")
Next
Console.WriteLine()
Console.Write("Number ? : ")
Dim number As Integer = Console.ReadLine()
count += 1
If count > capacity Then
capacity *= 2
ReDim Preserve numbers(capacity - 1)
End If
numbers(count - 1) = number
Loop
End Sub
End ModuleDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
Visual Basic Output Numbers ( capacity 2, count 0 ) :
Number ? : 1
Numbers ( capacity 2, count 1 ) : 1
Number ? : 2
Numbers ( capacity 2, count 2 ) : 1 2
Number ? : 3
Numbers ( capacity 4, count 3 ) : 1 2 3
Number ? : 4
Numbers ( capacity 4, count 4 ) : 1 2 3 4
Number ? : 5
Numbers ( capacity 8, count 5 ) : 1 2 3 4 5
Number ? : 6
Numbers ( capacity 8, count 6 ) : 1 2 3 4 5 6
Number ? : 7
Numbers ( capacity 8, count 7 ) : 1 2 3 4 5 6 7
Number ? : 8
Numbers ( capacity 8, count 8 ) : 1 2 3 4 5 6 7 8
Number ? : 9
Numbers ( capacity 16, count 9 ) : 1 2 3 4 5 6 7 8 9
Number ? : Het programma blijft hier oneindig vragen om de invoer van een getal.
Dit artikel is gepubliceerd op woensdag 28 april 2010 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
Visual Basic 2008 & 2010 Boeken
Berichten
|