Stack frames are used to store return addresses, parameters and local variables for subroutine calls
Every time a subroutine is called, it is pushed onto the stack as a stack frame
When a subroutine is finished, the stack frame is popped from the stack to retrieve the return address
Subroutines help reduce repeated code for frequently used operations, which also makes code easier to read
A function returns a value, a procedure does not
Subroutines are out of line blocks of code which are not defined within the main body of code
Parameters are used to pass data into and between subroutines. The specific value passed in is called an argument.
Parameters may be required or optional, or not needed at all depending on the subroutine
Global variables are declared at the top of the program outside any subroutines. They can be used anywhere, and exist as long as the program is running
Local variables are declared within subroutines and are stored on the call stack. They are destroyed once the subroutine ends.
Local variables are more memory efficient and are better for multi-person projects
Exception handling allows programs to 'try' code that may crash due to erroneous input, and 'catch' any errors that occur, carrying out a separate set of tasks and returning to operating as normal
A recursive subroutine calls itself within its own subroutine, and has a stopping condition (a base case)
If a recursive subroutine doesn't have a base case, it will never terminate and a stack overflow will occur
Many recursive solutions can also be implemented using iteration. Recursion may allow for more compact code; iteration may be less memory intensive