Wrong result when using a global variable in Fortran

前端 未结 2 2047
猫巷女王i
猫巷女王i 2020-12-07 06:11

I\'m learning the basics of Fortran. I created a simple subroutine initializing a matrix:

program test
   integer, parameter :: n = 1024
   real :: a(n, n)
          


        
相关标签:
2条回答
  • 2020-12-07 06:54

    n is not a global variable, it is a local variable of the main program.

    The subroutine is a completely independent compilation unit from the main program and they do not share any information.

    A subroutine can "see" other variables of the parent module, if it is a module procedure, or variables of a parent (host) procedure or program if it is an internal procedure.

    Be sure to read about the structure of Fortran programs and use modules as much as possible. Prefer modules over internal procedures. You will see how to put the subroutine into a module or how to make it internal to the main program in the link.

    I did not mention common blocks, just don't use them, they are obsolete. And rember to use implicit none in every compilation unit.

    0 讨论(0)
  • 2020-12-07 07:01

    Assuming that you want it everywhere, then one uses a COMMON block in the f77 era, and a MODULE now.

    I CAPITALISED most of the changes. And if there is no error gives a few ways to consider understanding N in the SUBROUTINE, and an ELEMENTAL FUNCTION would likely be worthwhile to try here too.

    MODULE MyMODULE
      integer, parameter :: n = 1024
    END MODULE MyMODULE
    
    !%%%%%%%%%% 
    program test
    USE MyModule
    IMPLICIT NONE
    ! done up in ˆmoduleˆ...!  integer, parameter :: n = 1024
    REAL, DIMENSION(n,n) :: A
    
    CALL Alternative_Init(A, 3.3)
    WRITE (*,*) a(1, 1)
    
    CALL Alternative2_Init(A, n, 1.23)
    WRITE (*,*) a(1, 1)
    
    call init(a)
    write (*, *) a(1, 1)
    END PROGRAM TEST
    
    !%%%%%%%%%% 
    subroutine init(a)
    USE MyModule
    IMPLICIT NONE
    
    real :: a(n, n)
    a(:, :) = 3.0
    
    RETURN
    END SUBROUTINE init
    
    
    !%%%%%%%%%% 
    SUBROUTINE Alternative_Init(a, Val4A)
    USE MyModule
    IMPLICIT NONE
    
    REAL, DIMENSION(:,:) , INTENT(INOUT) :: a
    REAL                 , INTENT(IN  )  :: Val4A
    
    a(:, :) = Val4A
    ! or just... A = Val4A ! which does them all too.
    
    RETURN
    END SUBROUTINE Alternative_Init
    
    !%%%%%%%%%% 
    SUBROUTINE Alternative2_Init(a, n, Val4A)
    !!!!  USE MyModule
    IMPLICIT NONE
    
    INTEGER              , INTENT(IN   ) :: n
    REAL, DIMENSION(n,n) , INTENT(  OUT) :: a
    REAL                 , INTENT(IN   ) :: Val4A
    
    A = Val4A
    
    RETURN
    END SUBROUTINE Alternative2_Init
    
    0 讨论(0)
提交回复
热议问题