сохранение ограничений массива в фортране во время вызова подпрограммы - PullRequest
5 голосов
/ 06 декабря 2010

У меня есть следующая программа

module test
contains
   subroutine foo()
      integer, allocatable :: a(:)
      allocate(a(-5:5))
      call bar(a)
      print *, a
   end subroutine
   subroutine bar(a)
      integer, intent(out) :: a(:)
      a = 0 
      a(-4) = 3  ! here
      a(2) = 3   
   end subroutine
end module

program x
   use test
   call foo()
end program

В строке, отмеченной «здесь», я делаю что-то не так. Дело в том, что когда я получаю массив a (в вызывающем абоненте, выделенном от -5 до +5), вызываемый абонент использует обычную нумерацию (от 1 до n), что означает, что при назначении -4 я выполняю внешнее назначение. Как я могу указать компилятору, что в процедуре bar нумерация массива a должна быть такой же, как в вызывающей программе?

Ответы [ 3 ]

4 голосов
/ 06 декабря 2010

Тип фиктивного аргумента, который вы используете в подпрограмме, с размером, указанным с помощью двоеточия, называется «предполагаемая форма». Это имя является ключом - Фортран передает только форму, а не нижнюю и верхнюю границы. Нижняя граница считается равной единице, если вы не переопределите ее, как показано в ответе Кемиисто. Если нижняя граница не фиксирована, вы можете передать аргумент для использования в качестве нижней границы.

Позднее добавление: пример кода, если нижнее измерение не известно во время компиляции:

subroutine example (low, array)
   integer, intent (in) :: low
   real, dimension (low:), intent (out) :: array
3 голосов
/ 07 декабря 2010

Существует два распространенных варианта:

  • Как писал Кемисто, вы передаете второй аргумент. Это было распространено в коде стиля F77. Вы не можете использовать трюк LBOUND! Он должен быть передан как целое число.
  • Вы объявляете аргумент указателем, который включает в себя весь дескриптор массива. Тогда границы массива в подпрограмме такие же, как в вызывающей области видимости. Конечно, вы можете потерять оптимизацию таким образом.
2 голосов
/ 06 декабря 2010

Как я могу указать компилятору, что в подпрограмме bar нумерация массива должна быть такой же, как в вызывающей программе?

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

subroutine bar(a)
      integer, intent(out) :: a(-5:)
...