Understanding the scope and lifetime of variables is crucial for writing efficient and error-free Fortran programs. This topic will cover the following key concepts:
-
Variable Scope
- Local Scope
- Global Scope
- Module Scope
-
Variable Lifetime
- Static Lifetime
- Dynamic Lifetime
-
Practical Examples
-
Exercises
Variable Scope
Local Scope
Variables declared within a subroutine, function, or block are local to that scope. They can only be accessed within the block where they are declared.
program local_scope_example implicit none call mySubroutine() contains subroutine mySubroutine() integer :: localVar localVar = 10 print *, "Local variable value: ", localVar end subroutine mySubroutine end program local_scope_example
Explanation:
localVar
is declared insidemySubroutine
and is only accessible within this subroutine.
Global Scope
Variables declared outside any subroutine or function are global and can be accessed from anywhere in the program.
program global_scope_example implicit none integer :: globalVar globalVar = 20 call printGlobalVar() contains subroutine printGlobalVar() print *, "Global variable value: ", globalVar end subroutine printGlobalVar end program global_scope_example
Explanation:
globalVar
is declared in the main program and is accessible within theprintGlobalVar
subroutine.
Module Scope
Variables declared in a module can be accessed by any program unit that uses the module.
module myModule implicit none integer :: moduleVar end module myModule program module_scope_example use myModule implicit none moduleVar = 30 call printModuleVar() contains subroutine printModuleVar() print *, "Module variable value: ", moduleVar end subroutine printModuleVar end program module_scope_example
Explanation:
moduleVar
is declared inmyModule
and is accessible in the main program and theprintModuleVar
subroutine.
Variable Lifetime
Static Lifetime
Variables with a static lifetime exist for the duration of the program. They retain their values between calls to subroutines or functions.
program static_lifetime_example implicit none call incrementCounter() call incrementCounter() contains subroutine incrementCounter() integer, save :: counter = 0 counter = counter + 1 print *, "Counter value: ", counter end subroutine incrementCounter end program static_lifetime_example
Explanation:
- The
save
attribute ensures thatcounter
retains its value between calls toincrementCounter
.
Dynamic Lifetime
Variables with a dynamic lifetime exist only during the execution of the block in which they are declared. They are created when the block is entered and destroyed when the block is exited.
program dynamic_lifetime_example implicit none call mySubroutine() call mySubroutine() contains subroutine mySubroutine() integer :: localVar localVar = 10 print *, "Local variable value: ", localVar end subroutine mySubroutine end program dynamic_lifetime_example
Explanation:
localVar
is created and destroyed each timemySubroutine
is called.
Practical Examples
Example 1: Local and Global Scope
program scope_example implicit none integer :: globalVar globalVar = 5 call subroutineA() call subroutineB() contains subroutine subroutineA() integer :: localVar localVar = 10 print *, "Subroutine A - Local variable: ", localVar print *, "Subroutine A - Global variable: ", globalVar end subroutine subroutineA subroutine subroutineB() print *, "Subroutine B - Global variable: ", globalVar end subroutine subroutineB end program scope_example
Explanation:
globalVar
is accessible in bothsubroutineA
andsubroutineB
.localVar
is only accessible withinsubroutineA
.
Example 2: Module Scope
module myModule implicit none integer :: moduleVar end module myModule program module_example use myModule implicit none moduleVar = 15 call subroutineC() contains subroutine subroutineC() print *, "Subroutine C - Module variable: ", moduleVar end subroutine subroutineC end program module_example
Explanation:
moduleVar
is declared inmyModule
and is accessible in both the main program andsubroutineC
.
Exercises
Exercise 1: Local and Global Scope
Write a program that declares a global variable and a local variable within a subroutine. Modify the values of both variables and print them inside and outside the subroutine.
Solution:
program exercise1 implicit none integer :: globalVar globalVar = 100 call modifyVariables() print *, "Main Program - Global variable: ", globalVar contains subroutine modifyVariables() integer :: localVar localVar = 50 globalVar = 200 print *, "Subroutine - Local variable: ", localVar print *, "Subroutine - Global variable: ", globalVar end subroutine modifyVariables end program exercise1
Exercise 2: Static and Dynamic Lifetime
Write a program with a subroutine that uses a static variable and a dynamic variable. Call the subroutine multiple times and observe the behavior of both variables.
Solution:
program exercise2 implicit none call testLifetime() call testLifetime() contains subroutine testLifetime() integer, save :: staticVar = 0 integer :: dynamicVar staticVar = staticVar + 1 dynamicVar = 1 print *, "Static variable: ", staticVar print *, "Dynamic variable: ", dynamicVar end subroutine testLifetime end program exercise2
Conclusion
In this section, we covered the scope and lifetime of variables in Fortran. Understanding these concepts is essential for managing data effectively and avoiding common programming errors. We explored local, global, and module scopes, as well as static and dynamic lifetimes, with practical examples and exercises to reinforce the concepts. In the next module, we will delve into advanced data structures, starting with derived types.
Fortran Programming Course
Module 1: Introduction to Fortran
- Introduction to Fortran
- Setting Up the Development Environment
- Basic Syntax and Structure
- Writing Your First Fortran Program
Module 2: Basic Concepts
- Variables and Data Types
- Operators and Expressions
- Input and Output
- Control Structures: If Statements
- Control Structures: Loops
Module 3: Arrays and Strings
Module 4: Procedures and Functions
Module 5: Advanced Data Structures
Module 6: File Handling
Module 7: Advanced Topics
Module 8: Best Practices and Optimization
- Code Optimization Techniques
- Debugging and Profiling
- Writing Maintainable Code
- Fortran Standards and Portability