Skip to content

2. De basis van de taal VB.NET

2.1. Inleiding

We behandelen VB.NET eerst als een klassieke programmeertaal. We zullen later ingaan op objecten.

In een programma komen twee dingen voor

  • gegevens
  • de instructies die deze gegevens bewerken

Meestal wordt ernaar gestreefd om de gegevens en de instructies van elkaar te scheiden:

2.2. De gegevens van VB.NET

VB.NET maakt gebruik van de volgende gegevenstypen:

  1. gehele getallen, reële getallen en decimale getallen
  1. tekens en tekenreeksen
  2. booleaanse waarden
  3. datums
  4. objecten

2.2.1. Vooraf gedefinieerde gegevenstypen

Type VB
Equivalent type .NET
Grootte
Waardegebied
Booleaanse waarde
System.Boolean
2 bytes
Waar of Onwaar.
Byte
System.Byte
1 byte
0 tot 255 (zonder teken).
Char
System.Char
2 bytes
0 tot 65.535 (zonder teken).
Datum
System.DateTime
8 bytes
0:00:00 op 1 januari 0001 tot 23:59:59 op 31 december 9999.
Decimaal
System.Decimal
16 bytes
0 tot +/-79 228 162 514 264 337 593 543 950 335 zonder decimalen; 0 tot +/-7,9228162514264337593543950335 met 28 decimalen; het kleinste getal dat niet nul is, is +/-0,0000000000000000000000000001 (+/-1E-28).
Double
System.Double
8 bytes
-1,79769313486231E+308 tot
-4,94065645841247E-324 voor negatieve waarden; 4,94065645841247E-324 tot 1,79769313486231E+308 voor positieve waarden.
Geheel getal
System.Int32
4 bytes
-2 147 483 648 tot 2 147 483 647.
Long
System.Int64
8 bytes
-9 223 372 036 854 775 808 tot 9 223 372 036 854 775 807.
Object
System.Object
4 bytes
Elk type kan worden opgeslagen in een variabele van het type Object.
Short
System.Int16
2 bytes
-32 768 tot 32 767.
Single
System.Single
4 bytes
-3,402823E+38 tot -1,401298E-45 voor negatieve waarden; 1,401298E-45 tot 3,402823E+38 voor positieve waarden.
String
System.String (klasse)
 
0 tot ongeveer 2 miljard Unicode-tekens.

In de bovenstaande tabel zien we dat er twee mogelijke typen zijn voor een 32-bits geheel getal: Integer en System.Int32. Beide typen zijn onderling uitwisselbaar. Hetzelfde geldt voor de andere typen VB en hun equivalenten in het .NET-platform. Hier volgt een voorbeeldprogramma:


Module types
    Sub Main()
        ' gehele getallen
        Dim var1 As Integer = 100
        Dim var2 As Long = 10000000000L
        Dim var3 As Byte = 100
        Dim var4 As Short = 4
        ' reële getallen
        Dim var5 As Decimal = 4.56789D
        Dim var6 As Double = 3.4
        Dim var7 As Single = -0.000103F
        ' datum
        Dim var8 As Date = New Date(2003, 1, 1, 12, 8, 4)
        ' booleaanse waarde
        Dim var9 As Boolean = True
        ' teken
        Dim var10 As Char = "A"c
        ' tekenreeks
        Dim var11 As String = "abcde"
        ' object
        Dim var12 As Object = New Object
        ' weergaven
        Console.Out.WriteLine("var1=" + var1.ToString)
        Console.Out.WriteLine("var2=" + var2.ToString)
        Console.Out.WriteLine("var3=" + var3.ToString)
        Console.Out.WriteLine("var4=" + var4.ToString)
        Console.Out.WriteLine("var5=" + var5.ToString)
        Console.Out.WriteLine("var6=" + var6.ToString)
        Console.Out.WriteLine("var7=" + var7.ToString)
        Console.Out.WriteLine("var8=" + var8.ToString)
        Console.Out.WriteLine("var9=" + var9.ToString)
        Console.Out.WriteLine("var10=" + var10)
        Console.Out.WriteLine("var11=" + var11)
        Console.Out.WriteLine("var12=" + var12.ToString)
    End Sub
End Module

De uitvoering levert de volgende resultaten op:

var1=100
var2=10000000000
var3=100
var4=4
var5=4,56789
var6=3,4
var7=-0,000103
var8=01/01/2003 12:08:04
var9=True
var10=A
var11=abcde
var12=System.Object

2.2.2. Notatie van letterlijke gegevens

Integer
145, -7, &FF (hexadecimaal)
Long
100000L
Double
134,789, -45E-18 (-45 × 10⁻¹⁸)
Single
134.789F, -45E-18F (-45 10-18)
Decimal
100000D
Char
"A"c
String
"vandaag"
Boolean
true, false
date
New Date(2003, 1, 1) voor 01-01-2003

