Может ли функция на Фортране возвращать несколько переменных? - PullRequest
2 голосов
/ 30 апреля 2020

В приведенном ниже примере функции как определить, являются ли a, b или c значениями ввода или вывода, отличными от контекста?

Кроме того, если вызывается example() значение, присвоенное c, выходит за рамки example()?

function example(a, b, c)
   real*8 a, b, c
   c = a + b
   example = c
end function example

Ответы [ 2 ]

3 голосов
/ 30 апреля 2020

У вас есть ответ, который говорит о намерениях для аргументов. Они предоставляют ценные советы программисту (в форме документации) и компилятору о том, как используются аргументы. Эти намерения дают представление об ограничениях для аргумента и применяются к процедурам (подпрограммам, а также функциям) более широко.

Однако некоторым фиктивным аргументам может даже не быть предоставлено намерение. Кроме того, спецификация намерения не означает, что аргумент используется таким образом (на аргументы intent (in) не нужно ссылаться; переменные intent (inout) не нужно изменять; аргументы intent (out) не нужно определять) ).

В конечном итоге вам нужно будет посмотреть на поведение функции.

Учитывая функцию вопроса

function example(a, b, c)
   real*8 a, b, c
   c = a + b
   example = c
end function example

, мы можем рассмотреть a и b быть «входами», и они должны быть определены, когда функция введена, и их значения используются при оценке результата функции. Результат функции называется example, но есть побочный эффект изменения c, «вывода». Его значение при входе в функцию не нужно, и его даже не нужно определять.

Теперь, поскольку это Фортран, есть тонкость, на которую следует обратить внимание. Вы спрашиваете

- это значение, присвоенное c вне области действия example?

, и ответ: возможно .

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

Обратите внимание:

implicit none
real*8 a, b, c, d
real*8 example  ! Really you should be using an explicit interface

a = 1.
b = 2.
c = 0.
d = 0.

print*, example(a,b,c)
print*, c

if (.false..and.example(a,b,d)>0) print*

end program

тогда, хотя значение c изменяется по этой ссылке на функцию, переменная d фактически становится undefined! 1


1 Под "неопределенным" я подразумеваю, что у него нет значения, которое можно надежно запросить или использовать. Поскольку Fortran позволяет компилятору замыкать оценку функции, но не требует этого, он говорит, что значение становится неопределенным. Вы не можете полагаться на побочные эффекты от функции, если не уверены, что функция используется.

3 голосов
/ 30 апреля 2020

Fortran имеет возможность указать атрибут намерения:

Атрибут INTENT определяет предполагаемое использование фиктивного аргумента. Фиктивный аргумент INTENT (IN) подходит для получения данных от вызывающей единицы определения объема, фиктивный аргумент INTENT (OUT) подходит для возврата данных в вызывающую единицу определения объема, а фиктивный аргумент INTENT (INOUT) подходит для использования как для получать данные и возвращать данные в вызывающий модуль определения объема.

Кроме того, можно указать атрибут результата или задать тип функции, поэтому можно написать:

double precision function example(a, b, c)
   implicit none
   double precision, intent(in) :: a, b
   double precision, intent(out) :: c
   c = a + b
   example = c
end function example

или

function example(a, b, c) result(res)
   implicit none
   double precision, intent(in) :: a, b
   double precision, intent(out) :: c
   double precision :: res
   c = a + b
   res = c
end function example

Примечание: я также добавил «неявное нет» и заменил вещественное * 8 двойной точностью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...