Visual Basic 2012 Voorbeelden
   

visual basic 2012 broncode voorbeelden

Blijf op de hoogte van de recente aanpassingen op vbvoorbeelden!

Microsoft Visual Studio 2012Microsoft Developers Network - Visual BasicMicrosoft .NET Framework

8.8. Inleiding in Functies

Print Email Deel op Twitter Deel op Facebook

Dit artikel is gepubliceerd op maandag 15 oktober 2012 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.

De variabele sum wordt in onderstaand voorbeeld enkel gebruikt om output te bekomen uit de aangeroepen MakeSum procedure.  Dit kan bekomen worden door met een referentie ("by reference" / ByRef) naar de variable - die de argumentwaarde voorstelt - te werken.
Visual Basic 2012 Broncode - Codevoorbeeld 166
Module Example1
    Sub Main()
        Dim value1 As Integer = 5
        Dim value2 As Integer = 10
        Dim sum As Integer
        '
        MakeSum(value1, value2, sum)
        Console.WriteLine(sum)
        '
        Console.ReadLine()
    End Sub
    Sub MakeSum(ByVal value1 As Integer, ByVal value2 As Integer, _
                ByRef sum As Integer)
        sum = value1 + value2
    End Sub
End Module
Console Application Output
15
Een elegantere oplossing voor het gebruik van "output argumenten", is het gebruik van een functie, zoals in onderstaand voorbeeld.
Visual Basic 2012 Broncode - Codevoorbeeld 167
Module Example2
    Sub Main()
        Dim value1 As Integer = 5
        Dim value2 As Integer = 10
        '
        Dim sum As Integer = GetSum(value1, value2)
        Console.WriteLine(sum)
        '
        Console.ReadLine()
    End Sub
    Function GetSum(ByVal value1 As Integer, _
                    ByVal value2 As Integer) As Integer
        Return (value1 + value2)
    End Function
End Module
Console Application Output
15

8.8.1. Definitie en Aanroep van een Functie

Een functie is vergelijkbaar met een procedure, maar levert ook een waarde op.

Een functie definieer je op volgende wijze :
Function <identifier>(<arguments>) [<type-specifier>]
    ...
End Function
Een belangrijk verschil is dat een aanroep (ook wel "call" genoemd) naar een functie een expressie is van dat type gespecificeerd in de type specifier ( de As clausule) van die functiedefinitie.
Hierboven is de aanroep naar de GetSum(...) functie dus een expressie van het type Integer.

In een functie zou altijd moeten opgegeven worden wat de op te leveren waarde is.  Dit kan verwezenlijkt worden met een Return statement, naast Return plaats je hier in dit voorbeeld een waarde die als Integer te representeren  is.

De term "method" wordt vanaf hier gebruik als verzamelnaam voor zowel procedures als functies.

Een procedure is als een functie die niets teruggeeft.
Of in het vakjargon een "function method" die "void" (een "leegte") oplevert.

Gebruik een procedure om een actie te verrichten, iets te doen (bijvoorbeeld output te geven), gebruik een functie louter om een waarde op te leveren.

Probeer steeds voor de identifier van je functies een benaming uit te kiezen die zo duidelijk mogelijk weergeeft welke waarde deze functie zal opleveren.  Veel gebruikte prefixes voor identifiers van functies zijn "Is", "Get" en "Has".  "Is" en "Has" functies leveren doorgaans een Boolean waarde op.

Dezelfde mogelijkheden omtrent variabelen en parameters als in procedures zijn ook mogelijk in functies.

8.8.2. Instellen van de Return Waarde

Een alternatieve werkwijze om de terugkeerwaarde in te stellen voor een functie is die terugkeerwaarde toe te kennen aan de functie-identifier.

Bij iedere call naar een functie wordt in het geheugen een ruimte gereserveerd om de terugkeerwaarde in te kunnen voorstellen.  Een Return statement zal deze ruimte opvullen en de functiecall beëindigen.  Maar ook manueel kan men deze ruimte opvullen, men kan naar deze ruimte verwijzen aan de hand van de identifier van de functie.  Door de terug te keren waarde toe te kennen aan de functie-identifier zal men dus ook die ruimte opvullen of de terugkeerwaarde instellen.
Visual Basic 2012 Broncode - Codevoorbeeld 168
Module Example3
    Sub Main()
        Console.WriteLine(Test1())
        Console.WriteLine(Test2())
        '
        Console.ReadLine()
    End Sub
    Function Test1() As String
        Console.WriteLine("Test1 : code before Return statement")
        Return "Test1"
        Console.WriteLine("Test1 : code after Return statement")           ' (1)
    End Function
    Function Test2() As String
        Console.WriteLine("Test2 : code before assigning return value")
        Test2 = "Test2"
        Console.WriteLine("Test2 : code after assigning return value")
    End Function
