Visual Basic 2008 9.0 .NET Examples and Ebook

Procedures and Functions

Vorig Onderwerp

Arrays

|

Object Oriented Programming

Volgend Onderwerp

Introduction to Procedures

Vorig Onderwerp

Sorting Arrays

|

Local, Module and Static Variables

Volgend Onderwerp
What are Procedures ?

What are Procedures ?

Arguments

Arguments

Working By Value with Argument Values

Working By Value with Argument Values

Working By Reference with Argument Values

Working By Reference with Argument Values

Several Arguments in One Procedure

Several Arguments in One Procedure

Exercises

Exercises



Next example will convert centimetres to inches and inches to centimetres.


Module Example1
    Sub Main()
        Dim menu As Char
        Dim value As Decimal
        '
        Console.Write("1 centimetres -> inches / 2 - inches -> centimetres : ")
        menu = Console.ReadLine()
        Do Until menu = "1"c OrElse menu = "2"c
            Console.WriteLine("An error occurred, please try again.")
            Console.Write("1 centimetres -> inches / 2 - inches -> centimetres : ")
            menu = Console.ReadLine()
        Loop
        '
        Console.Write("Value : ")
        value = Console.ReadLine()
        Do Until value > 0
            Console.WriteLine("An error occurred, please try again.")
            Console.Write("Value : ")
            value = Console.ReadLine()
        Loop
        '
        If menu = "1"c Then
            Console.WriteLine(value & " centimetres is " & value * 0.3937 & " inches")
        Else
            Console.WriteLine(value & " inches is " & value * 2.54 & " centimetres")
        End If
        '
        Console.ReadLine()
    End Sub
End Module
Download Broncode

Output :

 1 centimetre -> inches / 2 - inches -> centimetres : <i>3</i>
 An error occurred, please try again.
 1 centimetres -> inches / 2 - inches -> centimetres : <i>4</i>
 An error occurred, please try again.
 1 centimetres -> inches / 2 - inches -> centimetres : <i>1</i>
 Value : <i>-5</i>
 An error occurred, please try again.
 Value : <i>-10</i>
 An error occurred, please try again.
 Value : <i>10</i>
 10 centimetres is 3,937 inches

When an invalid menu-option is chosen, or a negative value is entered an error is produces.

Both situations will use the same instruction(s) to produce the error.

To avoid coding the same instruction more than once, "procedures" ( also called "subroutines" or "functions" ) can be used.


What are Procedures ?


When a certain functionality is needed on different occasions in a program ( at different point in code ) a procedure can be used to avoid coding the same instructions ( responsible for implementing that functionality ) more than once.

A procedure can be defined once, and called whenever needed.

The Sub Main() ... End Sub used in the above example is a procedure ( with identifier Main ). This Main procedure is needed when an module is set as startup-object of a project ( an assembly / a program ).

The definition of a procedure starts with Sub and ends with End Sub.
The opening Sub is followed by the identifier ( the name ) of that procedure.

Next example defines a procedure ShowError responsible for printing an error on the console.
Whenever our program needs to produce an error, we can call this procedure.


Module Example2
    Sub Main()
        Dim menu As Char
        Dim value As Decimal
        '
        Console.Write("1 centimetres -> inches / 2 - inches -> centimetres : ")
        menu = Console.ReadLine()
        Do Until menu = "1"c OrElse menu = "2"c
            ShowError()
            Console.Write("1 centimetres -> inches / 2 - inches -> centimetres : ")
            menu = Console.ReadLine()
        Loop
        '
        Console.Write("Value : ")
        value = Console.ReadLine()
        Do Until value > 0
            ShowError()
            Console.Write("Value : ")
            value = Console.ReadLine()
        Loop
        '
        If menu = "1"c Then
            Console.WriteLine(value & " centimetres is " & value * 0.3937 & " inches")
        Else
            Console.WriteLine(value & " inches is " & value * 2.54 & " centimetres")
        End If
        '
        Console.ReadLine()
    End Sub
    Sub ShowError()
        Console.WriteLine("An error occurred, please try again.")
    End Sub
End Module
Download Broncode

Output :

 1 centimetres -> inches / 2 - inches -> centimetres : <i>3</i>
 An error occurred, please try again.
 1 centimetres -> inches / 2 - inches -> centimetres : <i>4</i>
 An error occurred, please try again.
 1 centimetres -> inches / 2 - inches -> centimetres : <i>1</i>
 Value : <i>-5</i>
 An error occurred, please try again.
 Value : <i>-10</i>
 An error occurred, please try again.
 Value : <i>10</i>
 10 centimetres is 3,937 inches

There is no specific order in which the procedures need to be defined.

A call to a procedure is done by using the identifier of that procedure. The parentheses following the identifier are often optional and will be explained later.

Also chose an identifier that will explain as much as possible what the procedure will do, what the responsibility is of that procedure. Here ShowError is responsible for showing an error.

When a procedure is finished the program continues with the code following the call to this procedure.

When a program has lots of procedures, and these procedure all call each other, it can be difficult to keep track of how - at a certain point at runtime - a certain procedure was called, or who called that certain procedure. A callstack debug tool in your IDE ( programming environment ) can come to rescue.


Visual Studio : Visual Studio has a callstack tool, to trace all calls to procedures.

This tool behaves like a stack ( LIFO or last in, first out ). The latest call to a certain procedure will either call another procedure or finish and be removed from the stack.


Klik hier om terug naar boven te gaan.  Up



Arguments


The above example produce the same error ( "An error occurred, please try again." ) when an invalid menu-option was chosen and when an illegal value was entered.

It's not unthinkable that you would prefer a more specific error depending on the wrongdoing.

This can be done by changing ShowError into ShowMenuError and ShowValueError.


Module Example3
    Sub Main()
        Dim menu As Char
        Dim value As Decimal
        '
        Console.Write("1 centimetres -> inches / 2 - inches -> centimetres : ")
        menu = Console.ReadLine()
        Do Until menu = "1"c OrElse menu = "2"c
            ShowMenuError()
            Console.Write("1 centimetres -> inches / 2 - inches -> centimetres : ")
            menu = Console.ReadLine()
        Loop
        '
        Console.Write("Value : ")
        value = Console.ReadLine()
        Do Until value > 0
            ShowValueError()
            Console.Write("Value : ")
            value = Console.ReadLine()
        Loop
        '
        If menu = "1"c Then
            Console.WriteLine(value & " centimetres is " & value * 0.3937 & " inches")
        Else
            Console.WriteLine(value & " inches is " & value * 2.54 & " centimetres")
        End If
        '
        Console.ReadLine()
    End Sub
    Sub ShowMenuError()
        Console.WriteLine("An illegal menu option is chosen.  Please try again.")
    End Sub
    Sub ShowValueError()
        Console.WriteLine("The value should be above zero.  Please try again.")
    End Sub
End Module
Download Broncode

Output :

 1 centimetres -> inches / 2 - inches -> centimetres : <i>3</i>
 An illegal menu option is chosen.  Please try again.
 1 centimetres -> inches / 2 - inches -> centimetres : <i>4</i>
 An illegal menu option is chosen.  Please try again.
 1 centimetres -> inches / 2 - inches -> centimetres : <i>1</i>
 Value : <i>-5</i>
 The value should be above zero.  Please try again.
 Value : <i>-10</i>
 The value should be above zero.  Please try again.
 Value : <i>10</i>
 10 centimetres is 3,937 inches

In stead of defining two ShowError procedure, we could define only one that shows a certain ( undefined ) error.

The errormessage is not statically defined, but the procedure is parametrized with the message.


Module Example4
    Sub Main()
        Dim menu As Char
        Dim value As Decimal
        '
        Console.Write("1 centimetres -> inches / 2 - inches -> centimetres : ")
        menu = Console.ReadLine()
        Do Until menu = "1"c OrElse menu = "2"c
            ShowError("An illegal menu option is chosen.")
            Console.Write("1 centimetres -> inches / 2 - inches -> centimetres : ")
            menu = Console.ReadLine()
        Loop
        '
        Console.Write("Value : ")
        value = Console.ReadLine()
        Do Until value > 0
            ShowError("The value should be above zero.")
            Console.Write("Value : ")
            value = Console.ReadLine()
        Loop
        '
        If menu = "1"c Then
            Console.WriteLine(value & " centimetres is " & value * 0.3937 & " inches")
        Else
            Console.WriteLine(value & " inches is " & value * 2.54 & " centimetres")
        End If
        '
        Console.ReadLine()
    End Sub
    Sub ShowError(ByVal message As String)
        Console.WriteLine(message & "  Please try again.")
    End Sub
End Module
Download Broncode

Output :

 1 centimetres -> inches / 2 - inches -> centimetres : <i>3</i>
 An illegal menu option is chosen.  Please try again.
 1 centimetres -> inches / 2 - inches -> centimetres : <i>4</i>
 An illegal menu option is chosen.  Please try again.
 1 centimetres -> inches / 2 - inches -> centimetres : <i>1</i>
 Value : <i>-5</i>
 The value should be above zero.  Please try again.
 Value : <i>-10</i>
 The value should be above zero.  Please try again.
 Value : <i>10</i>
 10 centimetres is 3,937 inches

An argument is defined/declared between the parentheses of the procedure definition. Just like local variables ( declared between Sub and End Sub ) these variables have an identifier and are from a specific datatype.
Keyword ByVal is added by default and will be discussed later.

When ShowError is called, a String needs to be provided by the calling routine.

The implementation of ShowError will then show the provided String value as an error.


Module Example5
    Sub Main()
        ShowMenuError()
        '
        Example4.ShowError("message 1")
        '
        Dim someMessage As String = "message 2"
        Example4.ShowError(someMessage)
        '
        Example4.ShowError("message" & " " & "3")
        '
        Example4.ShowError(Console.ReadLine())
        '
        Console.ReadLine()
    End Sub
End Module
Download Broncode

Output :

 An illegal menu option is chosen.  Please try again.
 message 1  Please try again.
 message 2  Please try again.
 message 3  Please try again.
 <i>message 4</i>
 message 4  Please try again.

A procedure declared within a module, is by default "public" or accessible for other modules. Example5 calls ShowError(...) defined in Example4 ( Example4.ShowError(...) ).
A call to ShowError(...) ( without referring to the declaring module ) would be ambiguous, modules Example2 and Example4 define a different ShowError.


Klik hier om terug naar boven te gaan.  Up



Working By Value with Argument Values


By default ( and when the keyword ByVal is used ) a procedure works by value ( or with a shallow copy ) of the provided argument value.

MultiplyBy10 has a value that holds a copy of the provided value 5. This copy is multiplied by 10, so value of Main is untouched.


Module Example6
    Sub Main()
        Dim value As Integer = 5
        MultiplyBy10(value)
        Console.WriteLine("Main value : " & value)
    End Sub
    Sub MultiplyBy10(ByVal value As Integer)
        value *= 10
        Console.WriteLine("MultiplyBy10 value : " & value)
    End Sub
End Module
Download Broncode

Output :

 5
 50

Klik hier om terug naar boven te gaan.  Up


Working By Reference with Argument Values


If we want that the variable ( used to express the argument value ) of the calling routine changes when the argument variable of the called routine changes, we'll need to work by reference ( 'ByRef' ) with the provided argument value.

In Example7 MultiplyBy10 works by reference with the value that is expressed by value of Main. Both variables ( value of Main and value of MultiplyBy10 ) refer to the same value in memory. So if value in MultiplyBy10 is multiplied by 10, this will have effect on value of Main.


