Subs and Functions
Prerequisites: Arrays
Procedures let you name a piece of code and reuse it. VB has two kinds:
- A
Subdoes something and returns nothing. - A
Functioncomputes and returns a value.
Module Program
Sub Greet(name As String)
Console.WriteLine($"Hello, {name}!")
End Sub
Function Square(x As Integer) As Integer
Return x * x
End Function
Function Bmi(weightKg As Double, heightM As Double) As String
Dim value = weightKg / (heightM * heightM)
Dim category As String
If value < 18.5 Then
category = "underweight"
ElseIf value < 25 Then
category = "normal"
Else
category = "overweight"
End If
Return $"{value:F1} ({category})"
End Function
Sub Main()
Greet("Ada")
Console.WriteLine(Square(6))
Console.WriteLine(Square(Square(2)))
Console.WriteLine(Bmi(70, 1.75))
End Sub
End Module
Hello, Ada!
36
16
22.9 (normal)
- Parameters are written
name As Type; the return type goes after the parentheses:Function Square(...) As Integer. Return valueends the function and hands back the value.- Variables declared inside a procedure (
value,category) are local to it.
Returning early
Return can appear anywhere, which keeps code flat:
Module Program
Function Classify(age As Integer) As String
If age < 0 Then Return "invalid"
If age < 13 Then Return "child"
If age < 20 Then Return "teen"
Return "adult"
End Function
Sub Main()
For Each a In {-1, 8, 15, 42}
Console.WriteLine($"{a}: {Classify(a)}")
Next
End Sub
End Module
-1: invalid
8: child
15: teen
42: adult
In a Sub, Return (or the older Exit Sub) leaves early.
Recursion
A function can call itself:
Module Program
Function Factorial(n As Integer) As Long
If n <= 1 Then Return 1
Return n * Factorial(n - 1)
End Function
Sub Main()
Console.WriteLine(Factorial(5))
Console.WriteLine(Factorial(20))
End Sub
End Module
120
2432902008176640000
The old way: assigning to the function name
Older code returns a value by assigning it to the function's name:
Module Program
Function Double2(x As Integer) As Integer
Double2 = x * 2
End Function
Sub Main()
Console.WriteLine(Double2(21))
End Sub
End Module
42
It still works, but Return is clearer and is the modern style.
Practice
Write Function IsLeapYear(year As Integer) As Boolean (divisible by 4,
except centuries unless divisible by 400) and print the result for
1900, 2000, and 2024.
Show solution
Module Program
Function IsLeapYear(year As Integer) As Boolean
Return (year Mod 4 = 0 AndAlso year Mod 100 <> 0) OrElse year Mod 400 = 0
End Function
Sub Main()
For Each y In {1900, 2000, 2024}
Console.WriteLine($"{y}: {IsLeapYear(y)}")
Next
End Sub
End Module
1900: False
2000: True
2024: True