End Module
Console Application Output
Test1 : code before Return statement
Test1
Test2 : code before assigning return value
Test2 : code after assigning return value
Test2
Een groot verschil tussen bovenvermelde technieken is dus dat bij het gebruik van een Return statement ook de functie beëindigd wordt.   Regel (1) zal dus nooit worden uitgevoerd.

Bij uitvoering van onderstaand voorbeeld merk je dat de output van alle drie versies van de GetInfo... functie dezelfde is.

Toch verschillende de 3 versies in de wijze waarop de terugkeerwaarde wordt ingesteld.
Visual Basic 2012 Broncode - Codevoorbeeld 169
Module Example4
    Sub Main()
        For value As Integer = -1 To 1
            Console.WriteLine("Value " & value & " : ")
            Console.WriteLine(GetInfo1(value))
            Console.WriteLine(GetInfo2(value))
            Console.WriteLine(GetInfo3(value))
            Console.WriteLine()
        Next
        '
        Console.ReadLine()
    End Sub
    Function GetInfo1(ByVal value As Integer) As String
        Select Case value
            Case Is = 0
                Return "Value is zero."
            Case Is > 0
                Return "Value is positive."
            Case Is < 0
                Return "Value is negative."
        End Select
    End Function
    Function GetInfo2(ByVal value As Integer) As String
        Dim info2 As String
        Select Case value
            Case Is = 0
                info2 = "Value is zero."
            Case Is > 0
                info2 = "Value is positive."
            Case Is < 0
                info2 = "Value is negative."
        End Select
        Return info2
    End Function
    Function GetInfo3(ByVal value As Integer) As String
        Select Case value
            Case Is = 0
                GetInfo3 = "Value is zero."
            Case Is > 0
                GetInfo3 = "Value is positive."
            Case Is < 0
                GetInfo3 = "Value is negative."
        End Select
        'Return GetInfo3                                                   ' (1)
    End Function
End Module
Console Application Output
Value -1 :
Value is negative.
Value is negative.
Value is negative.

Value 0 :
Value is zero.
Value is zero.
Value is zero.

Value 1 :
Value is positive.
Value is positive.
Value is positive.
Functie GetInfo1 definieert meerdere "exit-points" in de functie, meerdere Return statements - die elk de functie beëindigen - zijn hier opgenomen.  Het gebruik van meerder exit- (ook ook entry-) point in een blok code, zal vaak de leesbaarheid en onderhoudbaarheid van deze code niet te goede komen.

Functie GetInfo2 gebruikt een extra (tijdelijke) variabele info2 om hierin de terugkeerwaarde in samen te stellen.  Deze variabele wordt dan gebruikt in het Return statement om de terugkeerwaarde in te stellen.

Zoals GetInfo3 demonstreert is het gebruik van deze variabele is echter overbodig.  Elke String functie (functie die een String oplevert) beschikt immers reeds over een plaats in het geheugen om een String in te bewaren.  Deze plaats kan bereikt worden aan de hand van de functienaam.

Het Return statement in versie 3 (op regel (1)) is niet noodzakelijk, maar kan worden opgenomen.

Onderstaand voorbeeld illustreert nogmaals hoe functies kunnen gedefinieerd worden, hoe ze kunnen worden aangeroepen, en waarvoor ze kunnen worden gebruikt :
Visual Basic 2012 Broncode - Codevoorbeeld 170
Module Example5
    Sub Main()
        Dim dividend As Integer = 24
        Dim divisor As Integer = 6
        Dim quotient As Single
        '
        If Not IsZero(divisor) Then quotient = GetQuotient(dividend, divisor)
        '
        Console.WriteLine(quotient)
        '
        Console.ReadLine()
    End Sub
    Function IsZero(ByVal value As Integer) As Boolean
        If value = 0 Then IsZero = True
    End Function
    Function GetQuotient(ByVal dividend As Integer, _
                         ByVal divisor As Integer) As Double
        GetQuotient = dividend / divisor
    End Function
