2016-02-27 4 views
0

Как вы проверяете значения в Fortran, как в Matlab? Например, в маленькой программе, почему она показывает c=0 в главном, когда она c=36 в подпрограмме testing? Как вы делаете так c=36 в основной программе?Проверить значения локальных переменных в подпрограммах извне

Можете ли вы назвать значение c каким-то образом? Я понимаю, что в основной программе переменная c либо не определена, либо имеет значение 0, но есть ли способ сохранить значение c в подпрограмме, чтобы вы могли использовать ее снова в других подпрограммах, не вычисляя ее снова?

Когда программа достаточно велика, удобно проверять значения по мере их поступления.

program main 

use test 

implicit none 

integer :: a,b,c 

call testing(a,b) 

write(*,*)'Test of c in main program',c 


end program main 



module test 

implicit none 


contains 


subroutine testing(a,b) 

integer :: a,b,c 

a=2 
b=3 

c=(a*b)**a 

write(*,*)'Value of c in subroutine',c 

end subroutine testing 

end module test 
+2

Вы спрашиваете «почему это значение переменной' c' в основной программе (которая не определена) не совпадает со значением переменной 'c' в подпрограмме ? "? – francescalus

+0

Нет, больше похоже на то, как вы вызываете значение c из подпрограммы «тестирование», так что она становится 36 в основной программе. –

+0

Посмотрите мой комментарий http://stackoverflow.com/questions/35604523/fortran-reusing-a-variable-in-different-subroutine#comment58893727_35604523 и комментарий @ VladimirF рядом с ним. –

ответ

1

Это желаемое поведение. В принципе, вызывающая процедура не должна ничего знать о подпрограмме, кроме как ее вызвать и что вернуться. Это называется инкапсуляцией.

Вы можете сделать переменные доступными для вызывающей программы, объявив его в самом модуле, а не в подпрограмме:

module test 
    implicit none 
    integer :: c 

contains 

    subroutine testing(a, b) 
     implicit none 
     integer :: a, b 

     a = 2 
     b = 3 
     c = (a*b) ** a 

     write(*, *) "Value of c in the subroutine: ", c 
    end subroutine testing 

end module test 

program main 

    use test 
    implicit none 
    integer :: a, b 

    call testing(a, b) 

    write(*, *) "Test of c in the main program: ", c 

end program main 

Заметим, что вы не должны объявлять c в основной программе, так как она получит переменная от модуля.

Вы также можете использовать блок COMMON, но модули намного превосходят.

3

Важно знать о scope в языках программирования.

Каждое имя (идентификатор) имеет ограниченный диапазон действительности.

Если объявить некоторые переменные внутри подпрограммы

subroutine s 
    integer :: i 
end subroutine 

чем i действителен только в этой подпрограмме.

Если вы объявляете переменную в модуле

module m 
    integer :: i 
contains 
    subroutines and functions 
end module 

то i действует внутри всех этих подпрограмм и функций, а также во всех программных модулей, которые use этот модуль.

Однако это не означает, что вы должны объявить переменную в модуле и просто поделиться ею. Это будет более или менее global variable. Это зарезервировано только для определенных случаев, где это необходимо, но не для получения результатов из ваших подпрограмм.

Если подпрограмма просто вычисляет что-то, и вы хотите, чтобы получить результат этого вычисления у вас есть две возможности:

1. передать его в качестве дополнительного аргумента, который будет определен подпрограммой

subroutine testing(a, b, c) 
    integer, intent(in) :: a, b 
    integer, intent(out) :: c 

    c = (a*b) ** a 
end subroutine 

вы затем вызвать его как

call testing(2, 3, c) 
print *, "result is:" c 

2. Сделать это функция

function testing(a, b) result(c) 
    integer, intent(in) :: a, b 
    integer :: c 

    c = (a*b) ** a 
end function 

и то вы можете использовать напрямую

c = testing(2, 3) 
print *, "result is:", c 

или просто

print *, "result is:", testing(2, 3)