Я новичок в Фортране, и мне интересно, как правильно «обернуть» подпрограммы.
Например. Предположим, у меня есть основная программа, которая вызывает некоторую подпрограмму outer
, которая проверяет флаг, а затем вызывает другую подпрограмму inner_1
или inner_2
, в зависимости от значения flag
. Он передает аргументы внутренним подпрограммам.
По наивности, я могу просто создать подпрограмму outer
, затем проверить флаг и вызвать внутренние подпрограммы. Но для этого необходимо объявить все переменные, передаваемые в outer
, просто для того, чтобы передать их внутренним подпрограммам. Для многих аргументов это кажется громоздким.
Это стандартный способ добиться этого или есть какой-то лучший способ, о котором я не знаю?
Я написал рабочий пример:
program main
use m_mod, only : outer
implicit none
real :: a = 1.0
integer :: b = 1
integer :: flag
flag = 1
call outer(a,b,flag)
flag = 2
call outer(a,b,flag)
end program main
module m_mod
implicit none
private
public :: outer
contains
subroutine outer(a,b,flag)
real, intent(in) :: a
integer, intent(in) :: b
integer, intent(in) :: flag
if (flag == 1) then
call inner_1(a,b)
else
call inner_2(a,b)
end if
end subroutine outer
subroutine inner_1(a,b)
real, intent(in) :: a
integer, intent(in) :: b
write(*,*) "inner_1-a", a
write(*,*) "inner_1-b", b
end subroutine inner_1
subroutine inner_2(a,b)
real, intent(in) :: a
integer, intent(in) :: b
write(*,*) "inner_2-a", a
write(*,*) "inner_2-b", b
end subroutine inner_2
end module m_mod
который выводит
inner_1-a 1.00000000
inner_1-b 1
inner_2-a 1.00000000
inner_2-b 1
как и ожидалось. Я просто хочу знать, есть ли лучший способ сделать это!
Существует много «сложных» способов, которые могут быть «лучше» в каком-то субъективном смысле, но вы должны спросить себя: является ли метод, который я выбрал, четким выражением логики, которую я хочу реализовать? Кажется, трудно утверждать, что это не так.
@francescalus спасибо за вклад. Это определенно «сработало», поэтому я был счастлив, но мне хотелось знать, существует ли стандартный, лучший способ. Ваш ответ говорит мне, что нет, поэтому я счастлив. Если для вас это того стоит, напишите это в качестве ответа, и я приму его.
Если вы хотите сохранить независимость внутренних процедур (т. е. их можно вызывать из других процедур, кроме оберточной), другого очевидного решения не существует. В противном случае вы можете преобразовать их в автономные процедуры без повторения списка аргументов:
module m_mod
implicit none
private
public :: outer
contains
subroutine outer(a,b,flag)
real, intent(in) :: a
integer, intent(in) :: b
integer, intent(in) :: flag
if (flag == 1) then
call inner_1()
else
call inner_2()
end if
CONTAINS
! a, b, (and flag), are available to the contained routines
! thanks to host association
subroutine inner_1()
write(*,*) "inner_1-a", a
write(*,*) "inner_1-b", b
end subroutine inner_1
subroutine inner_2()
write(*,*) "inner_2-a", a
write(*,*) "inner_2-b", b
end subroutine inner_2
end subroutine outer
end module m_mod
Я хочу, чтобы они были конфиденциальными, а процедура упаковки — единственная, которая с ними общается, так что это идеально.
Добро пожаловать, используйте тег fortran для вопросов по Fortran и следуйте инструкциям, отображаемым в кратком описании добавляемых вами тегов. Ваша подпись автоматически отображается под вашим вопросом или ответом и, следовательно, ее не следует писать в тексте вопроса.