Advantages of subroutines
Why Use Subroutines?
Any program could, in theory, be written as one long sequence of instructions with no subroutines at all. In practice, this quickly becomes unmanageable. Subroutines bring four key advantages that make programs shorter, safer to change, and much easier for other people - or your future self - to understand.
| Advantage | What it means in practice |
|---|---|
| Reusability | Write the code once; call it as many times as needed from anywhere in the program. |
| Easier maintenance | A bug fix or improvement is made in one place and automatically applies everywhere the subroutine is called. |
| Readability | A well-named subroutine makes the calling code read almost like plain English, so the program's purpose is immediately clear. |
| Decomposition | Large, complex problems are broken into smaller, focused subroutines that can each be written and tested independently. |
Advantages in Practice
The three examples below each highlight a different advantage. Select a tab to explore it, then choose a language.
The showBanner() subroutine is needed at the start of every section of a quiz. Rather than duplicating those three output lines three times, the subroutine is defined once and called wherever it is needed. Any one of those calls runs exactly the same block of code.
# Python -- reusability: define once, call three times
def showBanner():
print("====================")
print(" Welcome to Quiz ")
print("====================")
showBanner() # called before Round 1
print("Round 1 - Geography")
showBanner() # called before Round 2
print("Round 2 - Science")
showBanner() # called before Round 3
print("Round 3 - History")
' VB.NET -- reusability: define once, call three times
Sub showBanner()
Console.WriteLine("====================")
Console.WriteLine(" Welcome to Quiz ")
Console.WriteLine("====================")
End Sub
showBanner() ' called before Round 1
Console.WriteLine("Round 1 - Geography")
showBanner() ' called before Round 2
Console.WriteLine("Round 2 - Science")
showBanner() ' called before Round 3
Console.WriteLine("Round 3 - History")
// C# -- reusability: define once, call three times
static void ShowBanner()
{
Console.WriteLine("====================");
Console.WriteLine(" Welcome to Quiz ");
Console.WriteLine("====================");
}
ShowBanner(); // called before Round 1
Console.WriteLine("Round 1 - Geography");
ShowBanner(); // called before Round 2
Console.WriteLine("Round 2 - Science");
ShowBanner(); // called before Round 3
Console.WriteLine("Round 3 - History");
Suppose the banner needs updating - perhaps adding a star border instead of equals signs. Because the output is inside a subroutine, one edit to the subroutine body instantly changes every call. Without a subroutine, the same edit would have to be made in three separate places, risking inconsistency if any were missed.
# Python -- maintenance: edit ONE line inside the subroutine;
# all three calls automatically use the updated version
def showBanner():
print("********************") # changed from "==" to "**" in one place
print(" Welcome to Quiz ")
print("********************")
showBanner() # all three calls now display the new banner
showBanner()
showBanner()
' VB.NET -- maintenance: edit ONE line inside the subroutine;
' all three calls automatically use the updated version
Sub showBanner()
Console.WriteLine("********************") ' changed in one place
Console.WriteLine(" Welcome to Quiz ")
Console.WriteLine("********************")
End Sub
showBanner() ' all three calls now display the new banner
showBanner()
showBanner()
// C# -- maintenance: edit ONE line inside the subroutine;
// all three calls automatically use the updated version
static void ShowBanner()
{
Console.WriteLine("********************"); // changed in one place
Console.WriteLine(" Welcome to Quiz ");
Console.WriteLine("********************");
}
ShowBanner(); // all three calls now display the new banner
ShowBanner();
ShowBanner();
Here, a complete school report program is broken into four focused subroutines. The main flow at the bottom reads almost like a plain-English description of the program. Each subroutine can be written, tested, and corrected independently before being combined - a significant advantage for larger projects.
# Python -- decomposition: complex program split into named subroutines
def showHeader():
print("--- School Report ---")
def collectGrades():
print("Entering grades...") # would contain real input logic
def calculateAverage():
print("Calculating average...") # would contain real calculation logic
def printReport():
print("Printing final report...") # would contain real output logic
# Main program flow -- reads like a description of what the program does
showHeader()
collectGrades()
calculateAverage()
printReport()
' VB.NET -- decomposition: complex program split into named subroutines
Sub showHeader()
Console.WriteLine("--- School Report ---")
End Sub
Sub collectGrades()
Console.WriteLine("Entering grades...") ' would contain real input logic
End Sub
Sub calculateAverage()
Console.WriteLine("Calculating average...") ' would contain real calculation logic
End Sub
Sub printReport()
Console.WriteLine("Printing final report...") ' would contain real output logic
End Sub
' Main program flow -- reads like a description of what the program does
showHeader()
collectGrades()
calculateAverage()
printReport()
// C# -- decomposition: complex program split into named subroutines
static void ShowHeader()
{ Console.WriteLine("--- School Report ---"); }
static void CollectGrades()
{ Console.WriteLine("Entering grades..."); } // would contain real input logic
static void CalculateAverage()
{ Console.WriteLine("Calculating average..."); } // would contain real calculation logic
static void PrintReport()
{ Console.WriteLine("Printing final report..."); } // would contain real output logic
// Main program flow -- reads like a description of what the program does
ShowHeader();
CollectGrades();
CalculateAverage();
PrintReport();
Key Takeaways
- Reusability: a subroutine written once can be called any number of times, eliminating duplicated code.
- Easier maintenance: a fix or improvement made inside a subroutine automatically applies to every call - there is only one place to change.
- Readability: calling subroutines with meaningful names makes the main program flow read like a clear description of what the program does.
- Decomposition: subroutines allow a large problem to be broken into smaller, independently testable pieces - each subroutine can be verified before being combined.