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:

  1. Variable Scope

    • Local Scope
    • Global Scope
    • Module Scope
  2. Variable Lifetime

    • Static Lifetime
    • Dynamic Lifetime
  3. Practical Examples

  4. 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 inside mySubroutine 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 the printGlobalVar 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 in myModule and is accessible in the main program and the printModuleVar 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 that counter retains its value between calls to incrementCounter.

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 time mySubroutine 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 both subroutineA and subroutineB.
  • localVar is only accessible within subroutineA.

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 in myModule and is accessible in both the main program and subroutineC.

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.

© Copyright 2024. All rights reserved