End Module
Console Application Output
4
Functie IsZero gaat na of een bepaalde waarde (value) nul is.  Deze functie (ook wel "query" genoemd) zal dus antwoorden op de vraag of een bepaald getal nul is.  Het antwoord op dergelijke vraag kan enkel bevestigend of ontkrachtend zijn.  Het meest toepasselijke returntype is dan ook Boolean.

Functies die een Boolean opleveren gebruiken in hun identifier vaak de prefixen Is of Has.

Indien de ontvangen waarde bij de uitvoering van deze functie niet nul is, wordt hier niet expliciet een terugkeerwaarde ingesteld.  Op dat moment zal de defaultwaarde van het Boolean datatype worden opgeleverd.

8.8.3. Oefeningen

Opgave Oefening 1 :

Maak een functie GetResult, die 3 argumentwaarden bij aanroep verwacht.

De eerste en derde argumentwaarden dienen Integer expressies te zijn, het tweede argumenten een Char expressie.

Het is de bedoeling dat deze functie drie rekenkundige bewerkingen aan kan (tweede argument kan dus "+"c, "-"c en "*"c zijn).

De terugkeerwaarde mag een Integer expressie zijn.

Oplossing Oefening 1 :
Visual Basic 2012 Broncode - Codevoorbeeld 171
Module Exercise1Solution
    Sub Main()
        Console.WriteLine(GetResult(5, "+"c, 4))
        Console.WriteLine(GetResult(5, "-"c, 4))
        Console.WriteLine(GetResult(5, "*"c, 4))
        '
        Console.ReadLine()
    End Sub
    Function GetResult(ByVal value1 As Integer, _
                       ByVal operatorSymbol As Char, _
                       ByVal value2 As Integer) As Integer
        Select Case operatorSymbol
            Case "+"c
                GetResult = value1 + value2
            Case "-"c
                GetResult = value1 - value2
            Case "*"c
                GetResult = value1 * value2
        End Select
    End Function
End Module
Console Application Output
9
1
20
Opgave Oefening 2 :
Maak een programma met drie functies.

Functie IsLeapYear kan van een jaartal vertellen of het om een schrikkeljaar gaat of niet.
Een jaar is een schrikkeljaar als het deelbaar is door 4 maar niet door 100, of indien het deelbaar is door 400.  1900 bijvoorbeeld was geen schrikkeljaar, 2000 dan weer wel.

Functie GetDaysFebruary kan van een jaartal vertellen wat het aantal dagen voor februari is tijdens dit jaar.

Functie GetDays kan van een maand (volgnummer) en jaartal vertellen wat het aantal dagen is van deze maand tijdens dit jaar.

Probeer de functies te herbruiken daar waar mogelijk.
Oplossing Oefening 1 :
Visual Basic 2012 Broncode - Codevoorbeeld 172
Module Exercise2Solution
    Sub Main()
        Console.WriteLine(IsLeapYear(1900))
        Console.WriteLine(IsLeapYear(1996))
        Console.WriteLine(IsLeapYear(2000))
        Console.WriteLine()
        Console.WriteLine(GetDaysFebruary(1900))
        Console.WriteLine(GetDaysFebruary(1996))
        Console.WriteLine(GetDaysFebruary(2000))
        Console.WriteLine()
        Console.WriteLine(GetDays(1900, 2))
        Console.WriteLine(GetDays(1996, 2))
        Console.WriteLine(GetDays(2000, 2))
        Console.WriteLine()
        Console.WriteLine(GetDays(1900, 3))
        Console.WriteLine(GetDays(1996, 3))
        Console.WriteLine(GetDays(2000, 3))
        '
        Console.ReadLine()
    End Sub
    Function IsLeapYear(ByVal year As Integer) As Boolean
        If year Mod 4 = 0 AndAlso year Mod 100 <> 0 OrElse _
           year Mod 400 = 0 Then IsLeapYear = True
    End Function
    Function GetDaysFebruary(ByVal year As Integer) As Integer
        GetDaysFebruary = 28
        If IsLeapYear(year) Then GetDaysFebruary = 29
    End Function
    Function GetDays(ByVal year As Integer, ByVal month As Integer) As Integer
        If month = 2 Then
            GetDays = GetDaysFebruary(year)
        Else
            Dim days As Integer() = _
                           {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
            GetDays = days(month - 1)
        End If
    End Function
End Module
Console Application Output
False
True
True

28
29
29

28
29
29

31
31
31

Dit artikel is gepubliceerd op maandag 15 oktober 2012 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.