LINUX.ORG.RU

[fortran95]имя функции как параметр?


0

1

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

program testiface
real :: x
character(len=2)::nam
interface

	real function es(x)
		real x
	end function es
	
	real function ec(x)
		real x
	end function ec

end interface

nam='ec'

print *,nam

call test(1.,es)

contains

subroutine test(x,f)

	real::x,f,z
	z=f(x)

end subroutine

end program

real function es(x)
	real x
	print *,x,'es'
end function es

real function ec(x)
	real x
	print *,x,'ec'
end function ec
однако, если попытаться задать в качестве аргумента переменную, содержащую имя функции
call test(1.,nam)
, то компилятор ругается.

возможно ли както это провернуть?

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

★★★★★

Последнее исправление: thunar (всего исправлений: 1)

Еще в Fortran 66 можно было. Только надо протаскивать, конечно, не строку с именем, а саму подпрограмму передавать параметром.

anonymous
()
Ответ на: комментарий от anonymous

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

thunar ★★★★★
() автор топика
Ответ на: комментарий от thunar

А нельзя ли в фортране присвоить переменной функцию? Или раз уж функцию можно передать параметром, оформить в таком виде: вычисление необходимой функции, вызов функции с основной итерацией с передачей выбранной функции параметром

unC0Rr ★★★★★
()
Ответ на: комментарий от unC0Rr

присвоить переменной функцию?

каким термином зовётся такое действие?

по второму не распарсил — можешь в псевдокоде привести, если не трудно?

thunar ★★★★★
() автор топика
Ответ на: комментарий от unC0Rr

вот что имеется ввиду — вот такая обработка:

	subroutine particle_routine(wtd,dt0)
		character(len=1):: wtd ! что делать с частицами
		type(p1d3v),pointer,dimension(:)::f_
		real(8),pointer,dimension(:)::n_
		integer,pointer::vacant_
		real(8),pointer::mu_
		integer::ii
		real(8)::x_old,x_new,vx_new,dt0,dt1,dt2
		integer::nx_old,nx_new
		
		if (wtd(1:1).eq.'e') then !первый символ -- тип частицы
			f_=>f_e;vacant_=>vacant_e; mu_=>mu_e; n_=>GridVarsReal(:,1)
		elseif (wtd(1:1).eq.'i') then
			f_=>f_i; vacant_=>vacant_i; mu_=>mu_i; n_=>GridVarsReal(:,2)
		elseif (wtd(1:1).eq.'a') then
			f_=>f_a; vacant_=>vacant_a; mu_=>mu_a; n_=>GridVarsReal(:,3)
		endif
		
		n_=0
		ii=1
		do while (ii<vacant_)
			!print *,'ii=',ii
			if (f_(ii)%s) then
				f_(ii)%s=.false.
			else
				do
					x_old=f_(ii)%x; nx_old=f_(ii)%nx

а вот от этой проверки хочется избавиться:

\/\/\/\/\/\/\/\/

					
					if (wtd(1:1).eq.'e') then
						call move_e(ii,dt0)
					elseif (wtd(1:1).eq.'i') then
						call move_i(ii,dt0)
					elseif (wtd(1:1).eq.'a') then
						call move_a(ii,dt0)
					endif
/\/\/\/\/\/\/\/\
					
					x_new=f_(ii)%x; nx_new=f_(ii)%nx;vx_new=f_(ii)%v(1)
					if (x_new<=0 .or. x_new>=Lx) then
						vacant_=vacant_-1; f_(ii)=f_(vacant_) !дефраг
					else
						exit
					endif
				enddo
			endif

			if (vacant_<2) then
				exit
			endif
			
			if (nx_new>nx_old) then
				!print *,'>'
				dt1=(h*nx_old-x_old)/vx_new; dt2=dt0-dt1
				n_(nx_old)=n_(nx_old)+dt1/dt0
				n_(nx_new)=n_(nx_new)+dt2/dt0
			elseif (nx_new<nx_old) then
				!print *,'<'
				dt1=-(x_old-h*(nx_old-1))/vx_new; dt2=dt0-dt1
				n_(nx_old)=n_(nx_old)+dt1/dt0
				n_(nx_new)=n_(nx_new)+dt2/dt0
			else
				!print *,'_'
				n_(nx_new)=n_(nx_new)+1
			endif

			ii=ii+1
			
		enddo
		n_=n_/h*Np
	end subroutine particle_routine

thunar ★★★★★
() автор топика
Ответ на: комментарий от thunar

по второму не распарсил — можешь в псевдокоде привести, если не трудно?

function f1(x){
 return x*2;}

function f2(x){
 return x*x;}
...

function map(array,func){
 foreach(x in array)
  func(x);}


...


array={1,2,3};
if(expr1)
 map(array,f1);
else if(expr2)
 map(array,f2);
...

По первому варианту имелось в виду это (в псевдокоде):

if(expr1)
 func=f1;
else if(expr2)
 func=f2;
...
map(array,func);
staseg ★★★★★
()
Ответ на: комментарий от staseg

func=f1;

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

thunar ★★★★★
() автор топика
Ответ на: комментарий от staseg

map(array,func);

это распараллеленая обработка массива?

thunar ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.