Указатель функции выстраивает в Фортране

Я могу создать указатели функции в Фортране 90 с кодом как

real, external :: f

и затем используйте f как аргумент другой функции/подпрограмме. Но что, если я хочу массив указателей функции? В C я просто сделал бы

double (*f[])(int);

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

real, external, dimension(3) :: f

но gfortran не позволяет мне смешаться ВНЕШНИЙ и РАЗМЕР. Там какой-либо путь состоит в том, чтобы сделать то, что я хочу? (Контекст для этого является программой для решения системы дифференциальных уравнений, таким образом, я мог ввести уравнения, не имея миллиона параметров в моих подпрограммах.)

11
задан Eduardo Dobay 26 March 2010 в 03:59
поделиться

1 ответ

Объявление "real, external :: f" на самом деле не превращает "f" в полный указатель, так как вы не можете изменить процедуру, очков - он позволяет передать эту единственную функцию другой подпрограмме. Таким образом, вам также понадобится атрибут «указатель». На странице 267 книги «Fortran 95/2003, объясненной» Меткалфом, Рейдом и Коэном есть примеры - поиск в Google по запросу «указатель процедуры fortran» откроет эту страницу. Простой пример, близкий к вашему - "реальный, внешний, указатель :: f_ptr". Как вариант: «процедура (f), указатель :: f_ptr». Это функция Fortran 2003 - http://gcc.gnu.org/wiki/Fortran2003 и http://gcc.gnu.org/wiki/ProcedurePointers перечисляет частичную поддержку в гфортране лучше всего с 4.5. Я не уверен, разрешено ли «измерение» напрямую, но вы можете назначить процедуру указателю, что обеспечивает большую гибкость. Вы также можете поместить указатель в производный тип, который может быть преобразован в массив.

Edit: вот пример кода, который работает с gfortran 4.5: Edit 2: строка закомментирована согласно комментариям ниже.

module ExampleFuncs

  implicit none

contains

function f1 (x)
  real :: f1
  real, intent (in) :: x

  f1 = 2.0 * x

  return
end function f1


function f2 (x)
   real :: f2
   real, intent (in) :: x

   f2 = 3.0 * x**2

   return
end function f2


function fancy (func, x)

   real :: fancy
   real, intent (in) :: x

   interface AFunc
      function func (y)
         real :: func
         real, intent (in) ::y
      end function func
   end interface AFunc

   fancy = func (x) + 3.3 * x

end function fancy

end module  ExampleFuncs

program test_proc_ptr

  use ExampleFuncs

  implicit none

  ! REMOVE: pointer :: func
  interface
     function func (z)
        real :: func
        real, intent (in) :: z
     end function func
  end interface

  procedure (func), pointer :: f_ptr => null ()

  type Contains_f_ptr
     procedure (func), pointer, nopass :: my_f_ptr
  end type Contains_f_ptr

  type (Contains_f_ptr), dimension (2) :: NewType


  f_ptr => f1
  write (*, *) f_ptr (2.0)
  write (*, *) fancy (f_ptr, 2.0)

  f_ptr => f2
  write (*, *) f_ptr (2.0)
  write (*, *) fancy (f_ptr, 2.0)

  NewType(1) % my_f_ptr => f1
  NewType(2) % my_f_ptr => f2

  write (*, *) NewType(1) % my_f_ptr (3.0), NewType(2) % my_f_ptr (3.0)

  stop

end program test_proc_ptr
17
ответ дан 3 December 2019 в 07:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: