Home

Exploring Procedures

 

Technique of Using Variables and Arguments

 

Static Variables

Consider the following program: 


Module Module1

    Sub Starter(ByVal y As Integer)
        Dim a As Double = 112.5
        Dim b As Double = 175.25

        a = a / y
        b = b + 2

        Console.WriteLine("y   = {0}", y)
        Console.WriteLine("a   = {0}", a)
        Console.WriteLine("b   = {0}", b)
        Console.WriteLine("b/a = {0}", b / a)
        Console.WriteLine()
    End Sub

    Sub Main()
        Starter(2)
        Starter(2)
        Starter(2)
        Starter(2)
    End Sub

End Module

When executed, this program would produce: 

y   = 2
a   = 56.25
b   = 177.25
b/a = 3.15111111111111

y   = 2
a   = 56.25
b   = 177.25
b/a = 3.15111111111111

y   = 2
a   = 56.25
b   = 177.25
b/a = 3.15111111111111

y   = 2
a   = 56.25
b   = 177.25
b/a = 3.15111111111111

The Starter() procedure receives one argument passed when it is called. The called function also receives the same argument every time. Looking at the result, the argument passed to the function and the local variables declared inside of the called function keep the same value every time the procedure is called. That is, when the Starter() procedure exits, the values remain the same.

We know that, when a procedure is defined, any variable declared locally belongs to the procedure and its influence cannot expand beyond the body of the function. If you want a locally declared variable to keep its changed value when its host function is exited, declare such a variable as static. 

To declare a static variable, type the Static keyword on the left of the Dim keyword. You should always initialize a static variable before using it; that is, when declaring it. To make the local variables of our Starter() function static, we can declare them as follows: 


Module Module1

    Sub Starter(ByVal y As Int16)
        Static Dim a As Double = 112.5
        Static Dim b As Double = 175.25

        a = a / y
        b = b + 2

        Console.WriteLine("y   = {0}", y)
        Console.WriteLine("a   = {0}", a)
        Console.WriteLine("b   = {0}", b)
        Console.WriteLine("b/a = {0}", b / a)
        Console.WriteLine()
    End Sub

    Sub Main()
        Starter(2)
        Starter(2)
        Starter(2)
        Starter(2)
    End Sub

End Module

This time, when executing the program, it would produce: 

y   = 2
a   = 56.25
b   = 177.25
b/a = 3.15111111111111

y   = 2
a   = 28.125
b   = 179.25
b/a = 6.37333333333333

y   = 2
a   = 14.0625
b   = 181.25
b/a = 12.8888888888889

y   = 2
a   = 7.03125
b   = 183.25
b/a = 26.0622222222222

Notice that, this time, each local variable keeps its newly changed value when the function exits. 

 

Optional Arguments

If you create a procedure that takes one or more arguments, whenever you call that procedure, you must provide a value for the argument(s). Otherwise,, you would receive an error. If such an argument is passed with the same value over and over again, you may be tempted to remove the argument altogether. In some cases, although a certain argument is passed with the same value most of the time, you still have situations in which you want the user to decide whether to pass a value or not for the argument, you can declare the value optional. In other words, you can create the argument with a default value so that the user can call the procedure without passing a value for the argument, thus passing a value only when necessary. Such an argument is called default or optional.

Imagine you write a procedure that will be used to calculate the final price of an item after discount. The procedure would need the discount rate in order to perform the calculation. Such a procedure could look like this:


Module Module1

    Function CalculateNetPrice(ByVal DiscountRate As Double) As Double
        Dim OrigPrice As Double

        Console.Write("Please enter the original price: ")
        OrigPrice = Console.ReadLine()

        Return OrigPrice - (OrigPrice * DiscountRate / 100)

    End Function

End Module

Since this procedure expects an argument, if you do not supply it, the following program would not compile:


Module Module1

    Function CalculateNetPrice(ByVal DiscountRate As Double) As Double
        Dim OrigPrice As Double

        Console.Write("Please enter the original price: ")
        OrigPrice = Console.ReadLine()

        Return OrigPrice - (OrigPrice * DiscountRate / 100)

    End Function

    Sub Main()
        Dim FinalPrice As Double
        Dim Discount As Double = 15 ' That is 25% = 25

        FinalPrice = CalculateNetPrice(Discount)

        Console.WriteLine("Final Price = {0}", FinalPrice)
    End Sub

End Module

Most of the time, a procedure such as ours would use the same discount rate over and over again. Therefore, instead of supplying an argument all the time, you can define an argument whose value would be used whenever the function is not provided with the argument.

To specify that an argument is optional, when creating its procedure, type the Optional keyword to the left of the argument's name and assign it the default value. Here is an example:


Module Module1

    Function CalculateNetPrice(Optional ByVal DiscountRate As Double = 20) As Double
        Dim OrigPrice As Double

        Console.Write("Please enter the original price: ")
        OrigPrice = Console.ReadLine()

        Return OrigPrice - (OrigPrice * DiscountRate / 100)

    End Function

    Sub Main()
        Dim FinalPrice As Double

        FinalPrice = CalculateNetPrice()

        Console.WriteLine("Final Price = {0}", FinalPrice)
    End Sub

End Module

If a procedure takes more than one argument, you can provide a default argument for each and select which ones would have default values. If you want all arguments to have default values, when defining the procedure , provide the Optional keyword for each and assign it the desired default value. Here is an example:


Module Module1

    Function CalculateNetPrice(Optional ByVal Tax As Double = 5.75, _
                               Optional ByVal Discount As Double = 25, _
                               Optional ByVal OrigPrice As Double = 245.55) As Double
        Dim DiscountValue As Double = OrigPrice * Discount / 100
        Dim TaxValue As Double = Tax / 100
        Dim NetPrice As Double = OrigPrice - DiscountValue + TaxValue

        Console.WriteLine("Original Price: {0:C}", OrigPrice)
        Console.WriteLine("Discount Rate:  {0}%", Discount)
        Console.WriteLine("Tax Amount:     {0:C}", Tax)

        Return NetPrice
    End Function


    Sub Main()
        Dim FinalPrice As Double

        FinalPrice = CalculateNetPrice()
        Console.WriteLine("Final Price:    {0:C}", FinalPrice)
    End Sub

End Module

This would produce:

Original Price: $245.55
Discount Rate:  25%
Tax Amount:     $5.75
Final Price:    $184.22

If a procedure takes more than one argument as above, remember that some arguments can be specified as optional. In this case, when calling the procedure, any argument that doesn't have a default value must be passed with a value. When creating a procedure that takes more than one argument, the argument(s) that has(have) default value(s) must be the last in the procedure. This means that, if a procedure takes two arguments and one argument has a default value, this optional argument must be the second. If a procedure is taking three or more arguments and two or more arguments have default values, these optional arguments must by placed to the right of the non-optional argument(s). Because of this, when calling any procedure in VBasic, you must know what, if any, argument is optional and which one is not.

If a procedure takes two arguments and one argument has a default value, when calling this procedure, you can pass only one value. In this case, the passed value would be applied on the first argument. If a procedure takes more than two arguments and tow or more arguments have a default value, when calling this procedure, you can provide only the value(s) of the argument that is (are) not optional. If you want to provide the value of one of the arguments but that argument if not the first optional, you can leave empty the position(s) of the other argument(s) but remember to type a comma to indicate that the position is that of an argument that has a default value. Here is an example:


Module Module1

    Function CalculateNetPrice(ByVal AcquiredPrice As Double, _
                               ByVal MarkedPrice As Double, _
                               Optional ByVal TaxRate As Double = 5.75, _
                               Optional ByVal DiscountRate As Double = 25) As Double
        Dim DiscountAmount As Double = MarkedPrice * DiscountRate / 100
        Dim TaxAmount As Double = MarkedPrice * TaxRate / 100
        Dim NetPrice As Double = MarkedPrice - DiscountAmount + TaxAmount

        Console.WriteLine("Price Acquired: {0:C}", AcquiredPrice)
        Console.WriteLine("Marked Price:   {0:C}", MarkedPrice)
        Console.WriteLine("Discount Rate:  {0}%", DiscountRate)
        Console.WriteLine("Discount Amt:   {0:C}", DiscountAmount)
        Console.WriteLine("Tax Rate:       {0}%", TaxRate)
        Console.WriteLine("Tax Amount:     {0:C}", TaxAmount)

        Return NetPrice
    End Function


    Sub Main()
        Dim FinalPrice As Double

        FinalPrice = CalculateNetPrice(225.55, 150.55, , 40)
        Console.WriteLine("Final Price:    {0:C}", FinalPrice)
    End Sub

End Module

This would produce:

Price Acquired: $225.55
Marked Price:   $150.55
Discount Rate:  40%
Discount Amt:   $60.22
Tax Rate:       5.75%
Tax Amount:     $8.66
Final Price:    $98.99
 

Procedure Overloading

A program involves a great deal of names that represent variables and procedures of various kinds. The compiler does not allow two variables to have the same name in the same procedure (or in the same scope). Although two procedures should have unique names in the same program, you are allowed to use the same name for different procedures of the same program following certain rules. The ability to have various procedures with the same name in the same program is referring to as overloading. The most important rule about procedure overloading is to make sure that each one of these procedures has a different number or different type(s) of arguments.

The moment of inertia is the ability of of a beam to resist bending. It is calculated with regard to the cross section of the beam. Because it depends on the type of section of the beam, its calculation also depends on the type of section of the beam. In this exercise, we will review different formulas used to calculate the moment of inertia. Since this exercise is for demonstration purposes, you do not need to be a Science Engineering major to understand it.


 
The Moment Of Inertia

Here is an example that calculates the moment of inertia with regard to the X axis:


Module Module1

    ' Moment of Inertia
    ' Rectangle
    Function MomentOfInertia#(ByVal b#, ByVal h#)
        Return b * h * h * h / 3
    End Function

    Sub Main()
        Dim Base#, Height#

        Console.WriteLine("Enter the dimensions of the Rectangle\n")
        Console.Write("Base: ") : Base = Console.ReadLine()
        Console.Write("Height: ") : Height = Console.ReadLine()

        Console.WriteLine()
        Console.WriteLine("Moment of inertia with regard to the X axis: ")
        Console.WriteLine("I = {0}mm", MomentOfInertia(Base, Height))

    End Sub

End Module

This would produce:

Enter the dimensions of the Rectangle\n
Base: 3.25
Height: 2.85

Moment of inertia with regard to the X axis:
I = 25.07821875mm

Here are the formulas to calculate the moment of inertia for a semi-circle:

 
The Moment of Inertia for a Circle
 

A circle, and thus a semi-circle, requires only a radius. Since the other version of the MomentOfInertia() function requires two arguments, we can overload it by providing only one argument, the radius. Here is an example that calculates the moment of inertia with regard to the X or base axis, overloading the MomentOfInertia() function as follows:


Module Module1
' Moment of Inertia
    ' Rectangle
    Function MomentOfInertia#(ByVal b#, ByVal h#)
        Return b * h * h * h / 3
    End Function

    ' Semi-Circle
    Function MomentOfInertia#(ByVal R#)
        Const PI As Double = 3.14159

        Return R * R * R * R * PI / 8
    End Function

    Sub Main()
        Dim Base#, Height#, Radius#

        Console.WriteLine("Enter the dimensions of the Rectangle\n")
        Console.Write("Base:   ") : Base = Console.ReadLine()
        Console.Write("Height: ") : Height = Console.ReadLine()

        Console.WriteLine()
        Console.WriteLine("Moment of inertia with regard to the X axis: ")
        Console.WriteLine("I = {0}mm", MomentOfInertia(Base, Height))

        Console.WriteLine()
        Console.Write("Enter the radius: ") : Radius = Console.ReadLine()

        Console.WriteLine()
        Console.WriteLine("Moment of inertia of a semi-circle with regard to the X axis: ")
        Console.WriteLine("I = {0}mm", MomentOfInertia(Radius))

        Console.WriteLine()
    End Sub

End Module

Here is an example of running the program:

Enter the dimensions of the Rectangle\n
Base:   16.58
Height: 12.44

Moment of inertia with regard to the X axis:
I = 10639.5782395733mm

Enter the radius: 15.68

Moment of inertia of a semi-circle with regard to the X axis:
I = 23737.9795990479mm

If you create more than two procedures that have the same name, as mentioned already, the procedure is said to be overloaded. To indicated that a procedure is overloaded, you can type the Overloads keyword when defining each of the procedures that are overloaded. The above program can be written as follows:


Module Module1
' Moment of Inertia
    ' Rectangle
    Overloads Function MomentOfInertia#(ByVal b#, ByVal h#)
        Return b * h * h * h / 3
    End Function

    ' Semi-Circle
    Overloads Function MomentOfInertia#(ByVal R#)
        Const PI As Double = 3.14159

        Return R * R * R * R * PI / 8
    End Function

    Sub Main()
        Dim Base#, Height#, Radius#

        Console.WriteLine("Enter the dimensions of the Rectangle\n")
        Console.Write("Base:   ") : Base = Console.ReadLine()
        Console.Write("Height: ") : Height = Console.ReadLine()

        Console.WriteLine()
        Console.WriteLine("Moment of inertia with regard to the X axis: ")
        Console.WriteLine("I = {0}mm", MomentOfInertia(Base, Height))

        Console.WriteLine()
        Console.Write("Enter the radius: ") : Radius = Console.ReadLine()

        Console.WriteLine()
        Console.WriteLine("Moment of inertia of a semi-circle with regard to the X axis: ")
        Console.WriteLine("I = {0}mm", MomentOfInertia(Radius))

        Console.WriteLine()
    End Sub

End Module

 

 
 

Previous Copyright © 2004-2007 FunctionX, Inc. Next