Module Example7
    Sub Main()
        Dim value As Integer = 5
        MultiplyBy10(value)
        Console.WriteLine("Main value : " & value)
        '
        MultiplyBy10(value + 1)
        Console.WriteLine("Main value : " & value)
    End Sub
    Sub MultiplyBy10(ByRef value As Integer)
        value *= 10
    End Sub
End Module
Download Broncode

Output :

 50
 50

The call MultiplyBy10(value + 1) will have no effect on value of Main.
Here value of MultiplyBy10 holds a reference to value 51 and not to 50 ( or value of Main ). 51 gets multiplied by 10, which will have no effect on value of Main ( 50 ).

When the provided argument values only serve as input for the calling routine ( "in"-arguments ) ByVal is used.
If the argument is ( also ) used to retrieve some output from the called routine ( "(in/)out" arguments ) ByRef is used.

In/Out- or out-arguments are rarely used. More elegant constructions
( functions ) can be used to retrieve output from a called routine. In a next topic we'll discuss functions.


Klik hier om terug naar boven te gaan.  Up


Several Arguments in One Procedure


Use commas to separate the declaration of several arguments in a definition of a procedure.


Module Example8
    Sub Main()
        ShowSum(1, 2)
        '
        Console.WriteLine()
    End Sub
    Sub ShowSum(ByVal value1 As Integer, ByVal value2 As Integer)
        Console.WriteLine(value1 + value2)
    End Sub
End Module
Download Broncode

Output :

 3

Each argument can be either ByVal or ByRef.


Klik hier om terug naar boven te gaan.  Up


Exercises


Task :

What will be the output of Exercise1Task ?


Module Exercise1Task
    Sub Main()
        Dim x As Integer = 4
        Dim y As Integer = 5
        Dim z As Integer = 6
        '
        Test(x, y, z + 1)
        '
        Console.WriteLine("Main x : " & x)
        Console.WriteLine("Main y : " & y)
        Console.WriteLine("Main z : " & z)
        Console.ReadLine()
    End Sub
    Sub Test(ByRef y As Integer, ByVal z As Integer, ByRef x As Integer)
        z ^= 2
        x += z
        y += z
        '
        Console.WriteLine("Test x : " & x)
        Console.WriteLine("Test y : " & y)
        Console.WriteLine("Test z : " & z)
    End Sub
End Module
Download Broncode

Solution :


Output :

 Test x : 32
 Test y : 29
 Test z : 25
 Main x : 29
 Main y : 5
 Main z : 6

Task :


Create module Exercise2Solution with procedures Input and ShowSmallest.


Module Exercise2Task
    Sub Main()
        Dim number1, number2 As Integer
        '
        'Exercise2Solution.Input(number1, "Number 1 ? : ")
        'Exercise2Solution.Input(number2, "Number 2 ? : ")
        '
        'Exercise2Solution.ShowSmallest(number1, number2)
        '
        Console.ReadLine()
    End Sub
End Module
Download Broncode

Output :

 Number 1 ? : <i>5</i>
 Number 2 ? : <i>4</i>
 Smallest : 4

Solution :


Module Exercise2Solution
    Sub Input(ByRef value As Integer, ByVal message As String)
        Console.Write(message)
        value = Console.ReadLine()
    End Sub
    Sub ShowSmallest(ByVal value1 As Integer, ByVal value2 As Integer)
        Dim smallest As Integer = value1
        If value2 < smallest Then smallest = value2
        Console.WriteLine("Smallest : " & smallest)
    End Sub
End Module
Download Broncode




This version ( published on 2008-06-24 ) is printed from http://www.studyvb.com, visit the website for more recent information.

Updated On : 2008-01-28

Download Broncode

Published On : 2008-06-24

Introduction to Procedures

Vorig Onderwerp

Sorting Arrays

|

Local, Module and Static Variables

Volgend Onderwerp

Procedures and Functions

Vorig Onderwerp

Arrays

|

Object Oriented Programming

Volgend Onderwerp
Nederlands  Nederlands

Add to favorites (IE).