Let op de volgende punten:

  • 100000L, de L geeft aan dat het getal als een lang geheel getal wordt beschouwd
  • 134.789F, de F geeft aan dat het getal wordt beschouwd als een reëel getal met enkele precisie
  • 100000D, de D geeft aan dat het getal wordt beschouwd als een decimaal reëel getal
  • "A"c, om de tekenreeks "A" om te zetten in het teken 'A'
  • De tekenreeks wordt omgeven door het teken ". Als de tekenreeks het teken " moet bevatten, wordt dit dubbel weergegeven, zoals in "abcd""e", om de tekenreeks [abcd"e] weer te geven.

2.2.3. Gegevensverklaring

2.2.3.1. De rol van declaraties

Een programma verwerkt gegevens die worden gekenmerkt door een naam en een type. Deze gegevens worden in het geheugen opgeslagen. Bij het compileren van het programma wijst de compiler aan elk gegeven een geheugenlocatie toe die wordt gekenmerkt door een adres en een grootte. Hierbij maakt de compiler gebruik van de declaraties die door de programmeur zijn gemaakt. Bovendien stellen deze de compiler in staat om programmeerfouten op te sporen. Zo wordt de bewerking x=x*2 als foutief aangemerkt als x bijvoorbeeld een tekenreeks is.

2.2.3.2. Verklaring van constanten

De syntaxis voor het declareren van een constante is als volgt:

const identificatie as type=waarde

bijvoorbeeld [const PI as double=3.141592]. Waarom constanten declareren?

  1. Het programma is gemakkelijker te lezen als de constante een betekenisvolle naam krijgt: [const taux_tva as single=0.186F]
  2. Het aanpassen van het programma verloopt vlotter als de "constante" moet worden gewijzigd. In het voorgaande voorbeeld: als het btw-tarief stijgt naar 33%, hoeft alleen de instructie die de waarde definieert te worden aangepast: [const taux_tva as single=0.336F]. Als we 0,186 expliciet in het programma hadden gebruikt, zouden er talrijke instructies moeten worden aangepast.

2.2.3.3. Variabelen declareren

Een variabele wordt aangeduid met een naam en verwijst naar een gegevenstype. VB.NET maakt geen onderscheid tussen hoofdletters en kleine letters. De variabelen FIN en fin zijn dus identiek. Variabelen kunnen bij hun declaratie worden geïnitialiseerd. De syntaxis voor het declareren van een of meer variabelen is:

dim variabele1,variabele2,...,variabele n as type-identificatie

waarbij identificateur_de_type een vooraf gedefinieerd type is of een door de programmeur gedefinieerd type.

2.2.4. Conversies tussen getallen en tekenreeksen

nombre -> chaîne
nombre.ToString of "" & getal of CType(getal,String)
objet -> chaîne
objet.ToString
chaine -> Integer
Integer.Parse(tekenreeks) of Int32.Parse
chaîne -> Long
Long.Parse (reeks) of Int64.Parse
chaîne -> Double
Double.Parse (reeks)
chaîne -> Single
Single.Parse (tekenreeks)

De conversie van een tekenreeks naar een getal kan mislukken als de tekenreeks geen geldig getal vertegenwoordigt. Er wordt dan een fatale fout gegenereerd, in VB.NET een uitzondering genoemd. Deze fout kan worden afgehandeld met de volgende clausule try/catch:

try
        appel de la fonction susceptible de générer l'exception
 catch e as Exception
        traiter l'exception e
end try
instruction suivante

Als de functie geen uitzondering genereert, gaan we door naar de volgende instructie; anders gaan we naar de hoofdtekst van de clausule catch en vervolgens naar de volgende instructie. We zullen later terugkomen op het omgaan met uitzonderingen. Hier volgt een programma waarin de belangrijkste technieken voor het omzetten tussen getallen en tekenreeksen worden getoond. In dit voorbeeld geeft de functie de waarde van haar parameter op het scherm weer. Zo geeft affiche(S) de waarde van S op het scherm weer.


' richtlijnen
Option Strict On

' geïmporteerde naamruimten
Imports System

' de testmodule
Module Module1

    Sub Main()
        ' hoofdprocedure
        ' lokale gegevens
        Dim S As String
        Const i As Integer = 10
        Const l As Long = 100000
        Const f As Single = 45.78F
        Dim d As Double = -14.98

        ' getal --> tekenreeks
        affiche(CType(i, String))
        affiche(CType(l, String))
        affiche(CType(f, String))
        affiche(CType(d, String))

        'booleaanse waarde --> tekenreeks
        Const b As Boolean = False
        affiche(b.ToString)

        ' tekenreeks --> int
        Dim i1 As Integer = Integer.Parse("10")
        affiche(i1.ToString)
        Try
            i1 = Integer.Parse("10.67")
            affiche(i1.ToString)
        Catch e As Exception
            affiche("Erreur [10.67] : " + e.Message)
        End Try

        ' tekenreeks --> long
        Dim l1 As Long = Long.Parse("100")
        affiche("" + l1.ToString)
        Try
            l1 = Long.Parse("10.675")
            affiche("" & l1)
        Catch e As Exception
            affiche("Erreur [10.675] : " + e.Message)
        End Try

        ' tekenreeks --> double
        Dim d1 As Double = Double.Parse("100,87")
        affiche(d1.ToString)
        Try
            d1 = Double.Parse("abcd")
            affiche("" & d1)
        Catch e As Exception
            affiche("Erreur [abcd] : " + e.Message)
        End Try

        ' tekenreeks --> single
        Dim f1 As Single = Single.Parse("100,87")
        affiche(f1.ToString)
        Try
            d1 = Single.Parse("abcd")
            affiche(f1.ToString)
        Catch e As Exception
            affiche("Erreur [abcd] : " + e.Message)
        End Try
    End Sub

    ' weergeeft
    Public Sub affiche(ByVal S As String)
        Console.Out.WriteLine("S=" + S)
    End Sub
End Module

De verkregen resultaten zijn als volgt:

S=10
S=100000
S=45,78
S=-14,98
S=False
S=10
S=Erreur [10.67] : Le format de la chaîne d'entrée est incorrect.
S=100
S=Erreur [10.675] : Le format de la chaîne d'entrée est incorrect.
S=100,87
S=Erreur [abcd] : Le format de la chaîne d'entrée est incorrect.
S=100,87
S=Erreur [abcd] : Le format de la chaîne d'entrée est incorrect.

Let op: bij reële getallen in de vorm van een tekenreeks moet een komma worden gebruikt in plaats van een punt. We schrijven dus Dim d As Double = -14.98, maar Dim d1 As Double = Double.Parse("100,87")

2.2.5. Gegevenstabellen

Een array VB.NET is een object waarmee gegevens van hetzelfde type onder één identificatiecode kunnen worden gebundeld. De declaratie ervan is als volgt:

Dim Tabel(n) as type of Dim Tabel() as type = New type(n) {}

waarbij n de index is van het laatste element van de array. De syntaxis Tableau(i) verwijst naar het gegeven met nummer i, waarbij i tot het interval [0,n] behoort. Elke verwijzing naar het gegeven Tableau(i) waarbij i niet tot het interval [0,n] behoort, zal een uitzondering veroorzaken. Een array kan tegelijk met de declaratie worden geïnitialiseerd. In dat geval hoeft het nummer van het laatste element niet te worden opgegeven.


        Dim entiers() As Integer = {0, 10, 20, 30}

Arrays hebben een eigenschap Length, die het aantal elementen van de array aangeeft. Hier volgt een voorbeeldprogramma:


Module tab0
    Sub Main()
        ' een eerste tabel
        Dim tab0(5) As Integer
        For i As Integer = 0 To UBound(tab0)
            tab0(i) = i
        Next
        For i As Integer = 0 To UBound(tab0)
            Console.Out.WriteLine("tab0(" + i.ToString + ")=" + tab0(i).tostring)
        Next

        ' een tweede tabel
        Dim tab1() As Integer = New Integer(5) {}
        For i As Integer = 0 To tab1.Length - 1
            tab1(i) = i * 10
        Next
        For i As Integer = 0 To tab1.Length - 1
            Console.Out.WriteLine("tab1(" + i.ToString + ")=" + tab1(i).tostring)
        Next
    End Sub
End Module

en de uitvoering ervan:

tab0(0)=0
tab0(1)=1
tab0(2)=2
tab0(3)=3
tab0(4)=4
tab0(5)=5
tab1(0)=0
tab1(1)=10
tab1(2)=20
tab1(3)=30
tab1(4)=40
tab1(5)=50

Een tweedimensionale array kan als volgt worden gedeclareerd:

Dim Tabel(n,m) as Type of Dim Tabel(,) as Type = New Type(n,m) {}

waarbij n+1 het aantal rijen is en m+1 het aantal kolommen. De syntaxis Array(i,j) verwijst naar het j-de element van de i-de rij van Array. De tweedimensionale array kan ook tegelijk met de declaratie worden geïnitialiseerd:


        Dim réels(,) As Double = {{0.5, 1.7}, {8.4, -6}}

Het aantal elementen in elk van de dimensies kan worden verkregen met de methode GetLenth(i), waarbij i=0 de dimensie vertegenwoordigt die overeenkomt met de eerste index, i=1 de dimensie die overeenkomt met de tweede index, … Hier volgt een voorbeeldprogramma:


Module Module2
    Sub Main()
        ' een eerste tabel
        Dim tab0(2, 1) As Integer
        For i As Integer = 0 To UBound(tab0)
            For j As Integer = 0 To tab0.GetLength(1) - 1
                tab0(i, j) = i * 10 + j
            Next
        Next
        For i As Integer = 0 To UBound(tab0)
            For j As Integer = 0 To tab0.GetLength(1) - 1
                Console.Out.WriteLine("tab0(" + i.ToString + "," + j.ToString + ")=" + tab0(i, j).tostring)
            Next
        Next

        ' een tweede tabel
        Dim tab1(,) As Integer = New Integer(2, 1) {}
        For i As Integer = 0 To tab1.GetLength(0) - 1
            For j As Integer = 0 To tab1.GetLength(1) - 1
                tab1(i, j) = i * 100 + j
            Next
        Next
        For i As Integer = 0 To tab1.GetLength(0) - 1
            For j As Integer = 0 To tab1.GetLength(1) - 1
                Console.Out.WriteLine("tab1(" + i.ToString + "," + j.ToString + ")=" + tab1(i, j).tostring)
            Next
        Next
    End Sub
End Module

en de resultaten van de uitvoering ervan:

tab0(0)=0
tab0(1)=1
tab0(2)=2
tab0(3)=3
tab0(4)=4
tab0(5)=5
tab1(0)=0
tab1(1)=10
tab1(2)=20
tab1(3)=30
tab1(4)=40
tab1(5)=50

Een array van arrays wordt als volgt gedeclareerd:

Dim Array(n)() as Type of Dim Array()() as Type = new Type(n)()

De bovenstaande declaratie maakt een array met n+1 rijen aan. Elk element Array(i) is een verwijzing naar een eendimensionale array. Deze arrays worden niet aangemaakt bij de bovenstaande declaratie. Het onderstaande voorbeeld illustreert het aanmaken van een array van arrays:


         ' een tabel met tabellen
        Dim noms()() As String = New String(3)() {}
         ' initialisatie
        For i = 0 To noms.Length - 1
            noms(i) = New String(i) {}
            For j = 0 To noms(i).Length - 1
                noms(i)(j) = "nom" & i & j
            Next
        Next

Hier is noms(i) een array met i+1 elementen. Aangezien noms(i) een array is, is noms(i).Length het aantal elementen ervan. Hier volgt een voorbeeld waarin de drie soorten arrays die we zojuist hebben besproken, worden gecombineerd:


' richtlijnen
Option Strict On
Option Explicit On 

' imports
Imports System

' testklasse
Module test
    Sub main()
        ' een geïnitialiseerde eendimensionale array
        Dim entiers() As Integer = {0, 10, 20, 30}
        Dim i As Integer
        For i = 0 To entiers.Length - 1
            Console.Out.WriteLine("entiers[" & i & "]=" & entiers(i))
        Next

        ' een geïnitialiseerde tweedimensionale array
        Dim réels(,) As Double = {{0.5, 1.7}, {8.4, -6}}
        Dim j As Integer
        For i = 0 To réels.GetLength(0) - 1
            For j = 0 To réels.GetLength(1) - 1
                Console.Out.WriteLine("réels[" & i & "," & j & "]=" & réels(i, j))
            Next
        Next

        ' een array van arrays
        Dim noms()() As String = New String(3)() {}

        ' initialisatie
        For i = 0 To noms.Length°- 1
            noms(i) =°New String(i) {}
            For j = 0 To noms(i).Length - 1
                noms(i)(j) = "nom" & i & j
            Next
        Next

        ' weergave
        For i = 0 To noms.Length°- 1
            For j = 0 To noms(i).Length - 1
                Console.Out.WriteLine("noms[" & i & "][" & j & "]=" & noms(i)(j))
            Next
        Next
    End Sub
End Module

Bij uitvoering krijgen we de volgende resultaten:

entiers[0]=0
entiers[1]=10
entiers[2]=20
entiers[3]=30
réels[0,0]=0,5
réels[0,1]=1,7
réels[1,0]=8,4
réels[1,1]=-6
noms[0][0]=nom00
noms[1][0]=nom10
noms[1][1]=nom11
noms[2][0]=nom20
noms[2][1]=nom21
noms[2][2]=nom22
noms[3][0]=nom30
noms[3][1]=nom31
noms[3][2]=nom32
noms[3][3]=nom33

2.3. De basisinstructies van VB.NET

Er wordt onderscheid gemaakt tussen

1 de basisinstructies die door de computer worden uitgevoerd.

2 de instructies die de uitvoering van het programma sturen.

De basisinstructies worden duidelijk wanneer men de structuur van een microcomputer en zijn randapparatuur bekijkt.

  1. het uitlezen van informatie van het toetsenbord

  2. verwerking van informatie

  3. informatie op het scherm weergeven

  4. informatie uit een schijfbestand lezen

  5. informatie naar een bestand op de harde schijf schrijven

2.3.1. Schrijven naar het scherm

Er zijn verschillende instructies om informatie op het scherm weer te geven:

Console.Out.WriteLine(expression)
Console.WriteLine(expression)
Console.Error.WriteLine (expression)

waarbij expression elk gegevenstype is dat kan worden omgezet in een tekenreeks om op het scherm te worden weergegeven. In de voorbeelden die we tot nu toe hebben gezien, hebben we alleen de instructie Console.Out.WriteLine(uitdrukking) gebruikt.

De klasse System.Console biedt toegang tot schermschrijfbewerkingen (Write, WriteLine). De klasse Console heeft twee eigenschappen, Out en Error, die schrijfstromen zijn van het type StreamWriter:

  • Console.WriteLine() is gelijk aan Console.Out.WriteLine() en schrijft naar de Out-stream die doorgaans aan het scherm is gekoppeld.
  • Console.Error.WriteLine() schrijft naar de Error-stream, die doorgaans ook aan het scherm is gekoppeld.

De streams Out en Error zijn standaard gekoppeld aan het scherm. Maar ze kunnen tijdens de uitvoering van het programma worden omgeleid naar tekstbestanden, zoals we straks zullen zien.

2.3.2. Gegevens van het toetsenbord lezen

De gegevensstroom afkomstig van het toetsenbord wordt aangeduid door het object Console.In van het type StreamReader. Met dit type objecten kan een tekstregel worden gelezen met de methode ReadLine:


        Dim ligne As String = Console.In.ReadLine()

De via het toetsenbord ingevoerde regel wordt opgeslagen in de variabele ligne en kan vervolgens worden verwerkt door de programme.Le. De In-stroom kan, net als de Out- en Error-stromen, naar een bestand worden omgeleid.

2.3.3. Voorbeeld van invoer en uitvoer

Hier volgt een kort programma ter illustratie van de invoer- en uitvoerbewerkingen via toetsenbord en scherm:


' opties
Option Explicit On 
Option Strict On

' naamruimten
Imports System

' module
Module io1
    Sub Main()
        ' schrijven naar de Out-stream
        Dim obj As New Object
        Console.Out.WriteLine(("" & obj.ToString))

        ' schrijven naar de Error-stream
        Dim i As Integer = 10
        Console.Error.WriteLine(("i=" & i))

        ' een via het toetsenbord ingevoerde regel lezen
        Console.Out.Write("Tapez une ligne : ")
        Dim ligne As String = Console.In.ReadLine()
        Console.Out.WriteLine(("ligne=" + ligne))
    End Sub
End Module

en de resultaten van de uitvoering:

System.Object
i=10
Tapez une ligne : ceci est un essai
ligne=ceci est un essai

De instructies


        Dim obj As New Object
        Console.Out.WriteLine(obj.ToString)

zijn alleen bedoeld om aan te tonen dat elk willekeurig object kan worden weergegeven. We zullen hier niet ingaan op de betekenis van wat er wordt weergegeven.

2.3.4. Omleiding van I/O

Onder DOS/Windows bestaan er drie standaardapparaten, namelijk:

  1. standaard invoerapparaat – verwijst standaard naar het toetsenbord en heeft nummer 0
  2. standaarduitvoerapparaat – verwijst standaard naar het beeldscherm en heeft nummer 1
  3. standaardfoutapparaat – verwijst standaard naar het scherm en heeft nummer 2

In VB.NET schrijft de schrijfstroom Console.Out naar apparaat 1, schrijft de schrijfstroom Console.Error naar apparaat 2 en leest de leesstroom Console.In gegevens van apparaat 0. Wanneer je een programma start in een DOS-venster onder Windows, kun je instellen welke apparaten 0, 1 en 2 zullen zijn voor het uitgevoerde programma. Laten we de volgende opdrachtregel eens bekijken:

pg arg1 arg2 .. argn

Met behulp van de argumenten argi van het programma pg kunnen standaard I/O-apparaten naar bestanden worden omgeleid:

0<in.txt
de standaardinvoerstroom nr. 0 wordt omgeleid naar het bestand in.txt. In het programma haalt de stroom Console.In zijn gegevens dus uit het bestand in.txt.
 
1>out.txt
leidt uitvoer nr. 1 om naar het bestand out.txt. Dit heeft tot gevolg dat in het programma de stroom Console.Out zijn gegevens naar het bestand out.txt schrijft
  
1>>out.txt
idem, maar de geschreven gegevens worden toegevoegd aan de huidige inhoud van het bestand out.txt.
  
2>error.txt
leidt uitvoer nr. 2 om naar het bestand error.txt. Dit heeft tot gevolg dat in het programma de stream Console.Error zijn gegevens naar het bestand error.txt zal schrijven
  
2>>error.txt
idem, maar de geschreven gegevens worden toegevoegd aan de huidige inhoud van het bestand error.txt.
  
1>out.txt 2>error.txt
De apparaten 1 en 2 worden beide omgeleid naar bestanden
  

Merk op dat het programma pg niet hoeft te worden aangepast om de I/O-stromen van het programma pg naar bestanden om te leiden. Het is het programma OS dat de aard van de apparaten 0, 1 en 2 bepaalt. Laten we het volgende programma eens bekijken:


' opties
Option Explicit On 
Option Strict On

' naamruimten
Imports System

' omleidingen
Module console2
    Sub Main()
        ' In-stream lezen
        Dim data As String = Console.In.ReadLine()
        ' Out-stream schrijven
        Console.Out.WriteLine(("écriture dans flux Out : " + data))
        ' schrijven van foutstroom
        Console.Error.WriteLine(("écriture dans flux Error : " + data))
    End Sub
End Module

Laten we dit programma compileren:

dos>vbc es2.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573
Copyright (C) Microsoft Corporation 1987-2002. Tous droits réservés.

dos>dir
24/02/2004  15:39                  416 es2.vb
11/03/2004  08:20                3 584 es2.exe

Laten we een eerste uitvoering doen:

dos>es2.exe
un premier test
écriture dans flux Out : un premier test
écriture dans flux Error : un premier test

De vorige uitvoering leidt geen van de standaard I/O-stromen In, Out en Error om. We gaan nu alle drie de stromen omleiden. De stroom In wordt omgeleid naar een bestand in.txt, de stroom Out naar het bestand out.txt, de stroom Error naar het bestand error.txt. Deze omleiding vindt plaats op de opdrachtregel in de vorm

dos>es2.exe 0<in.txt 1>out.txt 2>error.txt

De uitvoering levert de volgende resultaten op:

dos>more in.txt
un second test

dos>es2.exe 0<in.txt 1>out.txt 2>error.txt

dos>more out.txt
écriture dans flux Out : un second test

dos>more error.txt
écriture dans flux Error : un second test

Het is duidelijk te zien dat de stromen Out en Error niet naar dezelfde apparaten schrijven.

2.3.5. De waarde van een uitdrukking toewijzen aan een variabele

We kijken hier naar de bewerking variable=expression.. De uitdrukking kan van het volgende type zijn: rekenkundig, relationeel, booleaans of tekenreeks.

2.3.5.1. Lijst met operatoren

Actie
Taalelement
Arithmétique
^, –, *, /, \, Mod, +, =
Assignation
=, ^=, *=, /=, \=, +=, -=, &=
Comparaison
=, <>, <, >, <=, >=, Like, Is
Concaténation
&, +
Opérations logiques/de bits
Not, And, Or, Xor, AndAlso, OrElse
Opérations diverses
AddressOf, GetType

2.3.5.2. Rekenkundige uitdrukking

De operatoren voor rekenuitdrukkingen zijn de volgende:

Arithmétique
^, –, *, /, \, Mod, +, =

+: optellen, -: aftrekken, *: vermenigvuldigen, /: reële deling, \: quotiënt van gehele deling, Mod: rest van gehele deling, ^: tot de macht verheffen. Het volgende programma:


' rekenkundige operatoren
Module operateursarithmetiques
    Sub Main()
        Dim i, j As Integer
        i = 4 : j = 3
        Console.Out.WriteLine(i & "/" & j & "=" & (i / j))
        Console.Out.WriteLine(i & "\" & j & "=" & (i \ j))
        Console.Out.WriteLine(i & " mod " & j & "=" & (i Mod j))

        Dim r1, r2 As Double
        r1 = 4.1 : r2 = 3.6
        Console.Out.WriteLine(r1 & "/" & r2 & "=" & (r1 / r2))
        Console.Out.WriteLine(r1 & "^2=" & (r1 ^ 2))
        Console.Out.WriteLine(Math.Cos(3))
    End Sub
End Module

levert de volgende resultaten op:

4/3=1,33333333333333
4\3=1
4 mod 3=1
4,1/3,6=1,13888888888889
4,1^2=16,81
-0,989992496600445

Er bestaan verschillende wiskundige functies. Hier volgen er enkele:


Public Shared Function Sqrt(ByVal d As Double ) As Double
vierkantswortel

[Visual Basic]
Public Shared Function Cos(ByVal d As Double ) As Double
Cosinus

Public Shared Function Sin(ByVal a As Double) As Double
Sinus

[Visual Basic]
Public Shared Function Tan(ByVal a As Double) As Double
Tangens

[Visual Basic]
Public Shared Function Pow(ByVal x As Double,ByVal y As Double) As Double
x tot de macht y (x>0)

[Visual Basic]
Public Shared Function Exp(ByVal d As Double) As Double
Exponentieel

[Visual Basic]
Overloads Public Shared Function Log( ByVal d As Double ) As Double
Natuurlogaritme

Overloads Public Shared Function Abs(ByVal value As Double ) As Double
absolute waarde
....
 

Al deze functies zijn gedefinieerd in een klasse .NET met de naam Math. Wanneer men ze gebruikt, moet men ze vooraf laten gaan door de naam van de klasse waarin ze zijn gedefinieerd. Men schrijft dus:

        Dim r1, r2 As Double
        r2 = Math.Sqrt(9)
        r1 = Math.Cos(3)

De volledige definitie van de klasse Math is als volgt:

E 
Vertegenwoordigt de basis van de natuurlijke logaritme, gespecificeerd door de constante e.
  
PI 
Vertegenwoordigt de verhouding tussen de omtrek van een cirkel en de diameter ervan, gespecificeerd door de constante π.
  
Abs 
Overschreven. Geeft de absolute waarde van een opgegeven getal terug.
 
Acos 
Geeft de hoek terug waarvan de cosinus het opgegeven getal is.
 
Asin 
Geeft de hoek terug waarvan de sinus het opgegeven getal is.
 
Atan 
Geeft de hoek terug waarvan de tangens het opgegeven getal is.
 
Atan2 
Geeft de hoek terug waarvan de tangens het quotiënt is van twee opgegeven getallen.
 
BigMul
Genereert het integraalproduct van twee 32-bits getallen.
 
Ceiling 
Geeft het kleinste gehele getal terug dat groter is dan of gelijk is aan het opgegeven getal.
 
Cos 
Geeft de cosinus van de opgegeven hoek terug.
 
Cosh 
Geeft de hyperbolische cosinus van de opgegeven hoek terug.
 
DivRem
Overschreven. Geeft het quotiënt van twee getallen terug, waarbij de rest als uitvoerparameter wordt doorgegeven.
 
Exp 
Geeft e tot de opgegeven macht terug.
 
Floor 
Geeft het grootste gehele getal terug dat kleiner is dan of gelijk is aan het opgegeven getal.
 
IEEERemainder 
Geeft de rest van de deling van een opgegeven getal door een ander getal terug.
 
Log 
Overschreven. Geeft de logaritme van een opgegeven getal terug.
 
Log10 
Geeft de logaritme met basis 10 van een opgegeven getal terug.
 
Max 
Overschreven. Geeft het grootste van twee opgegeven getallen terug.
 
Min 
Overbelasting. Geeft het kleinste van twee getallen terug.
 
Pow 
Geeft een opgegeven getal tot de opgegeven macht terug.
 
Round 
Overschreven. Geeft het getal terug dat het dichtst bij de opgegeven waarde ligt.
 
Sign 
Overschreven. Geeft een waarde terug die het teken van een getal aangeeft.
 
Sin 
Geeft de sinus van de opgegeven hoek terug.
 
Sinh 
Geeft de hyperbolische sinus van de opgegeven hoek terug.
 
Sqrt 
Geeft de vierkantswortel van een opgegeven getal terug.
 
Tan 
Geeft de tangens van de opgegeven hoek terug.
 
Tanh 
Geeft de hyperbolische tangens van de opgegeven hoek terug.
 

Wanneer een functie als "overladen" wordt aangeduid, betekent dit dat deze voor verschillende typen parameters bestaat. De functie Abs(x) bestaat bijvoorbeeld voor x van het type Integer, Long, Decimal, Single en Float. Voor elk van deze typen bestaat er een afzonderlijke definitie van de functie Abs. We zeggen dan dat deze overladen is.

2.3.5.3. Prioriteiten bij het evalueren van rekenkundige uitdrukkingen

De prioriteit van operatoren bij het evalueren van een rekenuitdrukking is als volgt (van hoogste naar laagste prioriteit):

Categorie
Operatoren
Primaire
Alle uitdrukkingen zonder operator: functies, haakjes
Élévation à la puissance
^
Négation unaire
+, -
Multiplication
*, /
Division par un entier
\
Modulo
Mod
Addition
+, -

2.3.5.4. Relationele uitdrukkingen

De operatoren zijn als volgt:

Comparaison
=, <>, <, >, <=, >=, Like, Is

=: gelijk aan, <>: verschillend van, <: kleiner dan (strikt), >: groter dan (strikt), <=: kleiner dan of gelijk aan, >=: groter dan of gelijk aan, Like: komt overeen met een patroon, Is: identiteit van objecten. Al deze operatoren hebben dezelfde prioriteit. Ze worden van links naar rechts geëvalueerd. Het resultaat van een relationele uitdrukking is een booleaanse waarde.

Vergelijking van tekenreeksen: laten we het volgende programma eens bekijken:


' naamruimten
Imports System

Module string1
    Sub main()
        Dim ch1 As Char = "A"c
        Dim ch2 As Char = "B"c
        Dim ch3 As Char = "a"c
        Console.Out.WriteLine("A<B=" & (ch1 < ch2))
        Console.Out.WriteLine("A<a=" & (ch1 < ch3))
        Dim chat As String = "chat"
        Dim chien As String = "chien"
        Dim chaton As String = "chaton"
        Dim chat2 As String = "CHAT"
        Console.Out.WriteLine("chat<chien=" & (chat < chien))
        Console.Out.WriteLine("chat<chaton=" & (chat < chaton))
        Console.Out.WriteLine("chat<CHAT=" & (chat < chat2))
        Console.Out.WriteLine("chaton like chat*=" & ("chaton" Like "chat*"))
    End Sub
End Module

en het resultaat van de uitvoering ervan:

A<B=True
A<a=True
chat<chien=True
chat<chaton=True
chat<CHAT=False
chaton like chat*=True

Stel dat we twee tekens hebben: C1 en C2. Deze kunnen worden vergeleken met de vergelijkingsoperatoren: <, <=, =, <>, >, >=. Daarbij worden de Unicode-waarden van de tekens, die getallen zijn, met elkaar vergeleken. Volgens de Unicode-volgorde gelden de volgende relaties:

spatie < .. < '0' < '1' < .. < '9' < .. < 'A' < 'B' < .. < 'Z' < .. < 'a' < 'b' < .. < 'z'

Tekenreeksen worden teken voor teken vergeleken. De eerste ongelijkheid die tussen twee tekens wordt aangetroffen, leidt tot een ongelijkheid in dezelfde richting voor de tekenreeksen. Met deze uitleg wordt de lezer uitgenodigd om de resultaten van het vorige programma te bestuderen.

2.3.5.5. Booleaanse uitdrukkingen

De operatoren zijn als volgt:

Opérations logiques/de bits
Not, And, Or, Xor, AndAlso, OrElse

Not: logisch 'en', Or: logisch 'of', Not: ontkenning, Xor: exclusief 'of'.

op1 AndAlso op2: als op1 onwaar is, wordt op2 niet geëvalueerd en is het resultaat onwaar.

op1 OrElse op2: als op1 waar is, wordt op2 niet geëvalueerd en is het resultaat waar.

De prioriteit van deze operatoren ten opzichte van elkaar is als volgt:

NOT logique
Not
AND logique
En, AndAlso
OR logique
Of, OrElse
XOR logique
XOR

Het resultaat van een Booleaanse uitdrukking is een Booleaanse waarde.

2.3.5.6. Bitbewerkingen

Enerzijds zijn er dezelfde operatoren als bij de Booleaanse operatoren, met dezelfde prioriteit. Daarnaast zijn er twee verschuivingsoperatoren: << en >>. Stel dat i en j twee gehele getallen zijn.

i<<n
verschuift i n bits naar links. De nieuwe bits zijn nullen.
i>>n
verschuift i n bits naar rechts. Als i een geheel getal met teken is (signed char, int, long), blijft het tekenbit behouden.
i & j
voert de bit-voor-bit logische OR-bewerking uit tussen i en j.
i | j
voert de bit-voor-bit logische OR-bewerking uit tussen i en j (OU).
~i
vult i aan tot 1
i^j
maakt de OU EXCLUSIF van i en j

Stel dat het volgende programma bestaat:


Module operationsbit
    Sub main()
        ' bitbewerkingen
        Dim i As Short = &H123F
        Dim k As Short = &H7123
        Console.Out.WriteLine("i<<4=" & (i << 4).ToString("X"))
        Console.Out.WriteLine("i>>4=" & (i >> 4).ToString("X"))
        Console.Out.WriteLine("k>>4=" & (k >> 4).ToString("X"))
        Console.Out.WriteLine("i and 4=" & (i And 4).ToString("X"))
        Console.Out.WriteLine("i or 4 =" & (i Or 4).ToString("X"))
        Console.Out.WriteLine("not i=" & (Not i).ToString("X"))
    End Sub
End Module

De uitvoering ervan levert de volgende resultaten op:

i<<4=23F0
i>>4=123
k>>4=712
i and 4=4
i or k =123F
not i=EDC0

2.3.5.7. Operator in combinatie met een toewijzing

Het is mogelijk om a+=b te schrijven, wat a=a+b betekent. De lijst met operatoren die met de toewijzingsbewerking kunnen worden gecombineerd, is als volgt:

combinaison d'opérateurs
^=, *=, /=, \=, +=, -=, &=

2.3.5.8. Algemene prioriteit van operatoren

Categorie
Operatoren
Primaire
Alle uitdrukkingen zonder operator
Élévation à la puissance
^
Négation unaire
+, -
Multiplication
*, /
Division par un entier
\
Modulo
Mod
Addition
+, -
Concaténation
&
Déplacement
<<, >>
Relationnel
=, <>, <, >, <=, >=, Like, Is, TypeOf...Is
NOT logique
Niet
AND logique
En, AndAlso
OR logique
Of, OrElse
XOR logique
XOR

Wanneer een operand tussen twee operatoren met dezelfde prioriteit staat, bepaalt de associativiteit van de operatoren de volgorde waarin de bewerkingen worden uitgevoerd. Alle operatoren zijn linksassociatief, wat betekent dat de bewerkingen van links naar rechts worden uitgevoerd. De prioriteit en de associativiteit kunnen worden geregeld met behulp van uitdrukkingen tussen haakjes.

2.3.5.9. Typeomzettingen

Er zijn een aantal vooraf gedefinieerde functies waarmee van het ene gegevenstype naar het andere kan worden geconverteerd. Dit zijn:

CBool,CByte,CChar,CDate,CDbl,CDec,CInt,CLng,CObj,CShort,CSng,CStr

Deze functies accepteren als argument een numerieke uitdrukking of een tekenreeks. Het type van het resultaat wordt weergegeven in de volgende tabel:

functie
resultaat
Waardegebied van de functieparameter
CBool
Boolean
Elke geldige tekenreeks of numerieke uitdrukking.
CByte
Byte
0 tot 255; breuken worden afgerond.
CChar
Tekenteken
Elke geldige tekenreeks; de waarde kan tussen 0 en 65 535 liggen.
CDate
Date
Elke geldige weergave van datum en tijd.
CDbl
Double
-1,79769313486231E+308 tot
-4,94065645841247E-324 voor negatieve waarden; 4,94065645841247E-324 tot 1,79769313486231E+308 voor positieve waarden.
CDec
Decimaal
+/-79 228 162 514 264 337 593 543 950 335 voor getallen zonder decimalen. Het waardebereik van getallen met 28 decimalen is
+/-7,9228162514264337593543950335. Het kleinste getal dat niet nul is, is 0,0000000000000000000000000001.
CInt
Geheel getal
-2 147 483 648 tot 2 147 483 647; breuken worden afgerond.
CLng
Long
-9 223 372 036 854 775 808 tot 9 223 372 036 854 775 807; breuken worden afgerond.

CObj 
Object
Elke geldige uitdrukking.
CShort
Kort
-32 768 tot 32 767; breuken worden afgerond.
CSng
Single
-3,402823E+38 tot -1,401298E-45 voor negatieve waarden; 1,401298E-45 tot 3,402823E+38 voor positieve waarden.
CStr
String
De waarden die door de functie Cstr worden geretourneerd, zijn afhankelijk van het argument expression.

Hier volgt een voorbeeldprogramma:


Module conversion
    Sub main()
        Dim var1 As Boolean = CBool("true")
        Dim var2 As Byte = CByte("100")
        Dim var3 As Char = CChar("A")
        Dim var4 As Date = CDate("30 janvier 2004")
        Dim var5 As Double = CDbl("100,45")
        Dim var6 As Decimal = CDec("1000,67")
        Dim var7 As Integer = CInt("-30")
        Dim var8 As Long = CLng("456")
        Dim var9 As Short = CShort("-14")
        Dim var10 As Single = CSng("56,78")
        Console.Out.WriteLine("var1=" & var1)
        Console.Out.WriteLine("var2=" & var2)
        Console.Out.WriteLine("var3=" & var3)
        Console.Out.WriteLine("var4=" & var4)
        Console.Out.WriteLine("var5=" & var5)
        Console.Out.WriteLine("var6=" & var6)
        Console.Out.WriteLine("var7=" & var7)
        Console.Out.WriteLine("var8=" & var8)
        Console.Out.WriteLine("var9=" & var9)
        Console.Out.WriteLine("var10=" & var10)
    End Sub
End Module

en de resultaten van de uitvoering ervan:

var1=True
var2=100
var3=A
var4=30/01/2004
var5=100,45
var6=1000,67
var7=-30
var8=456
var9=-14
var10=56,78

Men kan ook de functie CType(expression, type) gebruiken, zoals in het volgende programma wordt getoond:


Module ctype1
    Sub main()
        Dim var1 As Boolean = CType("true", Boolean)
        Dim var2 As Byte = CType("100", Byte)
        Dim var3 As Char = CType("A", Char)
        Dim var4 As Date = CType("30 janvier 2004", Date)
        Dim var5 As Double = CType("100,45", Double)
        Dim var6 As Decimal = CType("1000,67", Decimal)
        Dim var7 As Integer = CType("-30", Integer)
        Dim var8 As Long = CType("456", Long)
        Dim var9 As Short = CType("-14", Short)
        Dim var10 As Single = CType("56,78", Single)
        Dim var11 As String = CType("47,89", String)
        Dim var12 As String = 47.89.ToString
        Dim var13 As String = "" & 47.89
        Console.Out.WriteLine("var1=" & var1)
        Console.Out.WriteLine("var2=" & var2)
        Console.Out.WriteLine("var3=" & var3)
        Console.Out.WriteLine("var4=" & var4)
        Console.Out.WriteLine("var5=" & var5)
        Console.Out.WriteLine("var6=" & var6)
        Console.Out.WriteLine("var7=" & var7)
        Console.Out.WriteLine("var8=" & var8)
        Console.Out.WriteLine("var9=" & var9)
        Console.Out.WriteLine("var10=" & var10)
        Console.Out.WriteLine("var11=" & var11)
        Console.Out.WriteLine("var12=" & var12)
        Console.Out.WriteLine("var13=" & var13)
    End Sub
End Module

wat de volgende resultaten oplevert:

var1=True
var2=100
var3=A
var4=30/01/2004
var5=100,45
var6=1000,67
var7=-30
var8=456
var9=-14
var10=56,78
var11=47,89
var12=47,89
var13=47,89

2.4. Instructies voor het controleren van het verloop van het programma

2.4.1. Stoppen

Met de methode Exit, gedefinieerd in de klasse Environment, kan de uitvoering van een programma worden gestopt:


[Visual Basic]
Public Shared Sub Exit(ByVal exitCode As Integer )

stopt het lopende proces en geeft de waarde exitCode terug aan het bovenliggende proces. De waarde van exitCode kan door het bovenliggende proces worden gebruikt. Onder DOS wordt deze statusvariabele teruggegeven aan DOS in de systeemvariabele ERRORLEVEL, waarvan de waarde in een batchbestand kan worden getest. Onder Unix is het de variabele $? die de waarde van exitCode ophaalt.

    Environment.Exit(0)

stopt de uitvoering van het programma met een statuswaarde van 0.

2.4.2. Eenvoudige keuzestructuur

if condition then
    actions_alors
else
    actions_sinon
end if
  • elke actie staat op een aparte regel
  • de clausule else kan ontbreken.

Keuzestructuren kunnen in elkaar worden genest, zoals in het volgende voorbeeld te zien is:


' opties
Option Explicit On 
Option Strict On

' naamruimten
Imports System

Module if1
    Sub main()
        Dim i As Integer = 10
        If i > 4 Then
            Console.Out.WriteLine(i & " est > " & 4)
        Else
            If i = 4 Then
                Console.Out.WriteLine(i & " est = " & 4)
            Else
                Console.Out.WriteLine(i & " est < " & 4)
            End If
        End If
    End Sub
End Module

Het verkregen resultaat:

10 est > 4

2.4.3. Casestructuur

De syntaxis is als volgt:

select case expression
    case liste_valeurs1
        actions1
case liste_valeurs2
        actions2
...
case else
        actions_sinon
end select
  • het type van [expression] moet een van de volgende typen zijn:
Boolean, Byte, Char, Date, Decimal, Double, Integer, Long, Object, Short, Single et String
  • de clausule [case else] mag ontbreken.
  • [liste_valeursi] zijn mogelijke waarden van de uitdrukking. [listes_valeursi] vertegenwoordigt een lijst met voorwaarden: voorwaarde1, voorwaarde2, ..., voorwaardex. Als [expression] aan een van de voorwaarden voldoet, worden de acties achter de clausule [liste_valeursi] uitgevoerd. De voorwaarden kunnen de volgende vorm aannemen:
  • val1 to val2: waar als [expression] tot het domein [val1,val2] behoort
  • val1: waar als [expression] gelijk is aan val1
  • is > val1: waar als [expression] > val1. Het sleutelwoord [is] mag ontbreken
  • hetzelfde geldt voor de operatoren =, <, <=, >, >=, <>
  • alleen de acties die verband houden met de eerste gecontroleerde voorwaarde worden uitgevoerd.

Laten we het volgende programma eens bekijken:


' opties
Option Explicit On 
Option Strict On

' naamruimten
Imports System

Module selectcase1
    Sub main()
        Dim i As Integer = 10
        Select Case i
            Case 1 To 4, 7 To 8
                Console.Out.WriteLine("i est dans l'intervalle [1,4] ou [7,8]")
            Case Is > 12
                Console.Out.WriteLine("i est > 12")
            Case Is < 15
                Console.Out.WriteLine("i est < 15")
            Case Is < 20
                Console.Out.WriteLine("i est < 20")
        End Select
    End Sub
End Module

Dit levert de volgende resultaten op:

i est < 15

2.4.4. Herhalingsstructuur

2.4.4.1. Aantal herhalingen bekend


For counter [ As datatype ] = start To end [ Step step ]
   actions
Next [ counter ]

De acties worden uitgevoerd voor elke waarde die de variabele [counter] aanneemt. Laten we het volgende programma eens bekijken:


' opties
Option Explicit On 
Option Strict On

' naamruimten
Imports System

Module for1
    Sub main()
        Dim somme As Integer = 0
        Dim résultat As String = "somme("
        For i As Integer = 0 To 10 Step 2
            somme += i
            résultat += " " + i.ToString
        Next
        résultat += ")=" + somme.ToString
        Console.Out.WriteLine(résultat)
    End Sub
End Module

De resultaten:

somme( 0 2 4 6 8 10)=30

Een andere iteratiestructuur met een bekend aantal iteraties is de volgende:


For Each element [ As datatype ] In groupe
   [ actions ]
Next [ element ]
  • groupe is een verzameling objecten. De verzameling objecten die we al kennen, is de array
  • datatype is het type van de objecten in de verzameling. Voor een array zou dit het type van de elementen van de array zijn
  • element is een lokale variabele van de lus die achtereenvolgens alle waarden uit de verzameling als waarde zal aannemen.

De volgende code:


' opties
Option Explicit On 
Option Strict On

' naamruimten
Imports System

Module foreach1
    Sub main()
        Dim amis() As String = {"paul", "hélène", "jacques", "sylvie"}
        For Each nom As String In amis
            Console.Out.WriteLine(nom)
        Next
    End Sub
End Module

zou het volgende weergeven:

paul
hélène
jacques
sylvie

2.4.4.2. Aantal herhalingen onbekend

Er zijn talrijke structuren in VB.NET voor dit geval.


Do { While | Until } condition
   [ statements ]
Loop

De lus wordt herhaald zolang aan de voorwaarde wordt voldaan (while) of totdat aan de voorwaarde wordt voldaan (until). Het kan zijn dat de lus nooit wordt uitgevoerd.


Do
   [ statements ]
Loop { While | Until } condition

De lus wordt herhaald zolang aan de voorwaarde wordt voldaan (while) of totdat aan de voorwaarde wordt voldaan (until). De lus wordt altijd minstens één keer uitgevoerd.


While condition
   [ statements ]
End While

De lus wordt herhaald zolang aan de voorwaarde wordt voldaan. Het kan zijn dat de lus nooit wordt uitgevoerd. De volgende lussen berekenen allemaal de som van de eerste 10 gehele getallen.


' opties
Option Explicit On 
Option Strict On

' naamruimten
Imports System

Module boucles1
    Sub main()
        Dim i, somme As Integer
        i = 0 : somme = 0
        Do While i < 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do Until i = 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop Until i = 11
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop While i < 11
        Console.Out.WriteLine("somme=" + somme.ToString)
    End Sub
End Module
somme=55
somme=55
somme=55
somme=55

2.4.4.3. Instructies voor het beheren van lussen

exit do
verlaat een do ... loop-lus
exit for
verlaat een for-lus

2.5. De structuur van een programma VB.NET

Een programma VB.NET dat geen door de gebruiker gedefinieerde klasse of andere functies dan de hoofdfunctie Main gebruikt, kan de volgende structuur hebben:


' opties
Option Explicit On 
Option Strict On

' naamruimten
Imports espace1
Imports ....

Module nomDuModule
    Sub main()
....
    End Sub
End Module
  • De richtlijn [Option Explicit on] dwingt het declareren van variabelen af. In VB.NET is dit niet verplicht. Een niet-gedeclareerde variabele is dan van het type Object.
  • De richtlijn [Option Strict on] verbiedt elke conversie van gegevenstypen die tot gegevensverlies kan leiden, evenals elke conversie tussen numerieke typen en tekenreeksen. Er moet dan expliciet gebruik worden gemaakt van conversiefuncties.
  • Het programma importeert alle naamruimten die het nodig heeft. Dit begrip hebben we nog niet geïntroduceerd. In de voorgaande programma’s zijn we vaak instructies tegengekomen van het type:
        Console.Out.WriteLine(unechaine)

We hadden eigenlijk moeten schrijven:

        System.Console.Out.WriteLine(unechaine)

waarbij System de naamruimte is die de klasse [Console] bevat. Door de naamruimte [System] met een Imports-instructie te importeren, zal VB.NET deze systematisch doorzoeken wanneer het een onbekende klasse tegenkomt. Het herhaalt de zoekopdracht met alle gedeclareerde naamruimten totdat de gezochte klasse is gevonden. We schrijven dan:


' naamruimten
Imports System
....

        Console.Out.WriteLine(unechaine)

Een voorbeeld van een programma zou er als volgt uit kunnen zien:


' opties
Option Explicit On 
Option Strict On

'naamruimten
Imports System

' hoofdmodule
Module main1
    Sub main()
        Console.Out.WriteLine("main1")
    End Sub
End Module

Hetzelfde programma kan als volgt worden geschreven:


' opties
Option Explicit On 
Option Strict On

'naamruimten
Imports System

' testklasse
Public Class main2
    Public Shared Sub main()
        Console.Out.WriteLine("main2")
    End Sub
End Class

Hier maken we gebruik van het concept van klassen, dat in het volgende hoofdstuk wordt geïntroduceerd. Wanneer een dergelijke klasse een statische (shared) procedure met de naam main bevat, wordt deze uitgevoerd. We introduceren deze schrijfwijze hier omdat de zustertaal van VB.NET, namelijk C#, alleen het concept van klassen kent, c.a.d, en dat alle uitgevoerde code noodzakelijkerwijs tot een klasse behoort. Het begrip ‘klasse’ hoort thuis in de objectgeoriënteerde programmering. Het is enigszins onhandig om dit bij het ontwerpen van elk programma op te leggen. Dit zien we hier in versie 2 van het vorige programma, waar we genoodzaakt zijn het concept van een klasse en een statische methode in te voeren terwijl dat niet nodig is. Daarom zullen we het concept van een klasse voortaan alleen introduceren wanneer dat noodzakelijk is. In de overige gevallen zullen we het begrip ‘module’ gebruiken, zoals in versie 1 hierboven.

2.6. Compileren en uitvoeren van een programma VB.NET

Voor het compileren van een programma VB.NET is alleen SDK.NET nodig. Laten we het volgende programma nemen:


' opties
Option Explicit On 
Option Strict On

' naamruimten
Imports System

Module boucles1
    Sub main()
        Dim i, somme As Integer
        i = 0 : somme = 0
        Do While i < 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do Until i = 11
            somme += i
            i += 1
        Loop
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop Until i = 11
        Console.Out.WriteLine("somme=" + somme.ToString)
        i = 0 : somme = 0
        Do
            somme += i
            i += 1
        Loop While i < 11
        Console.Out.WriteLine("somme=" + somme.ToString)
    End Sub
End Module

Stel dat dit in een bestand met de naam [boucles1.vb] staat. Om het te compileren, gaan we als volgt te werk:

dos>dir boucles1.vb
11/03/2004  15:55                  583 boucles1.vb

dos>vbc boucles1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
pour Microsoft (R) .NET Framework version 1.1.4322.573
Copyright (C) Microsoft Corporation 1987-2002. Tous droits réservés.

dos>dir boucles1.*
11/03/2004  16:04                  601 boucles1.vb
11/03/2004  16:04                3 584 boucles1.exe

Het programma vbc.exe is de compiler VB.NET. Hier stond het in de PATH van de DOS:


dos>path
PATH=E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE;E:\Program Files\Microsoft Visual Studio .NET 2003\VC7\BIN;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin\prerelease;E:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\bin;E:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\bin;E:\WINNT\Microsoft.NET\Framework\v1.1.4322;e:\winnt\system32;e:\winnt;

dos>dir E:\WINNT\Microsoft.NET\Framework\v1.1.4322\vbc.exe
21/02/2003  10:20              737 280 vbc.exe

De compiler [vbc] genereert een .exe-bestand dat door de virtuele machine kan worden uitgevoerd. NET:

dos>boucles1
somme=55
somme=55
somme=55
somme=55

2.7. Het voorbeeld IMPOTS

We willen een programma schrijven waarmee de belasting van een belastingplichtige kan worden berekend. We gaan uit van het vereenvoudigde geval van een belastingplichtige die alleen zijn salaris hoeft aan te geven:

  • we berekenen het aantal aandelen van de werknemer nbParts=nbEnfants/2 +1 als hij ongehuwd is, nbEnfants/2+2 als hij getrouwd is, waarbij nbEnfants het aantal kinderen is.
  • als hij ten minste drie kinderen heeft, krijgt hij een half extra aandeel
  • zijn belastbaar inkomen wordt berekend als R = 0,72 * S, waarbij S zijn jaarsalaris is
  • we berekenen zijn gezinscoëfficiënt QF = R / nbParts
  • zijn belasting I wordt berekend. Laten we de volgende tabel bekijken:
12620,0
0
0
13190
0,05
631
15640
0,1
1290,5
24.740
0,15
2072,5
31810
0,2
3309,5
39.970
0,25
4900
48360
0,3
6898,5
55790
0,35
9316,5
92970
0,4
12106
127.860
0,45
16754,5
151250
0,50
23.147,5
172.040
0,55
30710
195.000
0,60
39312
0
0,65
49062

Elke regel heeft 3 velden. Om belasting I te berekenen, zoeken we de eerste regel waar QF <= veld1. Als QF bijvoorbeeld 23000 is, vinden we de regel

    24740        0.15        2072.5

Belasting I is dan gelijk aan 0,15*R - 2072,5*nbParts. Als QF zodanig is dat de relatie QF<=veld1 nooit geldt, dan worden de coëfficiënten van de laatste regel gebruikt. In dit geval:

    0                0.65        49062

wat de belasting I = 0,65*R - 49062*nbParts oplevert. Het bijbehorende programma VB.NET is als volgt:


' opties
Option Explicit On 
Option Strict On

' naamruimten
Imports System

Module impots
    ' ------------ main
    Sub Main()

        ' gegevenstabellen die nodig zijn voor de berekening van de belasting
        Dim Limites() As Decimal = {12620D, 13190D, 15640D, 24740D, 31810D, 39970D, 48360D, 55790D, 92970D, 127860D, 151250D, 172040D, 195000D, 0D}
        Dim CoeffN() As Decimal = {0D, 631D, 1290.5D, 2072.5D, 3309.5D, 4900D, 6898.5D, 9316.5D, 12106D, 16754.5D, 23147.5D, 30710D, 39312D, 49062D}

        ' de burgerlijke staat wordt opgehaald
        Dim OK As Boolean = False
        Dim reponse As String = Nothing
        While Not OK
            Console.Out.Write("Etes-vous marié(e) (O/N) ? ")
            reponse = Console.In.ReadLine().Trim().ToLower()
            If reponse <> "o" And reponse <> "n" Then
                Console.Error.WriteLine("Réponse incorrecte. Recommencez")
            Else
                OK = True
            End If
        End While
        Dim Marie As Boolean = reponse = "o"

        ' aantal kinderen
        OK = False
        Dim NbEnfants As Integer = 0
        While Not OK
            Console.Out.Write("Nombre d'enfants : ")
            reponse = Console.In.ReadLine()
            Try
                NbEnfants = Integer.Parse(reponse)
                If NbEnfants >= 0 Then
                    OK = True
                Else
                    Console.Error.WriteLine("Réponse incorrecte. Recommencez")
                End If
            Catch
                Console.Error.WriteLine("Réponse incorrecte. Recommencez")
            End Try
        End While
        ' salaris
        OK = False
        Dim Salaire As Integer = 0
        While Not OK
            Console.Out.Write("Salaire annuel : ")
            reponse = Console.In.ReadLine()
            Try
                Salaire = Integer.Parse(reponse)
                If Salaire >= 0 Then
                    OK = True
                Else
                    Console.Error.WriteLine("Réponse incorrecte. Recommencez")
                End If
            Catch
                Console.Error.WriteLine("Réponse incorrecte. Recommencez")
            End Try
        End While
        ' berekening van het aantal aandelen
        Dim NbParts As Decimal
        If Marie Then
            NbParts = CDec(NbEnfants) / 2 + 2
        Else
            NbParts = CDec(NbEnfants) / 2 + 1
        End If
        If NbEnfants >= 3 Then
            NbParts += 0.5D
        End If
        ' belastbaar inkomen
        Dim Revenu As Decimal
        Revenu = 0.72D * Salaire

        ' gezinsquotiënt
        Dim QF As Decimal
        QF = Revenu / NbParts

        ' bepaling van de belastingschijf die overeenkomt met QF
        Dim i As Integer
        Dim NbTranches As Integer = Limites.Length
        Limites((NbTranches - 1)) = QF
        i = 0
        While QF > Limites(i)
            i += 1
        End While
        ' de belasting
        Dim impots As Integer = CInt(i * 0.05D * Revenu - CoeffN(i) * NbParts)

        ' het resultaat wordt weergegeven
        Console.Out.WriteLine(("Impôt à payer : " & impots))
    End Sub
End Module

Het programma wordt in een DOS-venster gecompileerd met:

dos>vbc impots1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573

dos>dir impots1.exe
24/02/2004  15:42                5 632 impots1.exe

De compilatie levert een uitvoerbaar bestand op: impots.exe. Opgemerkt moet worden dat impots.exe niet rechtstreeks door de processor kan worden uitgevoerd. Het bevat in feite tussencode die alleen op een .NET-platform kan worden uitgevoerd. De verkregen resultaten zijn als volgt:

dos>impots1
Etes-vous marié(e) (O/N) ? o
Nombre d'enfants : 3
Salaire annuel : 200000
Impôt à payer : 16400
dos>impots1
Etes-vous marié(e) (O/N) ? n
Nombre d'enfants : 2
Salaire annuel : 200000
Impôt à payer : 33388
dos>impots1
Etes-vous marié(e) (O/N) ? w
Réponse incorrecte. Recommencez
Etes-vous marié(e) (O/N) ? q
Réponse incorrecte. Recommencez
Etes-vous marié(e) (O/N) ? o
Nombre d'enfants : q
Réponse incorrecte. Recommencez
Nombre d'enfants : 2
Salaire annuel : q
Réponse incorrecte. Recommencez
Salaire annuel : 1
Impôt à payer : 0

2.8. Argumenten van het hoofdprogramma

De hoofdprocedure Main kan als parameter een array van tekenreeksen accepteren:


    Sub main(ByVal args() As String)

De parameter args is een array van tekenreeksen die de argumenten ontvangt die bij het aanroepen van het programma via de opdrachtregel worden doorgegeven.

  • args.Length is het aantal elementen in de array args
  • args(i) is het i-de element van de array

Als we het programma P starten met het commando: P arg0 arg1 … argn en de procedure Main van het programma P als volgt is gedeclareerd:


    Sub main(ByVal args() As String)

dan geldt arg(0)="arg0", arg(1)="arg1" … Hier volgt een voorbeeld:


' richtlijnen
Option Strict On
Option Explicit On 

' naamruimten
Imports System

Module arg
    Sub main(ByVal args() As String)
        ' aantal argumenten
        console.out.writeline("Il y a " & args.length & " arguments")
        Dim i As Integer
        For i = 0 To args.Length - 1
            Console.Out.WriteLine("argument n° " & i & "=" & args(i))
        Next
    End Sub
End Module

De uitvoering levert de volgende resultaten op:

dos>arg1 a b c
Il y a 3 arguments
argument n° 0=a
argument n° 1=b
argument n° 2=c

2.9. Opsommingen

Een opsomming is een gegevenstype waarvan het waardenbereik bestaat uit een verzameling gehele constanten. Laten we eens kijken naar een programma dat beoordelingen voor een examen moet verwerken. Er zouden er vijf zijn: Voldoende, AssezBien, Goed, TrèsBien, Uitstekend. We zouden dan een opsomming kunnen definiëren voor deze vijf constanten:


    Enum mention
        Passable
        AssezBien
        Bien
        TrésBien
        Excellent
    End Enum

Intern worden deze vijf constanten gecodeerd door opeenvolgende gehele getallen, beginnend met 0 voor de eerste constante, 1 voor de volgende, enzovoort. Een variabele kan worden gedeclareerd om deze waarden uit de opsomming aan te nemen:


         ' een variabele die haar waarden ontleent aan de genoemde opsomming
        Dim maMention As mention = mention.Passable

Een variabele kan worden vergeleken met de verschillende mogelijke waarden van de opsomming:


         ' test met waarde uit de opsomming
        If (maMention = mention.Passable) Then
            Console.Out.WriteLine("Peut mieux faire")
        End If

Men kan alle waarden van de opsomming ophalen:


        For Each m In mention.GetValues(maMention.GetType)
            Console.Out.WriteLine(m)
        Next

Net zoals het eenvoudige type Integer gelijkwaardig is aan de structuur Int32, is het eenvoudige type Enum gelijkwaardig aan de structuur Enum. Deze klasse heeft een statische methode GetValues waarmee alle waarden van een opgesomd type kunnen worden opgehaald dat als parameter wordt doorgegeven. Dit moet een object zijn van het type Type, een klasse die informatie bevat over het type van een gegeven. Het type van een variabele v wordt verkregen via v.GetType(). Dus hier levert maMention.GetType() het object Type op van de opsomming mentions en Enum.GetValues(maMention.GetType()) de lijst met waarden van de opsomming mentions.

Dit wordt geïllustreerd door het volgende programma:


' richtlijnen
Option Strict On
Option Explicit On 

' naamruimten
Imports System

Public Module enum2

    ' een opsomming
    Enum mention
        Passable
        AssezBien
        Bien
        TrèsBien
        Excellent
    End Enum

    ' testpagina
    Sub Main()

        ' een variabele die haar waarden uit de genoemde opsomming haalt
        Dim maMention As mention = mention.Passable

        ' weergave van de waarde van de variabele
        Console.Out.WriteLine("mention=" & maMention)

        ' test met waarde uit de opsomming
        If (maMention = mention.Passable) Then
            Console.Out.WriteLine("Peut mieux faire")
        End If

        ' lijst met letterlijke vermeldingen
        For Each m As mention In [Enum].GetValues(maMention.GetType)
            Console.Out.WriteLine(m.ToString)
        Next

        ' lijst met volledige vermeldingen
        For Each m As Integer In [Enum].GetValues(maMention.GetType)
            Console.Out.WriteLine(m)
        Next
    End Sub
End Module

De uitvoerresultaten zijn als volgt:

dos>enum2
mention=0
Peut mieux faire
Passable
AssezBien
Bien
TrèsBien
Excellent
0
1
2
3
4

2.10. Uitzonderingsafhandeling

Veel functies van VB.NET kunnen uitzonderingen, oftewel fouten, genereren. Wanneer een functie een uitzondering kan genereren, moet de programmeur deze afhandelen om programma's te verkrijgen die beter bestand zijn tegen fouten: het onvoorspelbaar "crashen" van een applicatie moet altijd worden vermeden.

Het afhandelen van een uitzondering verloopt volgens het volgende schema:

try
    appel de la fonction susceptible de générer l'exception
catch  e as Exception e)
    traiter l'exception e
end try
instruction suivante

Als de functie geen uitzondering genereert, gaat men door naar de volgende instructie; anders gaat men naar de hoofdtekst van de clausule catch en vervolgens naar de volgende instructie. Let op de volgende punten:

  • e is een object dat is afgeleid van het type Exception. We kunnen specifieker zijn door typen te gebruiken zoals IOException, SystemException, enzovoort: er bestaan verschillende soorten uitzonderingen. Door catch e as Exception te schrijven, geven we aan dat we alle soorten uitzonderingen willen afhandelen. Als de code van de clausule try meerdere soorten uitzonderingen kan genereren, willen we misschien specifieker zijn door de uitzondering af te handelen met meerdere clausules catch:
try
    appel de la fonction susceptible de générer l'exception
catch e as IOException 
    traiter l'exception e
catch  e as SystemException
    traiter l'exception e
end try
instruction suivante
  • Aan de clausules try/catch kan een finally-clausule worden toegevoegd:
try
    appel de la fonction susceptible de générer l'exception
catch  e as Exception
    traiter l'exception e
finally
    code exécuté après try ou catch
end try
instruction suivante

Of er nu een uitzondering is of niet, de code van de clausule finally wordt altijd uitgevoerd.

  • In de clausule catch wil men het beschikbare object Exception misschien niet gebruiken. In plaats van catch e as Exception te schrijven, schrijft men dan catch.
  • De klasse Exception heeft een eigenschap Message die een bericht bevat met details over de fout die is opgetreden. Als men dit bericht wil weergeven, schrijft men dus:
catch e as Exception
    Console.Error.WriteLine("L'erreur suivante s'est produite : "+e.Message);
    ...
end try
  • De klasse Exception heeft een methode ToString die een tekenreeks retourneert waarin het type van de uitzondering en de waarde van de eigenschap Message worden aangegeven. We kunnen dus het volgende schrijven:
catch  ex as Exception
    Console.Error.WriteLine("L'erreur suivante s'est produite : "+ex.ToString)
    ...
end try

Het volgende voorbeeld toont een uitzondering die wordt gegenereerd door het gebruik van een niet-bestaand array-element:


' opties
Option Explicit On 
Option Strict On

' naamruimten
Imports System

Module tab1
    Sub Main()
        ' definitie en initialisatie van een array
        Dim tab() As Integer = {0, 1, 2, 3}
        Dim i As Integer

        ' weergave van een array met een for-lus
        For i = 0 To tab.Length - 1
            Console.Out.WriteLine(("tab[" & i & "]=" & tab(i)))
        Next i

        ' array weergeven met een for each-lus
        Dim élmt As Integer
        For Each élmt In tab
            Console.Out.WriteLine(élmt)
        Next élmt

        ' een uitzondering genereren
        Try
            tab(100) = 6
        Catch e As Exception
            Console.Error.WriteLine(("L'erreur suivante s'est produite : " & e.Message))
        End Try
    End Sub
End Module

De uitvoering van het programma levert de volgende resultaten op:

dos>exception1
tab[0]=0
tab[1]=1
tab[2]=2
tab[3]=3
0
1
2
3
L'erreur suivante s'est produite : L'index se trouve en dehors des limites du tableau.

Hier is nog een voorbeeld waarin de uitzondering wordt afgehandeld die wordt veroorzaakt door het toewijzen van een tekenreeks aan een getal wanneer de tekenreeks geen getal vertegenwoordigt:


' opties
Option Strict On
Option Explicit On 

'imports
Imports System

Public Module console1
  Public Sub Main()
    ' De naam wordt gevraagd
    System.Console.Write("Nom : ")

        ' antwoord lezen
    Dim nom As String = System.Console.ReadLine()

        ' om de leeftijd wordt gevraagd
    Dim age As Integer
    Dim ageOK As Boolean = False
    Do While Not ageOK
      ' vraag
      Console.Out.Write("âge : ")
      ' antwoord lezen en controleren
      Try
        age = Int32.Parse(System.Console.ReadLine())
        If age < 0 Then Throw New Exception
        ageOK = True
      Catch
        Console.Error.WriteLine("Age incorrect, recommencez...")
      End Try
    Loop

        ' eindweergave
    Console.Out.WriteLine("Vous vous appelez [" & nom & "] et vous avez [" & age & "] ans")
  End Sub
End Module

Enkele uitvoerresultaten:

dos>console1
Nom : dupont
âge : 23
Vous vous appelez dupont et vous avez 23 ans
dos>console1
Nom : dupont
âge : xx
Age incorrect, recommencez...
âge : 12
Vous vous appelez dupont et vous avez 12 ans

2.11. Het doorgeven van parameters aan een functie

We gaan hier in op de manier waarop parameters aan een functie worden doorgegeven. Laten we eens kijken naar de functie:


    Sub changeInt(ByVal a As Integer)
        a = 30
        Console.Out.WriteLine(("Paramètre formel a=" & a))
    End Sub    

In de definitie van de functie wordt a een formele parameter genoemd. Deze is er uitsluitend voor de definitie van de functie changeInt. Hij had net zo goed b kunnen heten. Laten we nu eens kijken naar een toepassing van deze functie:


    Sub Main()
        Dim age As Integer = 20
        changeInt(age)
        Console.Out.WriteLine(("Paramètre effectif age=" & age))
    End Sub

Hier in de instructie changeInt(leeftijd) is age de effectieve parameter die zijn waarde doorgeeft aan de formele parameter a. We zijn geïnteresseerd in de manier waarop een formele parameter de waarde van de bijbehorende effectieve parameter ophaalt.

2.11.1. Doorgave per waarde

Het volgende voorbeeld laat zien dat de parameters van een functie/procedure standaard per waarde worden doorgegeven: dat wil zeggen dat de waarde van de effectieve parameter wordt gekopieerd naar de bijbehorende formele parameter. Het gaat hier om twee afzonderlijke entiteiten. Als de functie de formele parameter wijzigt, blijft de effectieve parameter ongewijzigd.


' opties
Option Explicit On 
Option Strict On

' parameters als waarde doorgeven aan een functie
Imports System

Module param1
    Sub Main()
        Dim age As Integer = 20
        changeInt(age)
        Console.Out.WriteLine(("Paramètre effectif age=" & age))
    End Sub

    Sub changeInt(ByVal a As Integer)
        a = 30
        Console.Out.WriteLine(("Paramètre formel a=" & a))
    End Sub
End Module

De verkregen resultaten zijn als volgt:

Paramètre formel a=30
Paramètre effectif age=20

De waarde 20 van de effectieve parameter is overgenomen in de formele parameter a. Deze is vervolgens gewijzigd. De effectieve parameter is ongewijzigd gebleven. Deze overdrachtswijze is geschikt voor invoerparameters van een functie.

2.11.2. Doorgave via verwijzing

Bij doorgave via verwijzing vormen de effectieve parameter en de formele parameter één en dezelfde entiteit. Als de functie de formele parameter wijzigt, wordt ook de effectieve parameter gewijzigd. In VB.NET moet de formele parameter worden voorafgegaan door het sleutelwoord ByRef. Hier volgt een voorbeeld:


' opties
Option Explicit On 
Option Strict On

' parameters per waarde doorgeven aan een functie
Imports System

Module param2
    Sub Main()
        Dim age As Integer = 20
        changeInt(age)
        Console.Out.WriteLine(("Paramètre effectif age=" & age))
    End Sub

    Sub changeInt(ByRef a As Integer)
        a = 30
        Console.Out.WriteLine(("Paramètre formel a=" & a))
    End Sub
End Module

en de uitvoerresultaten:

Paramètre formel a=30
Paramètre effectif age=30

De werkelijke parameter is aangepast aan de wijziging van de formele parameter. Deze manier van doorgeven is geschikt voor uitvoerparameters van een functie.