2011-12-23 22 views
22

Başlık iyi konduğundan emin değil. Öneriler hoş geldiniz.Fortran'da bir işlev adı nasıl eklenir

İşte yapmak istediklerim. Bir koşulu kontrol edin ve sonra döngüde hangi fonksiyonun kullanılacağına karar verin. Örneğin: Benim döngü yazarken

if (a < 0) then 
    loop_func = func1 
else 
    loop_func = func2 
endif 

Sonra bir işaretçi olarak loop_func kullanabilirsiniz. Her iki işlev de tam olarak aynı girdileri alır ve problemi çözmek için a değerine dayanan farklı yaklaşımlardır. Bu, iki neredeyse aynı blok yerine yalnızca bir kod bloğuna sahip olmamı sağlayacaktır. Bu da altprogramlara uygulanabilir.

Bunun nasıl uygulanabileceği hakkında bir fikrin var mı?

Teşekkür ederiz.

cevap

31

Evet, Fortran'ın yordam işaretçileri vardır, böylece etkin bir şekilde bir işlev adı alabilirsiniz. Burada, fonksiyon göstergesine "f_ptr" tek bir işlev veya diğerine atanan bir kod örneği verilmiştir. Daha sonra program "f_ptr" yi kullanabilir ve seçilen işlev çağrılır.

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 

end module ExampleFuncs 


program test_func_ptrs 

    use ExampleFuncs 
    implicit none 

    abstract interface 
     function func (z) 
     real :: func 
     real, intent (in) :: z 
     end function func 
    end interface 

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

    real :: input 

    write (*, '(/ "Input test value: ")', advance="no") 
    read (*, *) input 

    if (input < 0) then 
     f_ptr => f1 
    else 
     f_ptr => f2 
    end if 

    write (*, '(/ "evaluate function: ", ES14.4)') f_ptr (input) 

    stop 

end program test_func_ptrs 
+0

Bu ne için lehçe? – wallyk

+0

Hmm ... so '=>' işaretçiler için bir çeşit atama operatörüdür ve 'yordam (func)' tür prosedürler için bir tür bildirimdir, örneğin tür (tür) türetilmiş türler içindir. Ben null() 'ın başlatma için kullanıldığını ve 0'a eşdeğer olduğunu varsayıyorum.Ve evet, Fortran doğru öğrendiğim ilk programlama dilidir. –

+0

Birkaç soru. 'Arayüz' ne için? Bir yordamı belirtme yolu (türetilmiş tipte olduğu gibi) ve işaretçinin işaret ettiği şeyin doğru "tip" olduğundan emin olmak için mi? Ayrıca, programınızın bitiminden önce bir "stop" var. Bu en iyi uygulama mı ve benim de koduma dahil olmalı mıyım? –

2

Çoğu Fortran uygulamasının işlev işaretçileri veya yordam işaretlerini işlemek için standart bir yolu yoktur. Ancak, Fortran 2003 ve sonrası bir şey var. (this 6. sayfasına bakınız.)

verilen durum için

, bu onun yerine oldukça iyi çalışacaktır:

function func1 (p1, p2, etc) 
... as you have it already 
end 

function func2 (p1, p2, etc) 
... as you have it already 
end 

function funcselect (a, p1, p2, etc) 
    if (a < 0) then 
      x = func1 (p1, p2, etc) 
    else 
      x = func2 (p1, p2, etc) 
    endif 
end 

Sonra sadece çağrı funcselect yerine loop_func ile yapardı ekstra parametresi ile .

+0

Ancak program, her işlev çağrıldığında durumu kontrol etmek zorunda değil mi? Bundan kaçınmaya çalışıyorum. –

+0

@SamuelTan: Evet, ama bu endişelenecek bir şey değil. Herhangi bir modern işlemcide, sadece birkaç CPU döngüsü: bir avuç nanosaniye. – wallyk

+2

"Fortran işlev işaretçileri veya yordam işaretçi işlemek için standart bir yolu yok" ifadesine katılmıyorum. Prosedür işaretçileri Fortran 2003 dil standardının bir parçasıdır. –

İlgili konular