Я могу создать указатели функции в Фортране 90 с кодом как
real, external :: f
и затем используйте f
как аргумент другой функции/подпрограмме. Но что, если я хочу массив указателей функции? В C я просто сделал бы
double (*f[])(int);
создать массив функций, возвращаясь дважды и беря целочисленный аргумент. Я попробовал самое очевидное,
real, external, dimension(3) :: f
но gfortran не позволяет мне смешаться ВНЕШНИЙ и РАЗМЕР. Там какой-либо путь состоит в том, чтобы сделать то, что я хочу? (Контекст для этого является программой для решения системы дифференциальных уравнений, таким образом, я мог ввести уравнения, не имея миллиона параметров в моих подпрограммах.)
Объявление "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